1 // regex TR1 header
2 #pragma once
3 #ifndef _REGEX_
4 #define _REGEX_
5 #ifndef RC_INVOKED
6
7  #if 1600 <= _MSC_VER
8   #ifndef _DISABLE_TRIGRAPH_WARNINGS
9      #pragma warning(default: 4837)
10   #endif /* _DISABLE_TRIGRAPH_WARNINGS */
11  #endif /* 1600 <= _MSC_VER */
12
13 #include <algorithm>
14 #include <iterator>
15 #include <limits>
16 #include <locale>
17 #include <memory>
18 #include <string>
19 #include <stdexcept>
20 #include <utility>
21 #include <vector>
22
23 #include <ctype.h>
24 #include <wchar.h>
25 #include <limits.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29  #pragma pack(push,_CRT_PACKING)
30  #pragma warning(push,3)
31  #pragma warning(disable: 4996)
32
33  #ifndef _ENHANCED_REGEX_VISUALIZER
34   #ifdef _DEBUG
35      #define _ENHANCED_REGEX_VISUALIZER    1
36   #else /* _DEBUG */
37      #define _ENHANCED_REGEX_VISUALIZER    0
38   #endif /* _DEBUG */
39  #endif /* _ENHANCED_REGEX_VISUALIZER */
40
41  #if _HAS_EXCEPTIONS
42
43  #else /* _HAS_EXCEPTIONS */
44  #error regex without exception handling not supported
45  #endif /* _HAS_EXCEPTIONS */
46
47   #define _REGEX_DIFFT(iter)    \
48     typename iterator_traits<iter>::difference_type
49   #define _REGEX_VALT(iter)    \
50     typename iterator_traits<iter>::value_type
51
52 _STD_BEGIN
53     namespace tr1 {    // TR1 additions
54
55     // NAMED CONSTANTS
56 enum _Meta
57     {    // meta character representations for parser
58     _Meta_lpar = '(',
59     _Meta_rpar = ')',
60     _Meta_dlr = '$',
61     _Meta_caret = '^',
62     _Meta_dot = '.',
63     _Meta_star = '*',
64     _Meta_plus = '+',
65     _Meta_query = '?',
66     _Meta_lsq = '[',
67     _Meta_rsq = ']',
68     _Meta_bar = '|',
69     _Meta_esc = '\\',
70     _Meta_dash = '-',
71     _Meta_lbr = '{',
72     _Meta_rbr = '}',
73     _Meta_comma = ',',
74     _Meta_colon = ':',
75     _Meta_equal = '=',
76     _Meta_exc = '!',
77     _Meta_eos = -1,
78     _Meta_nl = '\n',
79     _Meta_cr = '\r',
80     _Meta_bsp = '\b',
81     _Meta_chr = 0,
82
83     _Esc_bsl = '\\',
84     _Esc_word = 'b',
85     _Esc_not_word = 'B',
86     _Esc_ctrl_a = 'a',
87     _Esc_ctrl_b = 'b',
88     _Esc_ctrl_f = 'f',
89     _Esc_ctrl_n = 'n',
90     _Esc_ctrl_r = 'r',
91     _Esc_ctrl_t = 't',
Lines 92 ... 958 are skipped.
959         {    // return maximum possible number of capture groups
960         return (_Matches.max_size());
961         }
962
963     bool empty() const
964         {    // test if object is empty
965         return (_Matches.empty());
966         }
967
968     difference_type length(size_type _Sub = 0) const
969         {    // return length of capture group _Sub
970         return ((*this)[_Sub].length());
971         }
972
973     difference_type position(size_type _Sub = 0) const
974         {    // return offset of submatch _Sub
975         return (std::distance(_Org, (*this)[_Sub].first));
976         }
977
978     string_type str(size_type _Sub = 0) const
979         {    // return contents of submatch _Sub
980         return (string_type((*this)[_Sub]));
981         }
982
983     const_reference operator[](size_type _Sub) const
984         {    // return submatch _Sub
985         return (_Matches.size() <= _Sub ? _Null_elem : _Matches[_Sub]);
986         }
987
988     const_reference prefix() const
989         {    // return text preceding match
990         return (_Prefix);
991         }
992
993     const_reference suffix() const
994         {    // return text following match
995         return (_Suffix);
996         }
997
998     const_iterator begin() const
999         {    // return iterator for beginning of sequence of submatches
1000         return (_Matches.begin());
1001         }
1002
1003     const_iterator end() const
1004         {    // return iterator for end of sequence of submatches
1005         return (_Matches.end());
1006         }
1007
1008 #if _SECURE_SCL
1009     template<class _OutIt>
1010         _IF_CHK(_OutIt) format(_OutIt _Out,
1011             const string_type& _Fmt,
1012             regex_constants::match_flag_type _Flags) const
1013         {    // format text, replacing matches
1014         return (_Flags & regex_constants::format_sed
1015             ? _Format_sed(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags)
1016             : _Format_default(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags));
1017         }
1018
1019     template<class _OutElem, size_t _Size>
1020         _OutElem *format(_OutElem (&_Dest)[_Size],
1021             const string_type& _Fmt,
1022             regex_constants::match_flag_type _Flags) const
1023         {    // format text, replacing matches
1024         return (format(_STDEXT make_checked_array_iterator(_Dest, _Size),
1025             _Fmt, _Flags).base());
1026         }
1027
1028     template<class _OutIt>
1029         _SCL_INSECURE_DEPRECATE _IF_NOT_CHK(_OutIt) format(_OutIt _Out,
1030             const string_type& _Fmt,
1031             regex_constants::match_flag_type _Flags) const
1032         {    // format text, replacing matches
1033         return (_Flags & regex_constants::format_sed
1034             ? _Format_sed(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags)
1035             : _Format_default(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags));
1036         }
1037
1038 #else /* _SECURE_SCL */
1039     template<class _OutIt>
1040         _OutIt format(_OutIt _Out,
1041             const string_type& _Fmt,
1042             regex_constants::match_flag_type _Flags) const
1043         {    // format text, replacing matches
1044         return (_Flags & regex_constants::format_sed
1045             ? _Format_sed(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags)
1046             : _Format_default(*this, _Out, _Fmt.begin(), _Fmt.end(), _Flags));
1047         }
1048 #endif /* _SECURE_SCL */
1049
1050     template<class _OutIt>
1051         _OutIt format(_OutIt _Out,
1052             const string_type& _Fmt) const
1053         {    // format text, replacing matches
1054         return (format(_Out, _Fmt,
1055             regex_constants::format_default));
1056         }
1057
1058     string_type format(const string_type& _Fmt,
1059         regex_constants::match_flag_type _Flags =
1060             regex_constants::format_default) const
1061         {    // format text, replacing matches
1062         string_type _Str;
1063         format(back_inserter(_Str), _Fmt, _Flags);
1064         return (_Str);
1065         }
1066
1067     allocator_type get_allocator() const
1068         {    // return allocator object for submatches
1069         return (_Matches.get_allocator());
1070         }
1071
1072     void swap(match_results& _Right)
1073         {    // exchange contents with _Right
1074         _BidIt _Iter = _Org;
1075         _Org = _Right._Org;
1076         _Right._Org = _Iter;
1077
1078         _Matches.swap(_Right._Matches);
1079
1080         _Elem _Temp = _Right._Prefix;
1081         _Right._Prefix = _Prefix;
1082         _Prefix = _Temp;
1083
1084         _Temp = _Right._Suffix;
1085         _Right._Suffix = _Suffix;
1086         _Suffix = _Temp;
1087         }
1088
1089     void _Resize(unsigned _Nx)
1090         {    // allocate space for _Nx submatches
1091         _Matches.resize(_Nx);
1092         }
1093
1094     _Elem& _Pfx()
1095         {    // return modifiable pair of iterators to prefix
1096         return (_Prefix);
1097         }
1098
1099     _Elem& _Sfx()
1100         {    // return modifiable pair of iterators to suffix
1101         return (_Suffix);
1102         }
1103
1104     _Elem& _Null()
1105         {    // return modifiable pair of iterators for null element
1106         return (_Null_elem);
1107         }
1108
1109     _Elem& _At(unsigned _Sub)
1110         {    // unchecked access to element at _Sub
1111         return (_Matches[_Sub]);
1112         }
1113
1114     _Elem _At(unsigned _Sub) const
1115         {    // unchecked access to element at _Sub
1116         return (_Matches[_Sub]);
1117         }
1118
1119     _BidIt _Org;
1120
1121 private:
1122     _MyCont _Matches;
1123     _Elem _Prefix;
1124     _Elem _Suffix;
1125     _Elem _Null_elem;
1126     };
1127
1128     // TEMPLATE OPERATORS FOR match_results
1129 template<class _BidIt,
1130     class _Alloc>
1131     bool operator==(const match_results<_BidIt, _Alloc>& _Left,
1132         const match_results<_BidIt, _Alloc>& _Right)
1133     {    // compare results for equality
1134     return (_Left.str() == _Right.str());
1135     }
1136
1137 template<class _BidIt,
1138     class _Alloc>
1139     bool operator!=(const match_results<_BidIt, _Alloc>& _Left,
1140         const match_results<_BidIt, _Alloc>& _Right)
1141     {    // compare results for inequality
1142     return (!(_Left == _Right));
1143     }
1144
1145     // NFA PROPERTIES
1146 typedef unsigned long _Grps;
1147 const int _MAX_GRP = sizeof(_Grps) * CHAR_BIT;
1148 const int _BRE_MAX_GRP = 9;
1149
1150 const int _Bmp_max = 256;    // must fit in an int
1151 const int _Bmp_shift = 3;
1152 const int _Bmp_chrs = 1 << _Bmp_shift;    // # of bits to be stored in each char
1153 const int _Bmp_mask = _Bmp_chrs - 1;
1154 const int _Bmp_size = (_Bmp_max + _Bmp_chrs - 1) / _Bmp_chrs;
1155
1156 const int _Buf_incr = 16;
1157 const int _ARRAY_THRESHOLD = 4;
1158
1159 enum _Node_flags
1160     {    // flags for nfa nodes with special properties
1161     _Fl_none = 0x00,
1162     _Fl_negate = 0x01,
1163     _Fl_greedy = 0x02,
1164     _Fl_final = 0x04,
1165     _Fl_longest = 0x08
1166     };
1167
1168 inline _Node_flags operator|(_Node_flags _Left, _Node_flags _Right)
1169     {    // bitwise or
1170     return (_Node_flags((int)_Left | _Right));
1171     }
1172
1173 inline _Node_flags operator|=(_Node_flags& _Left, _Node_flags _Right)
1174     {    // bitwise or
1175     return (_Left = _Node_flags((int)_Left | _Right));
1176     }
1177
1178 enum _Node_type
1179     {    // type flag for nfa nodes
1180     _N_none,
1181     _N_nop,
1182     _N_bol,
1183     _N_eol,
1184     _N_wbound,
1185     _N_dot,
1186     _N_str,
1187     _N_class,
1188     _N_group,
1189     _N_end_group,
1190     _N_assert,
1191     _N_neg_assert,
1192     _N_end_assert,
1193     _N_capture,
1194     _N_end_capture,
1195     _N_back,
1196     _N_if,
1197     _N_endif,
1198     _N_rep,
1199     _N_end_rep,
1200     _N_begin,
1201     _N_end
1202     };
1203
1204     // TEMPLATE CLASS _Buf
1205 template<class _Elem>
1206     struct _Buf
1207     {    // character buffer
1208     _Buf()
1209         : _Sz(0), _Nchrs(0), _Chrs(0)
1210         {    // construct
1211         }
1212
1213     ~_Buf()
1214         {    // destroy
1215         free(_Chrs);
1216         }
1217
1218     int _Size() const
1219         {    // return number of characters held in buffer
1220         return (_Nchrs);
1221         }
1222
1223     _Elem _At(unsigned _Idx) const
1224         {    // return character at _Idx
1225  #if _HAS_ITERATOR_DEBUGGING
1226             if (_Nchrs <= _Idx)
1227                 _DEBUG_ERROR("_Buf subscript out of range");
1228  #else /* _HAS_ITERATOR_DEBUGGING */
1229         _SCL_SECURE_VALIDATE_RANGE(_Idx < _Nchrs);
1230  #endif /* _HAS_ITERATOR_DEBUGGING */
1231         return (_Chrs[_Idx]);
1232         }
1233
1234     const _Elem *_Str() const
1235         {    // return pointer to first character
1236         return (_Chrs);
1237         }
1238
1239     void _Insert(_Elem _Ch)
1240         {    // append _Ch
1241         if (_Sz <= _Nchrs)
1242             _Expand(_Nchrs + _Buf_incr);
1243         _Chrs[_Nchrs++] = _Ch;
1244         }
1245
1246     _Elem _Del()
1247         {    // remove and return last charcter
1248         return (_Chrs[--_Nchrs]);
1249         }
1250
1251     template<class _FwdIt>
1252         void _Insert(_FwdIt _First, _FwdIt _Last)
1253         {    // append multiple characters
1254         while (_First != _Last)
1255             _Insert(*_First++);
1256         }
1257
1258 private:
1259     void _Expand(int _Len)
1260         {    // expand buffer to hold _Len characters
1261         _Elem *_Tmp = (_Elem*)realloc(_Chrs, _Len * sizeof(_Elem));
1262         if (!_Tmp)
1263             _Xmem();
1264         _Chrs = _Tmp;
1265         _Sz = _Len;
1266         }
1267
1268     unsigned _Sz;
1269     unsigned _Nchrs;
1270     _Elem *_Chrs;
1271     };
1272
1273     // STRUCT _Bitmap
1274 struct _Bitmap
1275     {    // accelerator table for small character values
Lines 1276 ... 1905 are skipped.
1906         {    // construct empty object
1907         }
1908
1909     explicit basic_regex(_In_z_ const _Elem *_Ptr,
1910         flag_type _Flags = regex_constants::ECMAScript)
1911         : _Rep(0)
1912         {    // construct from null terminated character sequence
1913         _Reset(_Ptr, _Ptr + _RxTraits::length(_Ptr),
1914             _Flags, random_access_iterator_tag());
1915         }
1916
1917     basic_regex(_In_count_(_Len) const _Elem *_Ptr, size_t _Len,
1918         flag_type _Flags = regex_constants::ECMAScript)
1919         : _Rep(0)
1920         {    // construct from character sequence
1921         if (_Ptr == 0)
1922             _Xbad(regex_constants::error_parse);
1923         _Reset(_Ptr, _Ptr + _Len, _Flags, random_access_iterator_tag());
1924         }
1925
1926     template<class _STtraits,
1927         class _STalloc>
1928         explicit basic_regex(
1929             const std::basic_string<_Elem, _STtraits, _STalloc>& _Str,
1930             flag_type _Flags = regex_constants::ECMAScript)
1931         : _Rep(0)
1932         {    // construct from string object
1933         _Reset(_Str.begin(), _Str.end(), _Flags, random_access_iterator_tag());
1934         }
1935
1936     template<class _InIt>
1937         basic_regex(_InIt _First, _InIt _Last,
1938             flag_type _Flags)
1939         : _Rep(0)
1940         {    // construct from pair of iterators
1941         _DEBUG_RANGE(_First, _Last);
1942         _Reset(_First, _Last, _Flags, _STD _Iter_cat(_First));
1943         }
1944
1945     template<class _InIt>
1946         basic_regex(_InIt _First, _InIt _Last)
1947         : _Rep(0)
1948         {    // construct from pair of iterators
1949         _DEBUG_RANGE(_First, _Last);
1950         _Reset(_First, _Last, regex_constants::ECMAScript,
1951             _STD _Iter_cat(_First));
1952         }
1953
1954     basic_regex(const _MyT& _Right)
1955  #if _ENHANCED_REGEX_VISUALIZER
1956         : _Rep(0), _Visualization(_Right._Visualization)
1957  #else /* _ENHANCED_REGEX_VISUALIZER */
1958         : _Rep(0)
1959  #endif /* _ENHANCED_REGEX_VISUALIZER */
1960         {    // construct copy of _Right
1961         _Reset(_Right._Rep);
1962         }
1963
1964     ~basic_regex()
1965         {    // destroy the object
1966         _Tidy();
1967         }
1968
1969     _MyT& operator=(const _MyT& _Right)
1970         {    // replace with copy of _Right
1971         return (assign(_Right));
1972         }
1973
1974     _MyT& operator=(_In_z_ const _Elem *_Ptr)
1975         {    // replace with regular expression constructed from _Ptr
1976         _Reset(_Ptr, _Ptr + _RxTraits::length(_Ptr),
1977             ECMAScript, random_access_iterator_tag());
1978         return (*this);
1979         }
1980
1981     template<class _STtraits,
1982         class _STalloc>
1983         _MyT& operator=(
1984             const _STD basic_string<_Elem, _STtraits, _STalloc>& _Str)
1985         {    // replace with regular expression constructed from _Str
1986         _Reset(_Str.begin(), _Str.end(),
1987             ECMAScript, random_access_iterator_tag());
1988         return (*this);
1989         }
1990
1991     unsigned mark_count() const
1992         {    // return number of capture groups
1993         return (_Rep ? _Rep->_Marks - 1 : 0);
1994         }
1995
1996     _MyT& assign(const _MyT& _Right)
1997         {    // replace with copy of _Right
1998  #if _ENHANCED_REGEX_VISUALIZER
1999         _Visualization = _Right._Visualization;
2000  #endif /* _ENHANCED_REGEX_VISUALIZER */
2001
2002         _Reset(_Right._Rep);
2003         return (*this);
2004         }
2005
2006     _MyT& assign(_In_z_ const _Elem *_Ptr,
2007         flag_type _Flags = regex_constants::ECMAScript)
2008         {    // replace with regular expression constructed from _Ptr
2009         return (assign(_Ptr, _RxTraits::length(_Ptr), _Flags));
2010         }
2011
2012     _MyT& assign(_In_count_(_Len) const _Elem *_Ptr, size_t _Len,
2013         flag_type _Flags = regex_constants::ECMAScript)
2014         {    // replace with regular expression constructed from _Ptr, _Len
2015         _Reset(_Ptr, _Ptr + _Len,
2016             _Flags, random_access_iterator_tag());
2017         return (*this);
2018         }
2019
2020     template<class _STtraits,
2021         class _STalloc>
2022         _MyT& assign(
2023             const std::basic_string<_Elem, _STtraits, _STalloc>& _Str,
2024             flag_type _Flags = regex_constants::ECMAScript)
2025         {    // replace with regular expression constructed from _Str
2026         _Reset(_Str.begin(), _Str.end(),
2027             _Flags, random_access_iterator_tag());
2028         return (*this);
2029         }
2030
2031     template<class _InIt>
2032         _MyT& assign(_InIt _First, _InIt _Last,
2033             flag_type _Flags = regex_constants::ECMAScript)
2034         {    // replace with regular expression constructed from [_First, _Last)
2035         _DEBUG_RANGE(_First, _Last);
2036         _Reset(_First, _Last, _Flags, _Iter_cat(_First));
2037         return (*this);
2038         }
2039
2040     flag_type flags() const
2041         {    // return syntax option flags
2042         return (_Rep ? _Rep->_Fl : (flag_type)0);
2043         }
2044
2045     locale_type imbue(locale_type _Loc)
2046         {    // clear regular expression and set locale to argument
2047         _Tidy();
2048         return (_Traits.imbue(_Loc));
2049         }
2050
2051     locale_type getloc() const
2052         {    // return copy of locale object
2053         return (_Traits.getloc());
2054         }
2055
2056     void swap(_MyT& _Right) _THROW0()
2057         {    // exchange contents with _Right
2058         _Root_node *_Tmp = _Rep;
2059         _Rep = _Right._Rep;
2060         _Right._Rep = _Tmp;
2061
2062  #if _ENHANCED_REGEX_VISUALIZER
2063         _Visualization.swap(_Right._Visualization);
2064  #endif /* _ENHANCED_REGEX_VISUALIZER */
2065         }
2066
2067     _Root_node *_Get() const
2068         {    // return pointer to root node
2069         return (_Rep);
2070         }
2071
2072     bool _Empty() const
2073         {
2074         return (_Rep == 0);
2075         }
2076
2077 private:
2078     _Root_node *_Rep;
2079     _RxTraits _Traits;
2080
2081  #if _ENHANCED_REGEX_VISUALIZER
2082     std::basic_string<_Elem> _Visualization;
2083  #endif /* _ENHANCED_REGEX_VISUALIZER */
2084
2085     void _Tidy()
2086         {    // free all storage
2087         if (_Rep && --_Rep->_Refs == 0)
2088             _Destroy_node(_Rep);
2089         _Rep = 0;
2090         }
2091
2092     template<class _InIt>
2093         void _Reset(_InIt _First, _InIt _Last,
2094             flag_type _Flags, input_iterator_tag)
2095         {    // build regular expression from input iterators
2096         std::basic_string<_REGEX_VALT(_InIt)> _Str(_First, _Last);
2097
2098         _Reset(_Str.begin(), _Str.end(),
2099             _Flags, forward_iterator_tag());
2100         }
2101
2102     template<class _FwdIt>
2103         void _Reset(_FwdIt _First, _FwdIt _Last,
2104             flag_type _Flags, forward_iterator_tag)
2105         {    // build regular expression from forward iterators
2106  #if _ENHANCED_REGEX_VISUALIZER
2107         _Visualization.assign(_First, _Last);
2108  #endif /* _ENHANCED_REGEX_VISUALIZER */
2109
2110         _Parser<_FwdIt, _Elem, _RxTraits>
2111             _Prs(_Traits, _First, _Last, _Flags);
2112         _Root_node *_Rx = _Prs._Compile();
2113         _Reset(_Rx);
2114         }
2115
2116     void _Reset(_Root_node *_Rx)
2117         {    // build regular expression holding root node _Rx
2118         if (_Rx != 0)
2119             ++_Rx->_Refs;
2120         _Tidy();
2121         _Rep = _Rx;
2122         }
2123     };
2124
2125
2126 template<class _Elem,
2127     class _RxTraits>
2128     void swap(basic_regex<_Elem, _RxTraits>& _Left,
2129         basic_regex<_Elem, _RxTraits>& _Right) _THROW0()
2130     {    // exchange contents of _Left with _Right
2131     _Left.swap(_Right);
2132     }
2133
2134 template<class _BidIt,
2135     class _Alloc>
2136     void swap(match_results<_BidIt, _Alloc>& _Left,
2137         match_results<_BidIt, _Alloc>& _Right) _THROW0()
2138     {    // exchange contents of _Left with _Right
2139     _Left.swap(_Right);
2140     }
2141
2142 typedef basic_regex<char> regex;
2143 typedef basic_regex<wchar_t> wregex;
2144 typedef match_results<const char*> cmatch;
2145 typedef match_results<const wchar_t*> wcmatch;
2146 typedef match_results<string::const_iterator> smatch;
2147 typedef match_results<wstring::const_iterator> wsmatch;
2148
2149 #define _Isdigit(x) ('0' <= (x) && (x) <= '9')
2150
2151     // TEMPLATE FUNCTION _Format_default
2152 template<class _BidIt,
2153     class _Alloc,
2154     class _InIt,
2155     class _OutIt> inline
2156     _OutIt _Format_default(
Lines 2157 ... 4736 are skipped.
4737         regex_constants::syntax_option_type _Fx)
4738     : _Pat(_Pfirst), _Begin(_Pfirst), _End(_Plast),
4739         _Grp_idx(0), _Disj_count(0), _Finished_grps(0),
4740         _Nfa(_Tr, _Fx), _Traits(_Tr), _Flags(_Fx)
4741     {    // construct
4742     using namespace regex_constants;
4743     _L_flags = (_Flags & _Gmask) == ECMAScript
4744         || (_Flags & _Gmask) == 0 ? _ECMA_flags
4745         : (_Flags & _Gmask) == basic ? _Basic_flags
4746         : (_Flags & _Gmask) == extended ? _Extended_flags
4747         : (_Flags & _Gmask) == awk ? _Awk_flags
4748         : (_Flags & _Gmask) == grep ? _Grep_flags
4749         : (_Flags & _Gmask) == egrep ? _Egrep_flags
4750         : 0;
4751     if (_L_flags & _L_mtch_long)
4752         _Nfa._Setlong();
4753     _Trans();
4754     }
4755     }    // namespace tr1
4756
4757 template<class _Elem,
4758     class _RxTraits>
4759     class _Move_operation_category<tr1::basic_regex<_Elem, _RxTraits> >
4760     {    // basic_regex implements a performant swap
4761 public:
4762     typedef _Swap_move_tag _Move_cat;
4763     };
4764
4765 template<class _BidIt,
4766     class _Alloc>
4767     class _Move_operation_category<tr1::match_results<_BidIt, _Alloc> >
4768     {    // match_results implements a performant swap
4769 public:
4770     typedef _Swap_move_tag _Move_cat;
4771     };
4772
4773 _STD_END
4774  #pragma warning(default: 4996)
4775  #pragma warning(pop)
4776  #pragma pack(pop)
4777
4778 #endif /* RC_INVOKED */
4779 #endif /*_REGEX_ */
4780
4781 /*
4782  * Copyright (c) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
4783  * Consult your license regarding permissions and restrictions.
4784 V5.05:0009 */
4785