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 + -
显示快捷键?