regex_format.hpp

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

HPP
655
字号
/* * * Copyright (c) 1998-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) * */ /*  *   LOCATION:    see http://www.boost.org for most recent version.  *   FILE         regex_format.hpp  *   VERSION      see <boost/version.hpp>  *   DESCRIPTION: Provides formatting output routines for search and replace  *                operations.  Note this is an internal header file included  *                by regex.hpp, do not include on its own.  */#ifndef BOOST_REGEX_FORMAT_HPP#define BOOST_REGEX_FORMAT_HPPnamespace boost{#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//// Forward declaration://   template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >class match_results;namespace re_detail{//// struct trivial_format_traits:// defines minimum localisation support for formatting// in the case that the actual regex traits is unavailable.//template <class charT>struct trivial_format_traits{   typedef charT char_type;   static std::ptrdiff_t length(const charT* p)   {      return global_length(p);   }   static charT tolower(charT c)   {      return ::boost::re_detail::global_lower(c);   }   static charT toupper(charT c)   {      return ::boost::re_detail::global_upper(c);   }   static int value(const charT c, int radix)   {      int result = global_value(c);      return result >= radix ? -1 : result;   }   int toi(const charT*& p1, const charT* p2, int radix)const   {      return global_toi(p1, p2, radix, *this);   }};template <class OutputIterator, class Results, class traits>class basic_regex_formatter{public:   typedef typename traits::char_type char_type;   basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)      : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}   OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f);   OutputIterator format(const char_type* p1, match_flag_type f)   {      return format(p1, p1 + m_traits.length(p1), f);   }private:   typedef typename Results::value_type sub_match_type;   enum output_state   {      output_copy,      output_next_lower,      output_next_upper,      output_lower,      output_upper,      output_none   };   void put(char_type c);   void put(const sub_match_type& sub);   void format_all();   void format_perl();   void format_escape();   void format_conditional();   void format_until_scope_end();   const traits& m_traits;       // the traits class for localised formatting operations   const Results& m_results;     // the match_results being used.   OutputIterator m_out;         // where to send output.   const char_type* m_position;  // format string, current position   const char_type* m_end;       // format string end   match_flag_type m_flags;      // format flags to use   output_state    m_state;      // what to do with the next character   output_state    m_restore_state;  // what state to restore to.   bool            m_have_conditional; // we are parsing a conditionalprivate:   basic_regex_formatter(const basic_regex_formatter&);   basic_regex_formatter& operator=(const basic_regex_formatter&);};template <class OutputIterator, class Results, class traits>OutputIterator basic_regex_formatter<OutputIterator, Results, traits>::format(const char_type* p1, const char_type* p2, match_flag_type f){   m_position = p1;   m_end = p2;   m_flags = f;   format_all();   return m_out;}template <class OutputIterator, class Results, class traits>void basic_regex_formatter<OutputIterator, Results, traits>::format_all(){   // over and over:   while(m_position != m_end)   {      switch(*m_position)      {      case '&':         if(m_flags & ::boost::regex_constants::format_sed)         {            ++m_position;            put(m_results[0]);            break;         }         put(*m_position++);         break;      case '\\':         format_escape();         break;      case '(':         if(m_flags & boost::regex_constants::format_all)         {            ++m_position;            bool have_conditional = m_have_conditional;            m_have_conditional = false;            format_until_scope_end();            m_have_conditional = have_conditional;            if(m_position == m_end)               return;            BOOST_ASSERT(*m_position == static_cast<char_type>(')'));            ++m_position;  // skip the closing ')'            break;         }         put(*m_position);         ++m_position;         break;      case ')':         if(m_flags & boost::regex_constants::format_all)         {            return;         }         put(*m_position);         ++m_position;         break;      case ':':         if((m_flags & boost::regex_constants::format_all) && m_have_conditional)         {            return;         }         put(*m_position);         ++m_position;         break;      case '?':         if(m_flags & boost::regex_constants::format_all)         {            ++m_position;            format_conditional();            break;         }         put(*m_position);         ++m_position;         break;      case '$':         if((m_flags & format_sed) == 0)         {            format_perl();            break;         }         // fall through, not a special character:      default:         put(*m_position);         ++m_position;         break;      }   }}template <class OutputIterator, class Results, class traits>void basic_regex_formatter<OutputIterator, Results, traits>::format_perl(){   //   // On entry *m_position points to a '$' character   // output the information that goes with it:   //   BOOST_ASSERT(*m_position == '$');   //   // see if this is a trailing '$':   //   if(++m_position == m_end)   {      --m_position;      put(*m_position);      ++m_position;      return;   }   //   // OK find out what kind it is:   //   switch(*m_position)   {   case '&':      ++m_position;      put(this->m_results[0]);      break;   case '`':      ++m_position;      put(this->m_results.prefix());      break;   case '\'':      ++m_position;      put(this->m_results.suffix());      break;   case '$':      put(*m_position++);      break;   default:      // see if we have a number:      {         std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);         len = (std::min)(static_cast<std::ptrdiff_t>(2), len);         int v = m_traits.toi(m_position, m_position + len, 10);         if(v < 0)         {            // leave the $ as is, and carry on:            --m_position;            put(*m_position);            ++m_position;            break;         }         // otherwise output sub v:         put(this->m_results[v]);      }   }}template <class OutputIterator, class Results, class traits>void basic_regex_formatter<OutputIterator, Results, traits>::format_escape(){   // skip the escape and check for trailing escape:   if(++m_position == m_end)   {      put(static_cast<char_type>('\\'));      return;   }   // now switch on the escape type:   switch(*m_position)   {   case 'a':      put(static_cast<char_type>('\a'));      ++m_position;      break;   case 'f':      put(static_cast<char_type>('\f'));      ++m_position;      break;   case 'n':      put(static_cast<char_type>('\n'));      ++m_position;      break;   case 'r':      put(static_cast<char_type>('\r'));      ++m_position;      break;   case 't':      put(static_cast<char_type>('\t'));      ++m_position;      break;   case 'v':      put(static_cast<char_type>('\v'));      ++m_position;      break;   case 'x':      if(++m_position == m_end)      {         put(static_cast<char_type>('x'));         return;      }      // maybe have \x{ddd}      if(*m_position == static_cast<char_type>('{'))      {         ++m_position;         int val = m_traits.toi(m_position, m_end, 16);         if(val < 0)         {            // invalid value treat everything as literals:            put(static_cast<char_type>('x'));            put(static_cast<char_type>('{'));            return;         }         if(*m_position != static_cast<char_type>('}'))         {            while(*m_position != static_cast<char_type>('\\'))               --m_position;

⌨️ 快捷键说明

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