perl_matcher.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 551 行 · 第 1/2 页

HPP
551
字号
/* * * Copyright (c) 2002 * John Maddock * * Use, modification and distribution are subject to the  * Boost Software License, Version 1.0. (See accompanying file  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */#ifndef BOOST_REGEX_MATCHER_HPP#define BOOST_REGEX_MATCHER_HPP#include <boost/regex/v4/iterator_category.hpp>#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable: 4103)#endif#ifdef BOOST_HAS_ABI_HEADERS#  include BOOST_ABI_PREFIX#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif#ifdef BOOST_MSVC#  pragma warning(push)#  pragma warning(disable: 4800)#endifnamespace boost{namespace re_detail{//// error checking API://BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex_constants::syntax_option_type ef, match_flag_type mf);//// function can_start://template <class charT>inline bool can_start(charT c, const unsigned char* map, unsigned char mask){   return ((c < static_cast<charT>(0)) ? true : ((c >= static_cast<charT>(1 << CHAR_BIT)) ? true : map[c] & mask));}inline bool can_start(char c, const unsigned char* map, unsigned char mask){   return map[(unsigned char)c] & mask;}inline bool can_start(signed char c, const unsigned char* map, unsigned char mask){   return map[(unsigned char)c] & mask;}inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask){   return map[c] & mask;}inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask){   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);}#if !defined(__hpux) // WCHAR_MIN not usable in pp-directives.#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask){   return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);}#endif#endif//// Unfortunately Rogue Waves standard library appears to have a bug// in std::basic_string::compare that results in eroneous answers// in some cases (tested with Borland C++ 5.1, Rogue Wave lib version// 0x020101) the test case was:// {39135,0} < {0xff,0}// which succeeds when it should not.//#ifndef _RWSTD_VER#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)template <class C, class T, class A>inline int string_compare(const std::basic_string<C,T,A>& s, const C* p){    if(0 == *p)   {      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))         return 0;   }   return s.compare(p); }#endif#else#if !BOOST_WORKAROUND(BOOST_MSVC, < 1310)template <class C, class T, class A>inline int string_compare(const std::basic_string<C,T,A>& s, const C* p){    if(0 == *p)   {      if(s.empty() || ((s.size() == 1) && (s[0] == 0)))         return 0;   }   return s.compare(p); }#endifinline int string_compare(const std::string& s, const char* p){ return std::strcmp(s.c_str(), p); }# ifndef BOOST_NO_WREGEXinline int string_compare(const std::wstring& s, const wchar_t* p){ return std::wcscmp(s.c_str(), p); }#endif#endiftemplate <class Seq, class C>inline int string_compare(const Seq& s, const C* p){   std::size_t i = 0;   while((i < s.size()) && (p[i] == s[i]))   {      ++i;   }   return (i == s.size()) ? -p[i] : s[i] - p[i];}# define STR_COMP(s,p) string_compare(s,p)template<class charT>inline const charT* re_skip_past_null(const charT* p){  while (*p != static_cast<charT>(0)) ++p;  return ++p;}template <class iterator, class charT, class traits_type, class char_classT>iterator BOOST_REGEX_CALL re_is_set_member(iterator next,                           iterator last,                           const re_set_long<char_classT>* set_,                           const regex_data<charT, traits_type>& e, bool icase){      const charT* p = reinterpret_cast<const charT*>(set_+1);   iterator ptr;   unsigned int i;   //bool icase = e.m_flags & regex_constants::icase;   if(next == last) return next;   typedef typename traits_type::string_type traits_string_type;   const ::boost::regex_traits_wrapper<traits_type>& traits_inst = *(e.m_ptraits);      // dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never   // referenced   (void)traits_inst;   // try and match a single character, could be a multi-character   // collating element...   for(i = 0; i < set_->csingles; ++i)   {      ptr = next;      if(*p == static_cast<charT>(0))      {         // treat null string as special case:         if(traits_inst.translate(*ptr, icase) != *p)         {            while(*p == static_cast<charT>(0))++p;            continue;         }         return set_->isnot ? next : (ptr == next) ? ++next : ptr;      }      else      {         while(*p && (ptr != last))         {            if(traits_inst.translate(*ptr, icase) != *p)               break;            ++p;            ++ptr;         }         if(*p == static_cast<charT>(0)) // if null we've matched            return set_->isnot ? next : (ptr == next) ? ++next : ptr;         p = re_skip_past_null(p);     // skip null      }   }   charT col = traits_inst.translate(*next, icase);   if(set_->cranges || set_->cequivalents)   {      traits_string_type s1;      //      // try and match a range, NB only a single character can match      if(set_->cranges)      {         if((e.m_flags & regex_constants::collate) == 0)            s1.assign(1, col);         else         {            charT a[2] = { col, charT(0), };            s1 = traits_inst.transform(a, a + 1);         }         for(i = 0; i < set_->cranges; ++i)         {            if(STR_COMP(s1, p) >= 0)            {               do{ ++p; }while(*p);               ++p;               if(STR_COMP(s1, p) <= 0)                  return set_->isnot ? next : ++next;            }            else            {               // skip first string               do{ ++p; }while(*p);               ++p;            }            // skip second string            do{ ++p; }while(*p);            ++p;         }      }      //      // try and match an equivalence class, NB only a single character can match      if(set_->cequivalents)      {         charT a[2] = { col, charT(0), };         s1 = traits_inst.transform_primary(a, a +1);         for(i = 0; i < set_->cequivalents; ++i)         {            if(STR_COMP(s1, p) == 0)               return set_->isnot ? next : ++next;            // skip string            do{ ++p; }while(*p);            ++p;         }      }   }   if(traits_inst.isctype(col, set_->cclasses) == true)      return set_->isnot ? next : ++next;   if((set_->cnclasses != 0) && (traits_inst.isctype(col, set_->cnclasses) == false))      return set_->isnot ? next : ++next;   return set_->isnot ? ++next : next;}template <class BidiIterator>class repeater_count{   repeater_count** stack;   repeater_count* next;   int state_id;   std::size_t count;        // the number of iterations so far   BidiIterator start_pos;   // where the last repeat startedpublic:   repeater_count(repeater_count** s)   {      stack = s;      next = 0;      state_id = -1;      count = 0;   }   repeater_count(int i, repeater_count** s, BidiIterator start)      : start_pos(start)   {      state_id = i;      stack = s;      next = *stack;      *stack = this;      if(state_id > next->state_id)         count = 0;      else      {         repeater_count* p = next;         while(p->state_id != state_id)            p = p->next;         count = p->count;

⌨️ 快捷键说明

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