⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp_regex_traits.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 3 页
字号:
   }
   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
   : cpp_regex_traits_base<char>(l)
   {
      init();
   }

   regex_constants::syntax_type syntax_type(char c)const
   {
      return m_char_map[static_cast<unsigned char>(c)];
   }
   regex_constants::escape_syntax_type escape_syntax_type(char c) const
   {
      return m_char_map[static_cast<unsigned char>(c)];
   }

private:
   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
   void init();
};

#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
enum
{
   char_class_space=1<<0, 
   char_class_print=1<<1, 
   char_class_cntrl=1<<2, 
   char_class_upper=1<<3, 
   char_class_lower=1<<4,
   char_class_alpha=1<<5, 
   char_class_digit=1<<6, 
   char_class_punct=1<<7, 
   char_class_xdigit=1<<8,
   char_class_alnum=char_class_alpha|char_class_digit, 
   char_class_graph=char_class_alnum|char_class_punct,
   char_class_blank=1<<9,
   char_class_word=1<<10,
   char_class_unicode=1<<11
};

#endif

//
// class cpp_regex_traits_implementation:
// provides pimpl implementation for cpp_regex_traits.
//
template <class charT>
class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
{
public:
   typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
   typedef typename std::ctype<charT>::mask                  native_mask_type;
#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
   BOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
   BOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
   BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
#endif

   typedef std::basic_string<charT> string_type;
   typedef charT char_type;
   //cpp_regex_traits_implementation();
   cpp_regex_traits_implementation(const std::locale& l)
      : cpp_regex_traits_char_layer<charT>(l), m_is(&m_sbuf)
   {
      init();
   }
   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
      : cpp_regex_traits_char_layer<charT>(l), m_is(&m_sbuf)
   {
      init();
   }
   std::string error_string(regex_constants::error_type n) const
   {
      if(!m_error_strings.empty())
      {
         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
      }
      return get_default_error_string(n);
   }
   char_class_type lookup_classname(const charT* p1, const charT* p2) const
   {
      char_class_type result = lookup_classname_imp(p1, p2);
      if(result == 0)
      {
         string_type temp(p1, p2);
         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
      }
      return result;
   }
   string_type lookup_collatename(const charT* p1, const charT* p2) const;
   string_type transform_primary(const charT* p1, const charT* p2) const;
   string_type transform(const charT* p1, const charT* p2) const;
   re_detail::parser_buf<charT>   m_sbuf;            // buffer for parsing numbers.
   std::basic_istream<charT>      m_is;              // stream for parsing numbers.
private:
   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
   unsigned                       m_collate_type;    // the form of the collation string
   charT                          m_collate_delim;   // the collation group delimiter
   //
   // helpers:
   //
   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
   void init();
#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
public:
   bool isctype(charT c, char_class_type m)const;
#endif
};

#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)

template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;

#endif
#endif

template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
{
   //
   // PRECONDITIONS:
   //
   // A bug in gcc 3.2 (and maybe other versions as well) treats
   // p1 as a null terminated string, for efficiency reasons 
   // we work around this elsewhere, but just assert here that
   // we adhere to gcc's (buggy) preconditions...
   //
   BOOST_ASSERT(*p2 == 0);

   string_type result;
   //
   // swallowing all exceptions here is a bad idea
   // however at least one std lib will always throw
   // std::bad_alloc for certain arguments...
   //
   try{
      //
      // What we do here depends upon the format of the sort key returned by
      // sort key returned by this->transform:
      //
      switch(m_collate_type)
      {
      case sort_C:
      case sort_unknown:
         // the best we can do is translate to lower case, then get a regular sort key:
         {
            result.assign(p1, p2);
            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
            break;
         }
      case sort_fixed:
         {
            // get a regular sort key, and then truncate it:
            result.assign(this->m_pcollate->transform(p1, p2));
            result.erase(this->m_collate_delim);
            break;
         }
      case sort_delim:
            // get a regular sort key, and then truncate everything after the delim:
            result.assign(this->m_pcollate->transform(p1, p2));
            std::size_t i;
            for(i = 0; i < result.size(); ++i)
            {
               if(result[i] == m_collate_delim)
                  break;
            }
            result.erase(i);
            break;
      }
   }catch(...){}
   while(result.size() && (charT(0) == *result.rbegin()))
      result.erase(result.size() - 1);
   if(result.empty())
   {
      // character is ignorable at the primary level:
      result = string_type(1, charT(0));
   }
   return result;
}

template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
{
   //
   // PRECONDITIONS:
   //
   // A bug in gcc 3.2 (and maybe other versions as well) treats
   // p1 as a null terminated string, for efficiency reasons 
   // we work around this elsewhere, but just assert here that
   // we adhere to gcc's (buggy) preconditions...
   //
   BOOST_ASSERT(*p2 == 0);
   //
   // swallowing all exceptions here is a bad idea
   // however at least one std lib will always throw
   // std::bad_alloc for certain arguments...
   //
   string_type result;
   try{
      result = this->m_pcollate->transform(p1, p2);
      //
      // Borland's STLPort version returns a NULL-terminated
      // string that has garbage at the end - each call to
      // std::collate<wchar_t>::transform returns a different string!
      // So as a workaround, we'll truncate the string at the first NULL
      // which _seems_ to work....
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
      result.erase(result.find(charT(0)));
#else
      //
      // some implementations (Dinkumware) append unnecessary trailing \0's:
      while(result.size() && (charT(0) == *result.rbegin()))
         result.erase(result.size() - 1);
#endif
      BOOST_ASSERT(std::find(result.begin(), result.end(), charT(0)) == result.end());
   }
   catch(...)
   {
   }
   return result;
}


template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
{
   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
   if(m_custom_collate_names.size())
   {
      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
      if(pos != m_custom_collate_names.end())
         return pos->second;
   }
#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
               && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
               && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
   std::string name(p1, p2);
#else
   std::string name;
   const charT* p0 = p1;
   while(p0 != p2)
      name.append(1, char(*p0++));
#endif
   name = lookup_default_collate_name(name);
#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
               && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
               && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
   if(name.size())
      return string_type(name.begin(), name.end());
#else
   if(name.size())
   {
      string_type result;
      typedef std::string::const_iterator iter;
      iter b = name.begin();
      iter e = name.end();
      while(b != e)
         result.append(1, charT(*b++));
      return result;
   }
#endif
   if(p2 - p1 == 1)
      return string_type(1, *p1);
   return string_type();
}

template <class charT>
void cpp_regex_traits_implementation<charT>::init()
{
#ifndef BOOST_NO_STD_MESSAGES
#ifndef __IBMCPP__
   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
   if(cat_name.size())
   {
      cat = this->m_pmessages->open(
         cat_name, 
         this->m_locale);
      if((int)cat < 0)
      {
         std::string m("Unable to open message catalog: ");
         std::runtime_error err(m + cat_name);
         boost::re_detail::raise_runtime_error(err);
      }
   }
   //
   // if we have a valid catalog then load our messages:
   //
   if((int)cat >= 0)
   {
      //
      // Error messages:
      //
      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0); 
         i <= boost::regex_constants::error_unknown; 
         i = static_cast<boost::regex_constants::error_type>(i + 1))
      {
         const char* p = get_default_error_string(i);
         string_type default_message;
         while(*p)
         {
            default_message.append(1, this->m_pctype->widen(*p));
            ++p;
         }
         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
         std::string result;
         for(std::string::size_type j = 0; j < s.size(); ++j)
         {
            result.append(1, this->m_pctype->narrow(s[j], 0));
         }
         m_error_strings[i] = result;
      }
      //
      // Custom class names:
      //
#ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
      static const char_class_type masks[14] = 
      {
         std::ctype<charT>::alnum,
         std::ctype<charT>::alpha,
         std::ctype<charT>::cntrl,
         std::ctype<charT>::digit,
         std::ctype<charT>::graph,
         std::ctype<charT>::lower,
         std::ctype<charT>::print,
         std::ctype<charT>::punct,
         std::ctype<charT>::space,
         std::ctype<charT>::upper,
         std::ctype<charT>::xdigit,
         cpp_regex_traits_implementation<charT>::mask_blank,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -