  static inline FilterChar from_utf8 (const char * & in, const char * stop, 
                                      Uni32 err_char = '?')
  {
    Uni32 u = (Uni32)(-1);
    FilterChar::Width w = 1;

    // the first char is guaranteed not to be off the end
    char c = *in;
    ++in;

    while (in != stop && (c & 0xC0) == 0x80) {c = *in; ++in; ++w;}
    if ((c & 0x80) == 0x00) { // 1-byte wide
      u = c;
    } else if ((c & 0xE0) == 0xC0) { // 2-byte wide
      u  = c & 0x1F;
      get_check_next;
    } else if ((c & 0xF0) == 0xE0) { // 3-byte wide
      u  = c & 0x0F;
      get_check_next;
      get_check_next;
    } else if ((c & 0xF8) == 0xF0) { // 4-byte wide
      u  = c & 0x07;
      get_check_next;
      get_check_next;
      get_check_next;
    } else {
      goto error;
    }

    return FilterChar(u, w);
  error:
    return FilterChar(err_char, w);
  }
  static inline FilterChar from_utf8 (const char * & in, const char * stop, 
                                      Uni32 err_char = '?')
  {
    Uni32 u = (Uni32)(-1);
    FilterChar::Width w = 1;

     
    char c = *in;
    ++in;

    while (in != stop && (c & 0xC0) == 0x80) {c = *in; ++in; ++w;}
    if ((c & 0x80) == 0x00) {  
      u = c;
    } else if ((c & 0xE0) == 0xC0) {  
      u  = c & 0x1F;
      get_check_next;
    } else if ((c & 0xF0) == 0xE0) {  
      u  = c & 0x0F;
      get_check_next;
      get_check_next;
    } else if ((c & 0xF8) == 0xF0) {  
      u  = c & 0x07;
      get_check_next;
      get_check_next;
      get_check_next;
    } else {
      goto error;
    }

    return FilterChar(u, w);
  error:
    return FilterChar(err_char, w);
  }