regexpr2.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:33k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //+---------------------------------------------------------------------------
  2. //
  3. //  Copyright ( C ) Microsoft Corporation, 1994 - 2002.
  4. //
  5. //  File:       regexpr2.h
  6. //
  7. //  Contents:   classes for regular expression pattern matching a-la perl
  8. //
  9. //  Classes:    basic_rpattern_base
  10. //
  11. //  Functions:  rpattern::match
  12. //              rpattern::substitute
  13. //              match_results::cbackrefs
  14. //              match_results::backref
  15. //              match_results::all_backrefs
  16. //              match_results::backref_str
  17. //
  18. //  Author:     Eric Niebler ( ericne@microsoft.com )
  19. //
  20. //----------------------------------------------------------------------------
  21. #ifndef REGEXPR_H
  22. #define REGEXPR_H
  23. #ifdef _MSC_VER
  24.   // warning C4097: typedef-name '' used as synonym for class-name
  25.   // warning C4189: local variable is initialized but not referenced
  26.   // warning C4514: '' : unreferenced inline function has been removed
  27.   // warning C4702: unreachable code
  28.   // warning C4710: function 'blah' not inlined
  29.   // warning C4786: identifier was truncated to '255' characters in the debug information
  30. # pragma warning( push )
  31. # pragma warning( disable : 4097 4189 4514 4702 4710 4786 )
  32.   extern "C" unsigned long __cdecl _exception_code();
  33. # define REGEX_STACK_OVERFLOW 0xC00000FDL
  34. # if _MSC_VER < 1300
  35.    extern "C" int __cdecl _resetstkoflw(void);
  36. # else
  37. #  include <malloc.h> // for _resetstkoflw
  38. # endif
  39. #endif
  40. #include <list>
  41. #include <iosfwd>
  42. #include <string>
  43. #include <vector>
  44. #include "syntax2.h"
  45. #include "restack.h"
  46. namespace regex
  47. {
  48. // This is the default alignment for the unsafe heterogeneous stack.
  49. // If you are getting a compiler error in one of the unsafe_stack
  50. // methods, then compile with -DREGEX_STACK_ALIGNMENT=16 or 32
  51. #ifndef REGEX_STACK_ALIGNMENT
  52. # define REGEX_STACK_ALIGNMENT sizeof( void* )
  53. #endif
  54. #ifndef REGEX_DEBUG
  55. # if defined(DEBUG) | defined(_DEBUG) | defined(DBG)
  56. #  define REGEX_DEBUG 1
  57. # else
  58. #  define REGEX_DEBUG 0
  59. # endif
  60. #endif
  61. namespace detail
  62. {
  63. #if REGEX_DEBUG
  64.     typedef hetero_stack<REGEX_STACK_ALIGNMENT,true,true,32,0>        unsafe_stack;
  65. #else
  66.     typedef hetero_stack<REGEX_STACK_ALIGNMENT,false,true,4096,1024>  unsafe_stack;
  67. #endif
  68.     // Used to initialize variables with the same value they would have
  69.     // if they were initialized as a static global. ( Ptrs get NULL,
  70.     // integer types get 0, etc, etc )
  71.     template<typename T> struct static_init { static T const value; };
  72.     template<typename T> T const static_init<T>::value = T();
  73.     //
  74.     // Forward declarations
  75.     //
  76.     template< typename CI > class  sub_expr;
  77.     template< typename CI > class  match_group_base;
  78.     template< typename CI > class  basic_rpattern_base_impl;
  79.     template< typename CI > struct match_param;
  80.     template< typename CI > struct sub_expr_base;
  81.     template< typename CI > struct matcher_helper;
  82. } // namespace detail
  83. // --------------------------------------------------------------------------
  84. //
  85. // Class:       width_type
  86. //
  87. // Description: represents the width of a sub-expression
  88. //
  89. // Members:     m_min      - smallest number of characters a sub-expr can span
  90. //              m_max      - largest number of characters a sub-expr can span
  91. //
  92. // History:     8/14/2000 - ericne - Created
  93. //
  94. // --------------------------------------------------------------------------
  95. struct width_type
  96. {
  97.     size_t m_min;
  98.     size_t m_max;
  99. };
  100. inline width_type const uninit_width()
  101. {
  102.     width_type const width = { size_t( -1 ), size_t( -1 ) };
  103.     return width;
  104. }
  105. // Helper function for processing escape sequences
  106. template< typename CH, typename TR, typename AL >
  107. void process_escapes( std::basic_string<CH, TR, AL> & str, bool fPattern = false ); //throw()
  108. // --------------------------------------------------------------------------
  109. //
  110. // Class:       backref_tag
  111. //
  112. // Description: Struct which contains a back-reference.  It is a template
  113. //              on the iterator type.
  114. //
  115. // Methods:     backref_tag   - c'tor
  116. //              operator bool - so that if( br ) is true if this br matched
  117. //              operator!     - inverse of operator bool()
  118. //
  119. // Members:     reserved      - move along, nothing to see here
  120. //
  121. // History:     8/9/2001 - ericne - Created
  122. //
  123. // --------------------------------------------------------------------------
  124. template< typename CI >
  125. class backref_tag : public std::pair<CI, CI>
  126. {
  127.     struct detail_t { detail_t * d; };
  128.     template< typename OSTREAM >
  129.     void REGEX_CDECL _do_print( OSTREAM & sout, ... ) const
  130.     {
  131.         typedef typename OSTREAM::char_type CH;
  132.         typedef typename OSTREAM::traits_type TR;
  133.         std::ostreambuf_iterator<CH, TR> iout( sout );
  134.         for( CI iter = first; iter != second; ++iter, ++iout )
  135.             *iout = *iter;
  136.     }
  137.     template< typename OSTREAM >
  138.     void _do_print( OSTREAM & sout, typename OSTREAM::char_type const * ) const
  139.     {
  140.         sout.write( first, static_cast<std::streamsize>( std::distance( first, second ) ) );
  141.     }
  142. public:
  143.     typedef CI iterator_type;
  144.     typedef typename std::iterator_traits<CI>::value_type char_type;
  145.     typedef std::basic_string<char_type> string_type;
  146.     explicit backref_tag(
  147.         CI i1 = detail::static_init<CI>::value,
  148.         CI i2 = detail::static_init<CI>::value )
  149.       : std::pair<CI, CI>( i1, i2 ),
  150.         matched( false ), 
  151.         reserved1( i1 ), 
  152.         reserved2( 0 ), 
  153.         reserved3( false ),
  154.         reserved4( detail::static_init<CI>::value ), 
  155.         reserved5( detail::static_init<CI>::value ) 
  156.     {
  157.     }
  158.     
  159.     CI begin() const
  160.     {
  161.         return first;
  162.     }
  163.     
  164.     CI end() const
  165.     {
  166.         return second;
  167.     }
  168.     string_type const str() const
  169.     {
  170.         return matched ? string_type( first, second ) : string_type();
  171.     }
  172.     
  173.     // Use the "safe bool" idiom. This allows implicit conversion to bool,
  174.     // but not to int. It also disallows conversion to void*.
  175.     typedef detail_t * detail_t::* bool_type;
  176.     operator bool_type() const //throw()
  177.     {
  178.         return matched ? &detail_t::d : 0;
  179.     }
  180.     bool operator!() const //throw()
  181.     {
  182.         return ! matched;
  183.     }
  184.     
  185.     template< typename CH, typename TR >
  186.     std::basic_ostream<CH, TR> & print( std::basic_ostream<CH, TR> & sout ) const
  187.     {
  188.         _do_print( sout, CI() );
  189.         return sout;
  190.     }
  191.     
  192.     bool   matched;
  193.     CI     reserved1; // used for internal book-keeping
  194.     size_t reserved2; // used for internal book-keeping
  195.     bool   reserved3; // used for internal book-keeping
  196.     CI     reserved4; // used for internal book-keeping
  197.     CI     reserved5; // used for internal book-keeping
  198. };
  199. // --------------------------------------------------------------------------
  200. //
  201. // Class:       basic_match_results
  202. //
  203. // Description: Use this structure for returning match/substitute results
  204. //              out from the match()/substitute() methods.
  205. //
  206. // Methods:     cbackrefs      -
  207. //              backref        -
  208. //              all_backrefs   -
  209. //              rlength        -
  210. //
  211. // Members:     m_rgbackrefs   -
  212. //
  213. // Typedefs:    const_iterator -
  214. //              backref_type   -
  215. //              backref_vector -
  216. //
  217. // History:     8/8/2001 - ericne - Created
  218. //
  219. // --------------------------------------------------------------------------
  220. template< typename CI >
  221. struct basic_match_results
  222. {
  223.     typedef CI                            const_iterator;
  224.     typedef backref_tag< const_iterator > backref_type;
  225.     typedef std::vector< backref_type >   backref_vector;
  226.     friend struct detail::matcher_helper<CI>;
  227.     virtual ~basic_match_results()
  228.     {
  229.     }
  230.     size_t cbackrefs() const //throw()
  231.     {
  232.         return m_rgbackrefs.size();
  233.     }
  234.     backref_type const & backref( size_t cbackref ) const //throw( std::out_of_range )
  235.     {
  236.         return m_rgbackrefs.at( cbackref );
  237.     }
  238.     backref_vector const & all_backrefs() const //throw()
  239.     {
  240.         return m_rgbackrefs;
  241.     }
  242.     size_t rstart( size_t cbackref = 0 ) const //throw( std::out_of_range )
  243.     {
  244.         return std::distance( ibegin, m_rgbackrefs.at( cbackref ).first );
  245.     }
  246.     size_t rlength( size_t cbackref = 0 ) const //throw( std::out_of_range )
  247.     {
  248.         return std::distance( m_rgbackrefs.at( cbackref ).first, m_rgbackrefs.at( cbackref ).second );
  249.     }
  250. private:
  251.     backref_vector m_rgbackrefs;
  252.     CI ibegin;
  253. };
  254. template< typename CH >
  255. struct basic_match_results_c : public basic_match_results<CH const *>
  256. {
  257.     typedef basic_match_results<CH const *> base;
  258.     typedef typename base::const_iterator const_iterator;
  259.     typedef typename base::backref_type   backref_type;
  260.     typedef typename base::backref_vector backref_vector;
  261. };
  262. template< typename CH, typename TR = std::char_traits<CH>, typename AL = std::allocator<CH> >
  263. struct basic_subst_results : public basic_match_results<typename std::basic_string<CH, TR, AL>::const_iterator>
  264. {
  265.     typedef basic_match_results<typename std::basic_string<CH, TR, AL>::const_iterator> base;
  266.     typedef typename base::const_iterator const_iterator;
  267.     typedef typename base::backref_type   backref_type;
  268.     typedef typename base::backref_vector backref_vector;
  269.     typedef std::basic_string<CH, TR, AL> string_type;
  270.     friend struct detail::matcher_helper<const_iterator>;
  271.     basic_subst_results() 
  272.       : m_pbackref_str( &m_backref_str )
  273.     {
  274.     }
  275.     string_type const & backref_str() const //throw()
  276.     {
  277.         return *m_pbackref_str;
  278.     }
  279. private:
  280.     string_type         m_backref_str;
  281.     string_type const * m_pbackref_str;
  282. };
  283. // The REGEX_MODE is a way of controlling how matching occurs.
  284. enum REGEX_MODE
  285. {
  286.     MODE_FAST, // Uses the fast, recursive algorithm. Could overflow stack.
  287.     MODE_SAFE, // Uses the slow, iterative algorithm. Can't overflow stack.
  288.     MODE_MIXED, // Uses a heuristic to automatically determine which algorithm
  289.                 // is the most appropriate for this pattern.
  290.     // MS VC++ has structured exception handling, which makes the
  291.     // consequences of a stack overflow much less severe. Because of this,
  292.     // it is possible to use the "fast" algorithm always on MS platforms,
  293. #ifdef _MSC_VER
  294.     MODE_DEFAULT = MODE_FAST
  295. #else
  296.     MODE_DEFAULT = MODE_MIXED
  297. #endif
  298. };
  299. template< typename CH >
  300. void reset_intrinsic_charsets( CH ch = CH( 0 ) );
  301. // This is for implementation details that really belong in the
  302. // cpp file, but can't go there because of template strangeness.
  303. #include "reimpl2.h"
  304. // --------------------------------------------------------------------------
  305. //
  306. // Class:       basic_rpattern_base
  307. //
  308. // Description:
  309. //
  310. // Methods:     basic_rpattern_base - c'tor
  311. //              basic_rpattern_base -
  312. //              basic_rpattern_base -
  313. //              init                - ( re )initialize the pattern
  314. //              init                -
  315. //              set_substitution    - set the substitution string
  316. //              _find_next_group    - parse the next group of the pattern
  317. //              _find_next          - parse the next sub_expr of the pattern
  318. //              _find_atom          - parse the next atom of the pattern
  319. //              _quantify           - quantify the sub_expr
  320. //              _common_init        - perform some common initialization tasks
  321. //              _parse_subst        - parse the substitution string
  322. //              _add_subst_backref  - add a backref node to the subst list
  323. //
  324. // Members:     m_invisible_groups  - list of hidden groups
  325. //
  326. // Typedefs:    syntax_type         -
  327. //              backref_type        -
  328. //              backref_vector      -
  329. //              string_type         -
  330. //              size_type           -
  331. //
  332. // History:     8/14/2000 - ericne - Created
  333. //              8/5/2001 - ericne - complete overhaul
  334. //
  335. // --------------------------------------------------------------------------
  336. template< typename CI, typename SY >
  337. class basic_rpattern_base : protected detail::basic_rpattern_base_impl<CI>
  338. {
  339.     typedef detail::basic_rpattern_base_impl<CI> impl;
  340. public:
  341.     typedef SY syntax_type;
  342.     typedef typename detail::basic_rpattern_base_impl<CI>::char_type       char_type;
  343.     typedef typename detail::basic_rpattern_base_impl<CI>::traits_type     traits_type;
  344.     typedef typename detail::basic_rpattern_base_impl<CI>::string_type     string_type;
  345.     typedef typename detail::basic_rpattern_base_impl<CI>::size_type       size_type;
  346.     typedef typename detail::basic_rpattern_base_impl<CI>::backref_type    backref_type;
  347.     typedef typename detail::basic_rpattern_base_impl<CI>::backref_vector  backref_vector;
  348.     // Work-around for an apparant bug in gcc
  349.     struct iter_wrap
  350.     {
  351.         typename string_type::iterator & ipat;
  352.         iter_wrap( typename string_type::iterator & i ) : ipat(i) {}
  353.     private:
  354.         iter_wrap( iter_wrap const & );
  355.         iter_wrap & operator=( iter_wrap const & );
  356.     };
  357.     void init(
  358.         string_type const & pat,
  359.         REGEX_FLAGS flags = NOFLAGS,
  360.         REGEX_MODE mode = MODE_DEFAULT ); //throw( bad_regexpr, std::bad_alloc );
  361.     void init(
  362.         string_type const & pat,
  363.         string_type const & subst,
  364.         REGEX_FLAGS flags = NOFLAGS,
  365.         REGEX_MODE mode = MODE_DEFAULT ); //throw( bad_regexpr, std::bad_alloc );
  366.     void set_substitution(
  367.         string_type const & subst ); //throw( bad_regexpr, std::bad_alloc );
  368.     REGEX_FLAGS flags() const                       { return impl::flags(); }
  369.     REGEX_MODE mode() const                         { return impl::mode(); }
  370.     width_type get_width() const                    { return impl::get_width(); }
  371.     size_t cgroups() const                          { return impl::cgroups(); }
  372.     string_type const & get_pat() const             { return impl::get_pat(); }
  373.     string_type const & get_subst() const           { return impl::get_subst(); }
  374.     void swap( basic_rpattern_base<CI, SY> & that ) { impl::swap( that ); }
  375.     static size_t const npos;
  376. protected:
  377.     basic_rpattern_base() //throw()
  378.         : detail::basic_rpattern_base_impl<CI>()
  379.     {
  380.     }
  381.     basic_rpattern_base(
  382.         basic_rpattern_base<CI, SY> const & that ) //throw()
  383.       : detail::basic_rpattern_base_impl<CI>( that.flags(), that.mode(), that.get_pat(), that.get_subst() )
  384.     {
  385.         // Don't call _normalize_string(). If that.flags()&NORMALIZE,
  386.         // then subst has already been normalized.
  387.         basic_rpattern_base<CI, SY>::_common_init( m_flags );
  388.         basic_rpattern_base<CI, SY>::_parse_subst( *m_subst, m_fuses_backrefs, m_subst_list ); // must come after _common_init
  389.     }
  390.     explicit basic_rpattern_base(
  391.         string_type const & pat, 
  392.         REGEX_FLAGS flags = NOFLAGS, 
  393.         REGEX_MODE mode = MODE_DEFAULT ) //throw( bad_regexpr, std::bad_alloc )
  394.       : detail::basic_rpattern_base_impl<CI>( flags, mode, pat )
  395.     {
  396.         basic_rpattern_base<CI, SY>::_common_init( m_flags );
  397.     }
  398.     basic_rpattern_base( 
  399.         string_type const & pat, 
  400.         string_type const & subst, 
  401.         REGEX_FLAGS flags = NOFLAGS, 
  402.         REGEX_MODE mode = MODE_DEFAULT ) //throw( bad_regexpr, std::bad_alloc )
  403.       : detail::basic_rpattern_base_impl<CI>( flags, mode, pat, subst )
  404.     {
  405.         basic_rpattern_base<CI, SY>::_common_init( m_flags );
  406.         _normalize_string( *m_subst );
  407.         basic_rpattern_base<CI, SY>::_parse_subst( *m_subst, m_fuses_backrefs, m_subst_list ); // must come after _common_init
  408.     }
  409.     basic_rpattern_base & operator=(
  410.         basic_rpattern_base<CI, SY> const & that ) //throw( bad_regexpr, std::bad_alloc )
  411.     {
  412.         basic_rpattern_base<CI, SY> temp( that );
  413.         swap( temp );
  414.         return *this;
  415.     }
  416.     detail::match_group_base<CI> * _find_next_group(
  417.         iter_wrap & iw,
  418.         detail::match_group_base<CI> * pgroup, syntax_type & sy,
  419.         std::vector<detail::match_group_base<CI>*> & rggroups );
  420.     bool _find_next(
  421.         iter_wrap & iw,
  422.         detail::match_group_base<CI> * pgroup, syntax_type & sy,
  423.         std::vector<detail::match_group_base<CI>*> & rggroups );
  424.     void _find_atom(
  425.         iter_wrap & iw,
  426.         detail::match_group_base<CI> * pgroup,
  427.         syntax_type & sy );
  428.     void _quantify(
  429.         std::auto_ptr<detail::sub_expr<CI> > & pnew,
  430.         iter_wrap & iw,
  431.         bool is_group,
  432.         syntax_type & sy );
  433.     void _add_subst_backref(
  434.         detail::subst_node & snode, 
  435.         size_t nbackref, 
  436.         size_t rstart,
  437.         bool & uses_backrefs,
  438.         detail::subst_list_type & subst_list ) const;
  439.     virtual void _parse_subst(
  440.         string_type & subst,
  441.         bool & uses_backrefs,
  442.         detail::subst_list_type & subst_list ) const;
  443.     virtual void _common_init( REGEX_FLAGS flags );
  444. };
  445. template< typename CI, typename SY >
  446. size_t const basic_rpattern_base<CI, SY>::npos = size_t( -1 );
  447. // VC6 is buggy in its handling of the typename keyword
  448. #if defined(_MSC_VER) & _MSC_VER < 1300
  449. # define REGEX_TYPENAME
  450. #else
  451. # define REGEX_TYPENAME typename
  452. #endif
  453. // --------------------------------------------------------------------------
  454. //
  455. // Class:       basic_rpattern
  456. //
  457. // Description: generic regex pattern object
  458. //
  459. // Methods:     basic_rpattern - c'tor
  460. //              basic_rpattern -
  461. //              basic_rpattern -
  462. //              match          - match from begin iter to end iter
  463. //              match          - match a null-terminated string
  464. //              match          - match a std::string
  465. //              count          - count matches from begin iter to end iter
  466. //              count          - count matches in a null-terminated string
  467. //              count          - count matches in a std::string
  468. //              substitute     - do substitutions in a std::string
  469. //              _do_match      - internal implementation
  470. //              _do_count      - internal implementation
  471. //
  472. // History:     8/13/2001 - ericne - Created
  473. //
  474. // --------------------------------------------------------------------------
  475. template< typename CI, typename SY = perl_syntax<REGEX_TYPENAME std::iterator_traits<CI>::value_type> >
  476. class basic_rpattern : public basic_rpattern_base<CI, SY>
  477. {
  478.     typedef detail::basic_rpattern_base_impl<CI> impl;
  479. public:
  480.     typedef typename basic_rpattern_base<CI, SY>::syntax_type     syntax_type;
  481.     typedef typename basic_rpattern_base<CI, SY>::char_type       char_type;
  482.     typedef typename basic_rpattern_base<CI, SY>::traits_type     traits_type;
  483.     typedef typename basic_rpattern_base<CI, SY>::string_type     string_type;
  484.     typedef typename basic_rpattern_base<CI, SY>::size_type       size_type;
  485.     typedef typename basic_rpattern_base<CI, SY>::backref_type    backref_type;
  486.     typedef typename basic_rpattern_base<CI, SY>::backref_vector  backref_vector;
  487.     basic_rpattern() //throw()
  488.       : basic_rpattern_base<CI, SY>()
  489.     {
  490.     }
  491.     basic_rpattern( basic_rpattern const & that )
  492.       : basic_rpattern_base<CI, SY>( that )
  493.     {
  494.     }
  495.     explicit basic_rpattern( 
  496.         string_type const & pat,
  497.         REGEX_FLAGS flags = NOFLAGS,
  498.         REGEX_MODE mode = MODE_DEFAULT ) //throw( bad_regexpr, std::bad_alloc )
  499.       : basic_rpattern_base<CI, SY>( pat, flags, mode )
  500.     {
  501.     }
  502.     basic_rpattern(
  503.         string_type const & pat,
  504.         string_type const & subst,
  505.         REGEX_FLAGS flags = NOFLAGS,
  506.         REGEX_MODE mode = MODE_DEFAULT ) //throw( bad_regexpr, std::bad_alloc )
  507.       : basic_rpattern_base<CI, SY>( pat, subst, flags, mode )
  508.     {
  509.     }
  510.     basic_rpattern & operator=( basic_rpattern<CI, SY> const & that ) //throw( bad_regexpr, std::bad_alloc )
  511.     {
  512.         basic_rpattern_base<CI, SY>::operator=( that );
  513.         return *this;
  514.     }
  515.     // CI2 must be convertible to type CI
  516.     template< typename CI2 >
  517.     backref_type const & match(
  518.         CI2 ibegin,
  519.         CI2 iend,
  520.         basic_match_results<CI> & results ) const
  521.     {
  522.         // If your compile breaks here, it is because CI2 is not
  523.         // convertible to type CI. Check the declaration of your rpattern object.
  524.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  525.         ( void ) iterator_types_are_not_convertible;
  526.         detail::match_param<CI> param = detail::matcher_helper<CI>::init_param( ibegin, iend, results );
  527.         return impl::_do_match( param, false ) ? results.backref(0) : detail::static_init<backref_type>::value;
  528.     }
  529.     template< typename CH >
  530.     backref_type const & match(
  531.         CH * szbegin,
  532.         basic_match_results<CI> & results ) const
  533.     {
  534.         // If your compile breaks here, it is because CI2 is not
  535.         // convertible to type CI. Check the declaration of your rpattern object.
  536.         typedef CH * CI2;
  537.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  538.         ( void ) iterator_types_are_not_convertible;
  539.         detail::match_param<CI> param = detail::matcher_helper<CI>::init_param( szbegin, (CH*)0, results );
  540.         return impl::_do_match( param, szbegin ) ? results.backref(0) : detail::static_init<backref_type>::value;
  541.     }
  542.     template< typename CH, typename TR, typename AL >
  543.     backref_type const & match(
  544.         std::basic_string<CH, TR, AL> const & str,
  545.         basic_match_results<CI> & results,
  546.         size_type pos,
  547.         size_type len ) const
  548.     {
  549.         // If your compile breaks here, it is because CI2 is not
  550.         // convertible to type CI. Check the declaration of your rpattern object.
  551.         typedef typename std::basic_string<CH, TR, AL>::const_iterator CI2;
  552.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  553.         ( void ) iterator_types_are_not_convertible;
  554.         detail::match_param<CI> param = detail::matcher_helper<CI>::init_param( str.begin(), str.begin(), results );
  555.         if( len == npos || pos + len >= str.size() )
  556.             param.istop = CI(str.end());
  557.         else
  558.             std::advance( param.istop, pos + len );
  559.         std::advance( param.istart, pos );
  560.         param.ibegin = param.istart;
  561.         return impl::_do_match( param, false ) ? results.backref(0) : detail::static_init<backref_type>::value;
  562.     }
  563.     template< typename CH, typename TR, typename AL >
  564.     backref_type const & match(
  565.         std::basic_string<CH, TR, AL> const & str,
  566.         basic_match_results<CI> & results ) const
  567.     {
  568.         return match( str, results, 0, impl::npos );
  569.     }
  570.     template< typename CI2 >
  571.     size_t count( CI2 ibegin, CI2 iend ) const
  572.     {
  573.         // If your compile breaks here, it is because CI2 is not
  574.         // convertible to type CI. Check the declaration of your rpattern object.
  575.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  576.         ( void ) iterator_types_are_not_convertible;
  577.         backref_vector rgbackrefs;
  578.         detail::match_param<CI> param( ibegin, iend, & rgbackrefs );
  579.         return impl::_do_count( param, false );
  580.     }
  581.     template< typename CH >
  582.     size_t count( CH * szbegin ) const
  583.     {
  584.         // If your compile breaks here, it is because CI2 is not
  585.         // convertible to type CI. Check the declaration of your rpattern object.
  586.         typedef CH * CI2;
  587.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  588.         ( void ) iterator_types_are_not_convertible;
  589.         backref_vector rgbackrefs;
  590.         // If your compile breaks here, it is because CH const * is not
  591.         // convertible to type CI. Check the declaration of your rpattern object.
  592.         detail::match_param<CI> param( szbegin, (CH*)0, & rgbackrefs );
  593.         return impl::_do_count( param, szbegin );
  594.     }
  595.     template< typename CH, typename TR, typename AL >
  596.     size_t count(
  597.         std::basic_string<CH, TR, AL> const & str,
  598.         size_type pos,
  599.         size_type len ) const
  600.     {
  601.         // If your compile breaks here, it is because CI2 is not
  602.         // convertible to type CI. Check the declaration of your rpattern object.
  603.         typedef typename std::basic_string<CH, TR, AL>::const_iterator CI2;
  604.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  605.         ( void ) iterator_types_are_not_convertible;
  606.         backref_vector rgbackrefs;
  607.         // If your compile breaks here, then the string you passed in has
  608.         // a different iterator type than this rpattern type is expecting
  609.         detail::match_param<CI> param( str.begin(), str.begin(), & rgbackrefs );
  610.         if( len == npos || pos + len >= str.size() )
  611.             param.istop = CI(str.end());
  612.         else
  613.             std::advance( param.istop, pos + len );
  614.         std::advance( param.istart, pos );
  615.         param.ibegin = param.istart;
  616.         return impl::_do_count( param, false );
  617.     }
  618.     template< typename CH, typename TR, typename AL >
  619.     size_t count( std::basic_string<CH, TR, AL> const & str ) const
  620.     {
  621.         return count( str, 0, impl::npos );
  622.     }
  623.     template< typename CH, typename TR, typename AL >
  624.     size_t substitute(
  625.         std::basic_string<CH, TR, AL> & str,
  626.         basic_subst_results<CH, TR, AL> & results,
  627.         size_type pos,
  628.         size_type len ) const
  629.     {
  630.         // If your compile breaks here, it is because CI2 is not
  631.         // convertible to type CI. Check the declaration of your rpattern object.
  632.         typedef typename std::basic_string<CH, TR, AL>::const_iterator CI2;
  633.         detail::static_assert< detail::is_convertible<CI2,CI>::value > const iterator_types_are_not_convertible;
  634.         ( void ) iterator_types_are_not_convertible;
  635.         return detail::matcher_helper<CI>::_Do_subst( *this, str, results, pos, len );
  636.     }
  637.     template< typename CH, typename TR, typename AL >
  638.     size_t substitute(
  639.         std::basic_string<CH, TR, AL> & str,
  640.         basic_subst_results<CH, TR, AL> & results ) const
  641.     {
  642.         return substitute( str, results, 0, impl::npos );
  643.     }
  644. };
  645. // --------------------------------------------------------------------------
  646. //
  647. // Class:       basic_rpattern_c
  648. //
  649. // Description: a pattern object optimized for matching C-style, NULL-
  650. //              terminated strings. It treats the null-terminator as
  651. //              the end-of-string condition.
  652. //
  653. // Methods:     basic_rpattern_c - c'tor
  654. //              basic_rpattern_c -
  655. //              basic_rpattern_c -
  656. //              match            - match a null-terminated string
  657. //              count            - count matches in a null-terminated string
  658. //              _do_match_c      - internal implementation
  659. //              _do_count_c      - internal implementation
  660. //
  661. // History:     8/13/2001 - ericne - Created
  662. //
  663. // --------------------------------------------------------------------------
  664. template< typename CH, typename SY = perl_syntax<CH> >
  665. class basic_rpattern_c : public basic_rpattern_base<CH const *, SY>
  666. {
  667.     typedef detail::basic_rpattern_base_impl<CH const *> impl;
  668. public:
  669.     typedef typename basic_rpattern_base<CH const *, SY>::syntax_type     syntax_type;
  670.     typedef typename basic_rpattern_base<CH const *, SY>::char_type       char_type;
  671.     typedef typename basic_rpattern_base<CH const *, SY>::traits_type     traits_type;
  672.     typedef typename basic_rpattern_base<CH const *, SY>::string_type     string_type;
  673.     typedef typename basic_rpattern_base<CH const *, SY>::size_type       size_type;
  674.     typedef typename basic_rpattern_base<CH const *, SY>::backref_type    backref_type;
  675.     typedef typename basic_rpattern_base<CH const *, SY>::backref_vector  backref_vector;
  676.     basic_rpattern_c() //throw()
  677.       : basic_rpattern_base<CH const *, SY>()
  678.     {
  679.     }
  680.     basic_rpattern_c( basic_rpattern_c const & that )
  681.       : basic_rpattern_base<CH const *, SY>( that )
  682.     {
  683.     }
  684.     explicit basic_rpattern_c(
  685.         string_type const & pat,
  686.         REGEX_FLAGS flags = NOFLAGS,
  687.         REGEX_MODE mode = MODE_DEFAULT ) //throw( bad_regexpr, std::bad_alloc )
  688.       : basic_rpattern_base<CH const *, SY>( pat, flags, mode )
  689.     {
  690.     }
  691.     basic_rpattern_c & operator=( basic_rpattern_c<CH, SY> const & that )
  692.     {
  693.         basic_rpattern_base<CH const *, SY>::operator=( that );
  694.         return *this;
  695.     }
  696.     backref_type const & match(
  697.         CH const * szbegin,
  698.         basic_match_results_c<CH> & results ) const
  699.     {
  700.         detail::match_param<CH const *> param = detail::matcher_helper<CH const *>::init_param( szbegin, 0, results );
  701.         return impl::_do_match( param, szbegin ) ? results.backref(0) : detail::static_init<backref_type>::value;
  702.     }
  703.     size_t count( CH const * szbegin ) const
  704.     {
  705.         backref_vector rgbackrefs;
  706.         detail::match_param<CH const *> param( szbegin, 0, & rgbackrefs );
  707.         return impl::_do_count( param, szbegin );
  708.     }
  709. };
  710. #if defined(UNICODE) | defined(_UNICODE)
  711. typedef wchar_t rechar_t;
  712. #else
  713. typedef char    rechar_t;
  714. #endif
  715. typedef std::basic_string<rechar_t> restring;
  716. // On many implementations of the STL, string::iterator is not a typedef
  717. // for char*. Rather, it is a wrapper class. As a result, the regex code 
  718. // gets instantiated twice, once for bare pointers (rpattern_c) and once for
  719. // the wrapped pointers (rpattern). But if there is a conversion from the 
  720. // bare ptr to the wrapped ptr, then we only need to instantiate the template
  721. // for the wrapped ptr, and the code will work for the bare ptrs, too.
  722. // This can be a significant space savings.  The REGEX_FOLD_INSTANTIONS 
  723. // macro controls this optimization. The default is "off" for backwards
  724. // compatibility. To turn the optimization on, compile with:
  725. // -DREGEX_FOLD_INSTANTIATIONS=1
  726. #ifndef REGEX_FOLD_INSTANTIATIONS
  727. #define REGEX_FOLD_INSTANTIATIONS 0
  728. #endif
  729. typedef ::regex::detail::select
  730.     REGEX_FOLD_INSTANTIATIONS &&
  731.         detail::is_convertible<rechar_t const *,restring::const_iterator>::value,
  732.     restring::const_iterator,
  733.     rechar_t const *
  734. >::type lpctstr_t;
  735. // For matching against null-terminated strings
  736. typedef basic_rpattern<lpctstr_t, perl_syntax<rechar_t> >  perl_rpattern_c;
  737. typedef basic_rpattern<lpctstr_t, posix_syntax<rechar_t> > posix_rpattern_c;
  738. // For matching against std::strings
  739. typedef basic_rpattern<restring::const_iterator, perl_syntax<rechar_t> >  perl_rpattern;
  740. typedef basic_rpattern<restring::const_iterator, posix_syntax<rechar_t> > posix_rpattern;
  741. // Default to perl syntax
  742. typedef perl_rpattern    rpattern;
  743. typedef perl_rpattern_c  rpattern_c;
  744. // typedefs for the commonly used match_results and subst_results
  745. typedef basic_match_results<restring::const_iterator> match_results;
  746. typedef basic_match_results<lpctstr_t>                match_results_c;
  747. typedef basic_subst_results<rechar_t>                 subst_results;
  748. #if defined(_MSC_VER) & _MSC_VER >= 1300
  749. // These are no longer useful, and will go away in a future release
  750. // You should be using the version without the _c
  751. # pragma deprecated( basic_rpattern_c )
  752. # pragma deprecated( basic_match_results_c )
  753. #endif
  754. //
  755. // Define some classes and macros for creating function-local
  756. // static const rpatterns in a thread-safe way
  757. //
  758. #if defined( _MSC_VER ) & defined( _MT )
  759. namespace detail
  760. {
  761. template< typename PAT >
  762. class rpattern_destroyer
  763. {
  764.     PAT           const & m_refPat;
  765.     bool volatile const & m_fConstructed;
  766. public:
  767.     rpattern_destroyer( volatile bool const & fConstructed, PAT const & refPat )
  768.         : m_fConstructed( fConstructed ), m_refPat( refPat )
  769.     {
  770.     }
  771.     ~rpattern_destroyer()
  772.     {
  773.         if( m_fConstructed )
  774.             ( &m_refPat )->~PAT();
  775.     }
  776. };
  777. struct CRegExLock
  778. {
  779.     CRegExLock();
  780.     ~CRegExLock();
  781. };
  782. } // namespace detail
  783. #define STATIC_RPATTERN_EX( type, var, params ) 
  784.     static unsigned char s_rgb_##var[ sizeof( type ) ]; 
  785.     static bool volatile s_f_##var = false; 
  786.     static type const & var = *reinterpret_cast<type*>( s_rgb_##var ); 
  787.     static regex::detail::rpattern_destroyer<type> const s_des_##var( s_f_##var, var ); 
  788.     if( ! s_f_##var ) 
  789.     { 
  790.     regex::detail::CRegExLock objLock; 
  791.         if( ! s_f_##var ) 
  792.         { 
  793.             new( static_cast<void*>( s_rgb_##var ) ) type params; 
  794.             s_f_##var = true; 
  795.         } 
  796.     }
  797. #else
  798. #define STATIC_RPATTERN_EX( type, var, params ) 
  799.     static type const var params;
  800. #endif
  801. #define STATIC_RPATTERN( var, params ) 
  802.     STATIC_RPATTERN_EX( regex::rpattern, var, params )
  803. #define STATIC_RPATTERN_C( var, params ) 
  804.     STATIC_RPATTERN_EX( regex::rpattern_c, var, params )
  805. //
  806. // ostream inserter operator for back-references
  807. //
  808. template< typename CH, typename TR, typename CI >
  809. inline std::basic_ostream<CH, TR> & operator<<(
  810.     std::basic_ostream<CH, TR> & sout,
  811.     backref_tag<CI> const & br )
  812. {
  813.     return br.print( sout );
  814. }
  815. } // namespace regex
  816. //
  817. // specializations for std::swap
  818. //
  819. namespace std
  820. {
  821.     template<> 
  822.     inline void swap( regex::detail::regex_arena & left, regex::detail::regex_arena & right )
  823.     {
  824.         left.swap( right );
  825.     }
  826.     template< typename CI, typename SY >
  827.     inline void swap( regex::basic_rpattern_base<CI, SY> & left, regex::basic_rpattern_base<CI, SY> & right )
  828.     {
  829.         left.swap( right );
  830.     }
  831. }
  832. #ifdef _MSC_VER
  833. #pragma warning( pop )
  834. #endif
  835. #endif