inline StringT
convert_trigraphs(StringT const &value)
{
    StringT result;
    typename StringT::size_type pos = 0;
    typename StringT::size_type pos1 = value.find_first_of ("?", 0);
    if (StringT::npos != pos1) {
        do {
            result += value.substr(pos, pos1-pos);
            StringT trigraph (value.substr(pos1)); 
            if (is_trigraph(trigraph)) {
                result += convert_trigraph(trigraph);
                pos1 = value.find_first_of ("?", pos = pos1+3);
            }
            else {
                result += value[pos1];
                pos1 = value.find_first_of ("?", pos = pos1+1);
            }
        } while (StringT::npos != pos1);
        result += value.substr(pos);
    }
    else {
        result = value;
    }
    return result;
}
 inline StringT
 unescape_lit(StringT const &value)
 {
     StringT result;
     typename StringT::size_type pos = 0;
     typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
     if (StringT::npos != pos1) {
         do {
             if ('\\' == value[pos1+1] || '\"' == value[pos1+1] || 
                 '?' == value[pos1+1])
             {
                 result = result + value.substr(pos, pos1-pos);
                 pos1 = value.find_first_of ("\\", (pos = pos1+1)+1);
             }
             else {
                 result = result + value.substr(pos, pos1-pos+1);
                 pos1 = value.find_first_of ("\\", pos = pos1+1);
             }
             
         } while (pos1 != StringT::npos);
         result = result + value.substr(pos);
     }
     else {
     // the string doesn't contain any escaped character sequences
         result = value;
     }
     return result;
 }
 inline StringT
 escape_lit(StringT const &value)
 {
     StringT result;
     typename StringT::size_type pos = 0;
     typename StringT::size_type pos1 = value.find_first_of ("\"\\?", 0);
     if (StringT::npos != pos1) {
         do {
             result += value.substr(pos, pos1-pos) 
                         + StringT("\\") 
                         + StringT(1, value[pos1]);
             pos1 = value.find_first_of ("\"\\?", pos = pos1+1);
         } while (StringT::npos != pos1);
         result += value.substr(pos);
     }
     else {
         result = value;
     }
     return result;
 }
inline void
validate_identifier_name (StringT const &name, std::size_t line,
    std::size_t column, StringT const &file_name)
{
    using namespace std;    // some systems have strtoul in namespace std::

typename StringT::size_type pos = name.find_first_of('\\');

    while (StringT::npos != pos) {
    // the identifier name contains a backslash (must be universal char)
        BOOST_ASSERT('u' == name[pos+1] || 'U' == name[pos+1]);

    StringT uchar_val(name.substr(pos+2, ('u' == name[pos+1]) ? 4 : 8));
    universal_char_type type =
        classify_universal_char(strtoul(uchar_val.c_str(), 0, 16));

        if (universal_char_type_valid != type) {
        // an invalid char was found, so throw an exception
        StringT error_uchar(name.substr(pos, ('u' == name[pos+1]) ? 6 : 10));

            if (universal_char_type_invalid == type) {
                BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_invalid,
                    error_uchar, line, column, file_name.c_str());
            }
            else if (universal_char_type_base_charset == type) {
                BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_base_charset,
                    error_uchar, line, column, file_name.c_str());
            }
            else {
                BOOST_WAVE_LEXER_THROW(lexing_exception, universal_char_not_allowed,
                    error_uchar, line, column, file_name.c_str());
            }
        }

    // find next universal char (if appropriate)
        pos = name.find_first_of('\\', pos+2);
    }
}
 inline StringT
 unescape_lit(StringT const &value)
 {
     StringT result;
     typename StringT::size_type pos = 0;
     typename StringT::size_type pos1 = value.find_first_of ("\\", 0);
     if (StringT::npos != pos1) {
         do {
             switch (value[pos1+1]) {
             case '\\':
             case '\"':
             case '?':
                 result = result + value.substr(pos, pos1-pos);
                 pos1 = value.find_first_of ("\\", (pos = pos1+1)+1);
                 break;
                 
             case 'n':
                 result = result + value.substr(pos, pos1-pos) + "\n";
                 pos1 = value.find_first_of ("\\", pos = pos1+1);
                 ++pos;
                 break;
                 
             default:
                 result = result + value.substr(pos, pos1-pos+1);
                 pos1 = value.find_first_of ("\\", pos = pos1+1);
             }
             
         } while (pos1 != StringT::npos);
         result = result + value.substr(pos);
     }
     else {
     // the string doesn't contain any escaped character sequences
         result = value;
     }
     return result;
 }
inline bool 
is_special_macroname (StringT const &name)
{
    if (name.size() < 7)
        return false;

    if ("defined" == name)
        return true;

    if ('_' == name[0] && '_' == name[1]) {
    StringT str = name.substr(2);

        if (str == "cplusplus"  || str == "STDC__" || 
            str == "TIME__"     || str == "DATE__" ||
            str == "LINE__"     || str == "FILE__" ||
            str == "INCLUDE_LEVEL__")
        {
            return true;
        }
    }
    return false;
}