diff --git a/include/regex b/include/regex index 7f515a63..417dec00 100644 --- a/include/regex +++ b/include/regex @@ -721,6 +721,9 @@ typedef regex_token_iterator wsregex_token_iterator; #include #include <__locale> #include +#include +#include +#include #pragma GCC system_header @@ -1209,6 +1212,114 @@ regex_traits<_CharT>::__value(wchar_t __ch, int __radix) const return __value(static_cast(__ct_->narrow(__ch, char_type())), __radix); } +template class __transition; + +template +class __state +{ + typedef __transition<_CharT> __transition; + __transition* __t1_; + __transition* __t2_; + int __state_; + enum + { + __1_not_tried = 0, + __1_succeded = 1, + __1_failed = 2, + __2_not_tried = 0, + __2_succeded = 4, + __2_failed = 8 + }; + + __state(const __state&); + __state& operator=(const __state&); +public: + __state() + : __t1_(), __t2_(), __state_() {} + ~__state(); + + const __state* operator()(_CharT __c); + + void __add_one(__transition* __t) {__t1_ = __t;} +}; + +template +__state<_CharT>::~__state() +{ + delete __t1_; + delete __t2_; +} + +template +const __state<_CharT>* +__state<_CharT>::operator()(_CharT __c) +{ + const __state* __r = nullptr; + if ((__state_ & 3) == 0) + { + if (__t1_) + { + __r = (*__t1_)(__c); + if (__r) + __state_ |= __1_succeded; + else + __state_ |= __1_failed; + } + else + __state_ |= __1_failed; + } + else if ((__state_ & 0xC) == 0) + { + if (__t2_) + { + __r = (*__t2_)(__c); + if (__r) + __state_ |= __2_succeded; + else + __state_ |= __2_failed; + } + else + __state_ |= __2_failed; + } + return __r; +} + +template +class __transition +{ + __transition(const __transition&); + __transition& operator=(const __transition&); + + typedef __state<_CharT> __state; + typedef unique_ptr<__state, void(*)(__state*)> __sptr; + + static void __delete_state(__state* __p) {delete __p;} + static void __ignore_state(__state*) {} + +protected: + __sptr __sptr_; +public: + __transition(bool __owns, __state* __st) + : __sptr_(__st, __owns ? &__delete_state : &__ignore_state) {} + virtual ~__transition() {} + + virtual const __state* operator()(_CharT) const {return __sptr_.get();} +}; + +template +class __match_char + : public __transition<_CharT> +{ + typedef __transition<_CharT> base; + _CharT __c_; +public: + __match_char(_CharT __c, bool __owns, __state<_CharT>* __st) + : base(__owns, __st), __c_(__c) {} + + virtual const __state<_CharT>* operator()(_CharT __c) const + {return __c == __c_ ? base::__sptr_.get() : nullptr;} +}; + template > class basic_regex { @@ -1222,6 +1333,9 @@ private: _Traits __traits_; flag_type __flags_; unsigned __marked_count_; + int __open_count_; + shared_ptr<__state<_CharT> > __start_; + __state<_CharT>* __end_; public: // constants: @@ -1239,10 +1353,10 @@ public: // construct/copy/destroy: basic_regex(); explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript) - : __flags_(__f), __marked_count_(0) + : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0) {__parse(__p, __p + __traits_.length(__p));} basic_regex(const value_type* __p, size_t __len, flag_type __f) - : __flags_(__f), __marked_count_(0) + : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0) {__parse(__p, __p + __len);} basic_regex(const basic_regex&); #ifdef _LIBCPP_MOVE @@ -1251,16 +1365,16 @@ public: template explicit basic_regex(const basic_string& __p, flag_type __f = regex_constants::ECMAScript) - : __flags_(__f), __marked_count_(0) + : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0) {__parse(__p.begin(), __p.end());} template basic_regex(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript) - : __flags_(__f), __marked_count_(0) + : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0) {__parse(__first, __last);} basic_regex(initializer_list __il, flag_type __f = regex_constants::ECMAScript) - : __flags_(__f), __marked_count_(0) + : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0) {__parse(__il.begin(), __il.end());} ~basic_regex(); @@ -1343,6 +1457,9 @@ private: template _ForwardIterator __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last); template _ForwardIterator __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last); @@ -1364,6 +1481,24 @@ private: template _ForwardIterator __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c); + template + _ForwardIterator + __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last); + template + _ForwardIterator + __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last); void __push_l_anchor() {} void __push_r_anchor() {} @@ -1375,11 +1510,12 @@ private: void __start_matching_list() {} void __end_nonmatching_list() {} void __end_matching_list() {} - void __push_char(value_type __c) {} + void __push_char(value_type __c); void __push_char(const typename _Traits::string_type& __c) {} void __push_range() {} void __push_class_type(typename _Traits::char_class_type) {} void __push_back_ref(int __i) {} + void __push_alternation() {} }; template @@ -1408,6 +1544,7 @@ basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, __parse_basic_reg_exp(__first, __last); break; case extended: + __parse_extended_reg_exp(__first, __last); break; case awk: break; @@ -1452,6 +1589,81 @@ basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first, return __first; } +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first, + _ForwardIterator __last) +{ + while (true) + { + _ForwardIterator __temp = __parse_ERE_branch(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_temp); + __first = __temp; + if (__first == __last) + break; + if (*__first != '|') + throw regex_error(regex_constants::error_temp); + __push_alternation(); + ++__first; + } + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_ERE_expression(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_temp); + do + { + __first = __temp; + __temp = __parse_ERE_expression(__first, __last); + } while (__temp != __first); + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last); + if (__temp == __first && __temp != __last) + { + switch (*__temp) + { + case '^': + __push_l_anchor(); + ++__temp; + break; + case '$': + __push_r_anchor(); + ++__temp; + break; + case '(': + ++__marked_count_; + ++__open_count_; + __temp = __parse_extended_reg_exp(++__temp, __last); + if (__temp == __last || *__temp != ')') + throw regex_error(regex_constants::error_paren); + --__open_count_; + ++__temp; + break; + } + } + if (__temp != __first) + __temp = __parse_ERE_dupl_symbol(__temp, __last); + __first = __temp; + return __first; +} + template template _ForwardIterator @@ -1499,12 +1711,12 @@ basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first, __temp = __parse_Back_open_paren(__first, __last); if (__temp != __first) { + ++__marked_count_; __first = __parse_RE_expression(__temp, __last); __temp = __parse_Back_close_paren(__first, __last); if (__temp == __first) throw regex_error(regex_constants::error_paren); __first = __temp; - ++__marked_count_; } else __first = __parse_BACKREF(__first, __last); @@ -1519,22 +1731,48 @@ basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE( _ForwardIterator __first, _ForwardIterator __last) { - _ForwardIterator __temp = __first; - __first = __parse_ORD_CHAR(__first, __last); + _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last); if (__temp == __first) { - __first = __parse_QUOTED_CHAR(__first, __last); + __temp = __parse_QUOTED_CHAR(__first, __last); if (__temp == __first) { - if (__first != __last && *__first == '.') + if (__temp != __last && *__temp == '.') { __push_match_any(); - ++__first; + ++__temp; } else - __first = __parse_bracket_expression(__first, __last); + __temp = __parse_bracket_expression(__first, __last); } } + __first = __temp; + return __first; +} + +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE( + _ForwardIterator __first, + _ForwardIterator __last) +{ + _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last); + if (__temp == __first) + { + __temp = __parse_QUOTED_CHAR_ERE(__first, __last); + if (__temp == __first) + { + if (__temp != __last && *__temp == '.') + { + __push_match_any(); + ++__temp; + } + else + __temp = __parse_bracket_expression(__first, __last); + } + } + __first = __temp; return __first; } @@ -1651,6 +1889,44 @@ basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first, return __first; } +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '^': + case '.': + case '[': + case '$': + case '(': + case '|': + case '*': + case '+': + case '?': + case '{': + case '\\': + break; + case ')': + if (__open_count_ == 0) + { + __push_char(*__first); + ++__first; + } + break; + default: + __push_char(*__first); + ++__first; + break; + } + } + return __first; +} + template template _ForwardIterator @@ -1682,6 +1958,43 @@ basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first, return __first; } +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + _ForwardIterator __temp = next(__first); + if (__temp != __last) + { + if (*__first == '\\') + { + switch (*__temp) + { + case '^': + case '.': + case '*': + case '[': + case '$': + case '\\': + case '(': + case ')': + case '|': + case '+': + case '?': + case '{': + __push_char(*__temp); + __first = ++__temp; + break; + } + } + } + } + return __first; +} + template template _ForwardIterator @@ -1740,6 +2053,75 @@ basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first, return __first; } +template +template +_ForwardIterator +basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, + _ForwardIterator __last) +{ + if (__first != __last) + { + switch (*__first) + { + case '*': + __push_greedy_inf_repeat(0); + ++__first; + break; + case '+': + __push_greedy_inf_repeat(1); + ++__first; + break; + case '?': + __push_repeat(0, 1); + ++__first; + break; + case '{': + { + int __min; + _ForwardIterator __temp = __parse_DUP_COUNT(__first, __last, __min); + if (__temp == __first) + throw regex_error(regex_constants::error_badbrace); + __first = __temp; + if (__first == __last) + throw regex_error(regex_constants::error_brace); + switch (*__first) + { + case '}': + __push_exact_repeat(__min); + ++__first; + break; + case ',': + if (++__first == __last) + throw regex_error(regex_constants::error_badbrace); + if (*__first == '}') + { + __push_greedy_inf_repeat(__min); + ++__first; + } + else + { + int __max; + __temp = __parse_DUP_COUNT(__first, __last, __max); + if (__temp == __first) + throw regex_error(regex_constants::error_brace); + __first = __temp; + if (__first == __last || *__first != '}') + throw regex_error(regex_constants::error_brace); + ++__first; + if (__max < __min) + throw regex_error(regex_constants::error_badbrace); + __push_repeat(__min, __max); + } + default: + throw regex_error(regex_constants::error_badbrace); + } + } + break; + } + } + return __first; +} + template template _ForwardIterator @@ -1951,9 +2333,442 @@ basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first, return __first; } +template +void +basic_regex<_CharT, _Traits>::__push_char(value_type __c) +{ + unique_ptr<__state<_CharT> > __new_end(new __state<_CharT>); + unique_ptr<__transition<_CharT> > __new_transition( + new __match_char<_CharT>(__c, true, __new_end.get())); + __state<_CharT>* __e = __new_end.release(); + if (__end_ == nullptr) + { + __start_.reset(new __state<_CharT>); + __end_ = __start_.get(); + } + __end_->__add_one(__new_transition.release()); + __end_ = __e; +} + typedef basic_regex regex; typedef basic_regex wregex; +// sub_match + +template +class sub_match + : public pair<_BidirectionalIterator, _BidirectionalIterator> +{ +public: + typedef _BidirectionalIterator iterator; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef basic_string string_type; + + bool matched; + + difference_type length() const + {return matched ? _STD::distance(this->first, this->second) : 0;} + string_type str() const + {return matched ? string_type(this->first, this->second) : string_type();} + operator string_type() const + {return str();} + + int compare(const sub_match& __s) const + {return str().compare(__s.str());} + int compare(const string_type& __s) const + {return str().compare(__s);} + int compare(const value_type* __s) const + {return str().compare(__s);} +}; + +typedef sub_match csub_match; +typedef sub_match wcsub_match; +typedef sub_match ssub_match; +typedef sub_match wssub_match; + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __x.compare(__y) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __x.compare(__y) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x.c_str()) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x.c_str()) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const basic_string::value_type, _ST, _SA>& __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __x.compare(__y.c_str()) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __x.compare(__y.c_str()) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool operator>(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + const basic_string::value_type, _ST, _SA>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y.compare(__x) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(typename iterator_traits<_BiIter>::value_type const* __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __x.compare(__y) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __x.compare(__y) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const* __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + typedef basic_string::value_type> string_type; + return __y.compare(string_type(1, __x)) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + typedef basic_string::value_type> string_type; + return __y.compare(string_type(1, __x)) > 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(typename iterator_traits<_BiIter>::value_type const& __x, + const sub_match<_BiIter>& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator==(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + typedef basic_string::value_type> string_type; + return __x.compare(string_type(1, __y)) == 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator!=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__x == __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + typedef basic_string::value_type> string_type; + return __x.compare(string_type(1, __y)) < 0; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return __y < __x; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator>=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__x < __y); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +bool +operator<=(const sub_match<_BiIter>& __x, + typename iterator_traits<_BiIter>::value_type const& __y) +{ + return !(__y < __x); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _ST>& +operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m) +{ + return __os << __m.str(); +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_REGEX diff --git a/test/re/re.regex/re.regex.construct/ptr_flg.pass.cpp b/test/re/re.regex/re.regex.construct/ptr_flg.pass.cpp index 060fb20e..f2d7c814 100644 --- a/test/re/re.regex/re.regex.construct/ptr_flg.pass.cpp +++ b/test/re/re.regex/re.regex.construct/ptr_flg.pass.cpp @@ -13,6 +13,8 @@ // basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript); +#include + #include #include diff --git a/test/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp b/test/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp new file mode 100644 index 00000000..a2538a66 --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/compare_string_type.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// int compare(const string_type& s) const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + typedef SM::string_type string; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare(string()) == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare(string()) > 0); + assert(sm.compare(string("123")) == 0); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + typedef SM::string_type string; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare(string()) == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare(string()) > 0); + assert(sm.compare(string(L"123")) == 0); + } +} diff --git a/test/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp b/test/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp new file mode 100644 index 00000000..5eb962fc --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/compare_sub_match.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// int compare(const sub_match& s) const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare(sm2) == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare(sm2) > 0); + sm2.first = s; + sm2.second = s + 3; + sm2.matched = true; + assert(sm.compare(sm2) == 0); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare(sm2) == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare(sm2) > 0); + sm2.first = s; + sm2.second = s + 3; + sm2.matched = true; + assert(sm.compare(sm2) == 0); + } +} diff --git a/test/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp b/test/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp new file mode 100644 index 00000000..72e8eb3f --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/compare_value_type_ptr.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// int compare(const value_type* s) const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare("") == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare("") > 0); + assert(sm.compare("123") == 0); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM sm2 = SM(); + assert(sm.compare(L"") == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.compare(L"") > 0); + assert(sm.compare(L"123") == 0); + } +} diff --git a/test/re/re.submatch/re.submatch.members/length.pass.cpp b/test/re/re.submatch/re.submatch.members/length.pass.cpp new file mode 100644 index 00000000..42b645e2 --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/length.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// difference_type length() const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + SM sm = SM(); + assert(sm.length() == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.length() == 3); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + SM sm = SM(); + assert(sm.length() == 0); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + assert(sm.length() == 3); + } +} diff --git a/test/re/re.submatch/re.submatch.members/operator_string.pass.cpp b/test/re/re.submatch/re.submatch.members/operator_string.pass.cpp new file mode 100644 index 00000000..a41ba108 --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/operator_string.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// operator string_type() const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM::string_type str = sm; + assert(str.empty()); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + str = sm; + assert(str == std::string("123")); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM::string_type str = sm; + assert(str.empty()); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + str = sm; + assert(str == std::wstring(L"123")); + } +} diff --git a/test/re/re.submatch/re.submatch.members/str.pass.cpp b/test/re/re.submatch/re.submatch.members/str.pass.cpp new file mode 100644 index 00000000..ffa7cfbd --- /dev/null +++ b/test/re/re.submatch/re.submatch.members/str.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// string_type str() const; + +#include +#include + +int main() +{ + { + typedef char CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM::string_type str = sm.str(); + assert(str.empty()); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + str = sm.str(); + assert(str == std::string("123")); + } + { + typedef wchar_t CharT; + typedef std::sub_match SM; + SM sm = SM(); + SM::string_type str = sm.str(); + assert(str.empty()); + const CharT s[] = {'1', '2', '3', 0}; + sm.first = s; + sm.second = s + 3; + sm.matched = true; + str = sm.str(); + assert(str == std::wstring(L"123")); + } +} diff --git a/test/re/re.submatch/re.submatch.op/compare.pass.cpp b/test/re/re.submatch/re.submatch.op/compare.pass.cpp new file mode 100644 index 00000000..404a6c08 --- /dev/null +++ b/test/re/re.submatch/re.submatch.op/compare.pass.cpp @@ -0,0 +1,283 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// template +// bool +// operator==(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator!=(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator<(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator<=(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator>=(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator>(const sub_match& lhs, const sub_match& rhs); +// +// template +// bool +// operator==(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator!=(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator>(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool operator>=(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<=(const basic_string::value_type, ST, SA>& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator==(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool +// operator!=(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool +// operator<(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool operator>(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool +// operator>=(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool +// operator<=(const sub_match& lhs, +// const basic_string::value_type, ST, SA>& rhs); +// +// template +// bool +// operator==(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator!=(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator>(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator>=(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<=(typename iterator_traits::value_type const* lhs, +// const sub_match& rhs); +// +// template +// bool +// operator==(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator!=(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator<(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator>(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator>=(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator<=(const sub_match& lhs, +// typename iterator_traits::value_type const* rhs); +// +// template +// bool +// operator==(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator!=(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator>(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator>=(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator<=(typename iterator_traits::value_type const& lhs, +// const sub_match& rhs); +// +// template +// bool +// operator==(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); +// +// template +// bool +// operator!=(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); +// +// template +// bool +// operator<(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); +// +// template +// bool +// operator>(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); +// +// template +// bool +// operator>=(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); +// +// template +// bool +// operator<=(const sub_match& lhs, +// typename iterator_traits::value_type const& rhs); + +#include +#include + +template +void +test(const std::basic_string& x, const std::basic_string& y) +{ + typedef std::basic_string string; + typedef std::sub_match sub_match; + sub_match sm1; + sm1.first = x.begin(); + sm1.second = x.end(); + sm1.matched = true; + sub_match sm2; + sm2.first = y.begin(); + sm2.second = y.end(); + sm2.matched = true; + assert((sm1 == sm2) == (x == y)); + assert((sm1 != sm2) == (x != y)); + assert((sm1 < sm2) == (x < y)); + assert((sm1 > sm2) == (x > y)); + assert((sm1 <= sm2) == (x <= y)); + assert((sm1 >= sm2) == (x >= y)); + assert((x == sm2) == (x == y)); + assert((x != sm2) == (x != y)); + assert((x < sm2) == (x < y)); + assert((x > sm2) == (x > y)); + assert((x <= sm2) == (x <= y)); + assert((x >= sm2) == (x >= y)); + assert((sm1 == y) == (x == y)); + assert((sm1 != y) == (x != y)); + assert((sm1 < y) == (x < y)); + assert((sm1 > y) == (x > y)); + assert((sm1 <= y) == (x <= y)); + assert((sm1 >= y) == (x >= y)); + assert((x.c_str() == sm2) == (x == y)); + assert((x.c_str() != sm2) == (x != y)); + assert((x.c_str() < sm2) == (x < y)); + assert((x.c_str() > sm2) == (x > y)); + assert((x.c_str() <= sm2) == (x <= y)); + assert((x.c_str() >= sm2) == (x >= y)); + assert((sm1 == y.c_str()) == (x == y)); + assert((sm1 != y.c_str()) == (x != y)); + assert((sm1 < y.c_str()) == (x < y)); + assert((sm1 > y.c_str()) == (x > y)); + assert((sm1 <= y.c_str()) == (x <= y)); + assert((sm1 >= y.c_str()) == (x >= y)); + assert((x[0] == sm2) == (string(1, x[0]) == y)); + assert((x[0] != sm2) == (string(1, x[0]) != y)); + assert((x[0] < sm2) == (string(1, x[0]) < y)); + assert((x[0] > sm2) == (string(1, x[0]) > y)); + assert((x[0] <= sm2) == (string(1, x[0]) <= y)); + assert((x[0] >= sm2) == (string(1, x[0]) >= y)); + assert((sm1 == y[0]) == (x == string(1, y[0]))); + assert((sm1 != y[0]) == (x != string(1, y[0]))); + assert((sm1 < y[0]) == (x < string(1, y[0]))); + assert((sm1 > y[0]) == (x > string(1, y[0]))); + assert((sm1 <= y[0]) == (x <= string(1, y[0]))); + assert((sm1 >= y[0]) == (x >= string(1, y[0]))); +} + +int main() +{ + test(std::string("123"), std::string("123")); + test(std::string("1234"), std::string("123")); + test(std::wstring(L"123"), std::wstring(L"123")); + test(std::wstring(L"1234"), std::wstring(L"123")); +} diff --git a/test/re/re.submatch/re.submatch.op/stream.pass.cpp b/test/re/re.submatch/re.submatch.op/stream.pass.cpp new file mode 100644 index 00000000..5f4d705a --- /dev/null +++ b/test/re/re.submatch/re.submatch.op/stream.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class sub_match; + +// template +// basic_ostream& +// operator<<(basic_ostream& os, const sub_match& m); + +#include +#include +#include + +template +void +test(const std::basic_string& s) +{ + typedef std::basic_string string; + typedef std::sub_match SM; + typedef std::basic_ostringstream ostringstream; + SM sm; + sm.first = s.begin(); + sm.second = s.end(); + sm.matched = true; + ostringstream os; + os << sm; + assert(os.str() == s); +} + +int main() +{ + test(std::string("123")); + test(std::wstring(L"123")); +} diff --git a/test/re/re.submatch/types.pass.cpp b/test/re/re.submatch/types.pass.cpp new file mode 100644 index 00000000..358380ba --- /dev/null +++ b/test/re/re.submatch/types.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// class sub_match +// : public pair +// { +// public: +// typedef BidirectionalIterator iterator; +// typedef typename iterator_traits::value_type value_type; +// typedef typename iterator_traits::difference_type difference_type; +// typedef basic_string string_type; +// +// bool matched; +// ... +// }; + +#include +#include +#include + +int main() +{ + { + typedef std::sub_match SM; + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_convertible*>::value), ""); + + SM sm; + sm.first = nullptr; + sm.second = nullptr; + sm.matched = false; + } + { + typedef std::sub_match SM; + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); + static_assert((std::is_convertible*>::value), ""); + + SM sm; + sm.first = nullptr; + sm.second = nullptr; + sm.matched = false; + } + { + static_assert((std::is_same >::value), ""); + static_assert((std::is_same >::value), ""); + static_assert((std::is_same >::value), ""); + static_assert((std::is_same >::value), ""); + } +}