diff --git a/include/regex b/include/regex index 30def6b2f..68096b0c0 100644 --- a/include/regex +++ b/include/regex @@ -1558,6 +1558,50 @@ __loop<_CharT>::__exec_split(bool __second, __state& __s) const __s.__node_ = this->second(); } +// __alternate + +template +class __alternate + : public __owns_two_states<_CharT> +{ + typedef __owns_two_states<_CharT> base; + +public: + typedef _STD::__state<_CharT> __state; + + explicit __alternate(__owns_one_state<_CharT>* __s1, + __owns_one_state<_CharT>* __s2) + : base(__s1, __s2) {} + + virtual void __exec(__state& __s) const; + virtual void __exec_split(bool __second, __state& __s) const; + + virtual string speak() const + { + ostringstream os; + os << "__alternate"; + return os.str(); + } +}; + +template +void +__alternate<_CharT>::__exec(__state& __s) const +{ + __s.__do_ = __state::__split; +} + +template +void +__alternate<_CharT>::__exec_split(bool __second, __state& __s) const +{ + __s.__do_ = __state::__accept_but_not_consume; + if (!__second) + __s.__node_ = this->first(); + else + __s.__node_ = this->second(); +} + // __begin_marked_subexpression template @@ -2413,7 +2457,9 @@ private: unsigned __mexp_begin, unsigned __mexp_end); template _ForwardIterator - __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last); + __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, unsigned __mexp_end); template _ForwardIterator __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last); @@ -2466,14 +2512,14 @@ private: unsigned __mexp_begin = 0, unsigned __mexp_end = 0) {__push_loop(__min, numeric_limits::max(), __s, __mexp_begin, __mexp_end);} - void __push_exact_repeat(int __count) {} void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s, size_t __mexp_begin = 0, size_t __mexp_end = 0, bool __greedy = true); __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate); void __push_char(value_type __c); void __push_back_ref(int __i); - void __push_alternation() {} + void __push_alternation(__owns_one_state<_CharT>* __sa, + __owns_one_state<_CharT>* __sb); void __push_begin_marked_subexpression(); void __push_end_marked_subexpression(unsigned); @@ -2629,18 +2675,19 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last) { - while (true) + __owns_one_state<_CharT>* __sa = __end_; + _ForwardIterator __temp = __parse_ERE_branch(__first, __last); + if (__temp == __first) + throw regex_error(regex_constants::error_temp); + __first = __temp; + while (__first != __last && *__first == '|') { - _ForwardIterator __temp = __parse_ERE_branch(__first, __last); + __owns_one_state<_CharT>* __sb = __end_; + __temp = __parse_ERE_branch(++__first, __last); if (__temp == __first) throw regex_error(regex_constants::error_temp); + __push_alternation(__sa, __sb); __first = __temp; - if (__first == __last) - break; - if (*__first != '|') - throw regex_error(regex_constants::error_temp); - __push_alternation(); - ++__first; } return __first; } @@ -2668,6 +2715,8 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last) { + __owns_one_state<_CharT>* __e = __end_; + unsigned __mexp_begin = __marked_count_; _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last); if (__temp == __first && __temp != __last) { @@ -2695,7 +2744,8 @@ basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, } } if (__temp != __first) - __temp = __parse_ERE_dupl_symbol(__temp, __last); + __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin+1, + __marked_count_+1); __first = __temp; return __first; } @@ -3080,7 +3130,7 @@ basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first, if (__temp == __first) throw regex_error(regex_constants::error_brace); if (__max == -1) - __push_greedy_inf_repeat(__min, __s, __mexp_end, __mexp_end); + __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end); else { if (__max < __min) @@ -3100,28 +3150,31 @@ template template _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, - _ForwardIterator __last) + _ForwardIterator __last, + __owns_one_state<_CharT>* __s, + unsigned __mexp_begin, + unsigned __mexp_end) { if (__first != __last) { switch (*__first) { case '*': - __push_greedy_inf_repeat(0, nullptr); + __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end); ++__first; break; case '+': - __push_greedy_inf_repeat(1, nullptr); + __push_greedy_inf_repeat(1, __s, __mexp_begin, __mexp_end); ++__first; break; case '?': - __push_loop(0, 1, nullptr); + __push_loop(0, 1, __s, __mexp_begin, __mexp_end); ++__first; break; case '{': { int __min; - _ForwardIterator __temp = __parse_DUP_COUNT(__first, __last, __min); + _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min); if (__temp == __first) throw regex_error(regex_constants::error_badbrace); __first = __temp; @@ -3130,7 +3183,7 @@ basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, switch (*__first) { case '}': - __push_exact_repeat(__min); + __push_loop(__min, __min, __s, __mexp_begin, __mexp_end); ++__first; break; case ',': @@ -3138,12 +3191,12 @@ basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, throw regex_error(regex_constants::error_badbrace); if (*__first == '}') { - __push_greedy_inf_repeat(__min, nullptr); + __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end); ++__first; } else { - int __max; + int __max = -1; __temp = __parse_DUP_COUNT(__first, __last, __max); if (__temp == __first) throw regex_error(regex_constants::error_brace); @@ -3153,8 +3206,9 @@ basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first, ++__first; if (__max < __min) throw regex_error(regex_constants::error_badbrace); - __push_loop(__min, __max, nullptr); + __push_loop(__min, __max, __s, __mexp_begin, __mexp_end); } + break; default: throw regex_error(regex_constants::error_badbrace); } @@ -3499,6 +3553,21 @@ basic_regex<_CharT, _Traits>::__push_back_ref(int __i) __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } +template +void +basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa, + __owns_one_state<_CharT>* __ea) +{ + __sa->first() = new __alternate<_CharT>( + static_cast<__owns_one_state<_CharT>*>(__sa->first()), + static_cast<__owns_one_state<_CharT>*>(__ea->first())); + __ea->first() = nullptr; + __ea->first() = new __empty_state<_CharT>(__end_->first()); + __end_->first() = nullptr; + __end_->first() = new __empty_non_own_state<_CharT>(__ea->first()); + __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first()); +} + template __bracket_expression<_CharT, _Traits>* basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate) diff --git a/test/re/iterators.h b/test/re/iterators.h new file mode 100644 index 000000000..85332ac72 --- /dev/null +++ b/test/re/iterators.h @@ -0,0 +1,251 @@ +#ifndef ITERATORS_H +#define ITERATORS_H + +#include + +template +class input_iterator +{ + It it_; + + template friend class input_iterator; +public: + typedef std::input_iterator_tag iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef It pointer; + typedef typename std::iterator_traits::reference reference; + + It base() const {return it_;} + + input_iterator() : it_() {} + explicit input_iterator(It it) : it_(it) {} + template + input_iterator(const input_iterator& u) :it_(u.it_) {} + + reference operator*() const {return *it_;} + pointer operator->() const {return it_;} + + input_iterator& operator++() {++it_; return *this;} + input_iterator operator++(int) + {input_iterator tmp(*this); ++(*this); return tmp;} + + friend bool operator==(const input_iterator& x, const input_iterator& y) + {return x.it_ == y.it_;} + friend bool operator!=(const input_iterator& x, const input_iterator& y) + {return !(x == y);} +}; + +template +inline +bool +operator==(const input_iterator& x, const input_iterator& y) +{ + return x.base() == y.base(); +} + +template +inline +bool +operator!=(const input_iterator& x, const input_iterator& y) +{ + return !(x == y); +} + +template +class forward_iterator +{ + It it_; + + template friend class forward_iterator; +public: + typedef std::forward_iterator_tag iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef It pointer; + typedef typename std::iterator_traits::reference reference; + + It base() const {return it_;} + + forward_iterator() : it_() {} + explicit forward_iterator(It it) : it_(it) {} + template + forward_iterator(const forward_iterator& u) :it_(u.it_) {} + + reference operator*() const {return *it_;} + pointer operator->() const {return it_;} + + forward_iterator& operator++() {++it_; return *this;} + forward_iterator operator++(int) + {forward_iterator tmp(*this); ++(*this); return tmp;} + + friend bool operator==(const forward_iterator& x, const forward_iterator& y) + {return x.it_ == y.it_;} + friend bool operator!=(const forward_iterator& x, const forward_iterator& y) + {return !(x == y);} +}; + +template +inline +bool +operator==(const forward_iterator& x, const forward_iterator& y) +{ + return x.base() == y.base(); +} + +template +inline +bool +operator!=(const forward_iterator& x, const forward_iterator& y) +{ + return !(x == y); +} + +template +class bidirectional_iterator +{ + It it_; + + template friend class bidirectional_iterator; +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef It pointer; + typedef typename std::iterator_traits::reference reference; + + It base() const {return it_;} + + bidirectional_iterator() : it_() {} + explicit bidirectional_iterator(It it) : it_(it) {} + template + bidirectional_iterator(const bidirectional_iterator& u) :it_(u.it_) {} + + reference operator*() const {return *it_;} + pointer operator->() const {return it_;} + + bidirectional_iterator& operator++() {++it_; return *this;} + bidirectional_iterator operator++(int) + {bidirectional_iterator tmp(*this); ++(*this); return tmp;} + + bidirectional_iterator& operator--() {--it_; return *this;} + bidirectional_iterator operator--(int) + {bidirectional_iterator tmp(*this); --(*this); return tmp;} +}; + +template +inline +bool +operator==(const bidirectional_iterator& x, const bidirectional_iterator& y) +{ + return x.base() == y.base(); +} + +template +inline +bool +operator!=(const bidirectional_iterator& x, const bidirectional_iterator& y) +{ + return !(x == y); +} + +template +class random_access_iterator +{ + It it_; + + template friend class random_access_iterator; +public: + typedef std::random_access_iterator_tag iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef It pointer; + typedef typename std::iterator_traits::reference reference; + + It base() const {return it_;} + + random_access_iterator() : it_() {} + explicit random_access_iterator(It it) : it_(it) {} + template + random_access_iterator(const random_access_iterator& u) :it_(u.it_) {} + + reference operator*() const {return *it_;} + pointer operator->() const {return it_;} + + random_access_iterator& operator++() {++it_; return *this;} + random_access_iterator operator++(int) + {random_access_iterator tmp(*this); ++(*this); return tmp;} + + random_access_iterator& operator--() {--it_; return *this;} + random_access_iterator operator--(int) + {random_access_iterator tmp(*this); --(*this); return tmp;} + + random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;} + random_access_iterator operator+(difference_type n) const + {random_access_iterator tmp(*this); tmp += n; return tmp;} + friend random_access_iterator operator+(difference_type n, random_access_iterator x) + {x += n; return x;} + random_access_iterator& operator-=(difference_type n) {return *this += -n;} + random_access_iterator operator-(difference_type n) const + {random_access_iterator tmp(*this); tmp -= n; return tmp;} + + reference operator[](difference_type n) const {return it_[n];} +}; + +template +inline +bool +operator==(const random_access_iterator& x, const random_access_iterator& y) +{ + return x.base() == y.base(); +} + +template +inline +bool +operator!=(const random_access_iterator& x, const random_access_iterator& y) +{ + return !(x == y); +} + +template +inline +bool +operator<(const random_access_iterator& x, const random_access_iterator& y) +{ + return x.base() < y.base(); +} + +template +inline +bool +operator<=(const random_access_iterator& x, const random_access_iterator& y) +{ + return !(y < x); +} + +template +inline +bool +operator>(const random_access_iterator& x, const random_access_iterator& y) +{ + return y < x; +} + +template +inline +bool +operator>=(const random_access_iterator& x, const random_access_iterator& y) +{ + return !(x < y); +} + +template +inline +typename std::iterator_traits::difference_type +operator-(const random_access_iterator& x, const random_access_iterator& y) +{ + return x.base() - y.base(); +} + +#endif diff --git a/test/re/re.alg/re.alg.search/extended.pass.cpp b/test/re/re.alg/re.alg.search/extended.pass.cpp new file mode 100644 index 000000000..b207f6eb4 --- /dev/null +++ b/test/re/re.alg/re.alg.search/extended.pass.cpp @@ -0,0 +1,445 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// regex_search(BidirectionalIterator first, BidirectionalIterator last, +// match_results& m, +// const basic_regex& e, +// regex_constants::match_flag_type flags = regex_constants::match_default); + +#include +#include + +#include "../../iterators.h" + +int main() +{ + { + std::cmatch m; + const char s[] = "a"; + assert(std::regex_search(s, m, std::regex("a", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.empty()); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+1); + assert(m.length(0) == 1); + assert(m.position(0) == 0); + assert(m.str(0) == "a"); + } + { + std::cmatch m; + const char s[] = "ab"; + assert(std::regex_search(s, m, std::regex("ab", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+2); + assert(m.length(0) == 2); + assert(m.position(0) == 0); + assert(m.str(0) == "ab"); + } + { + std::cmatch m; + const char s[] = "ab"; + assert(!std::regex_search(s, m, std::regex("ba", std::regex_constants::extended))); + assert(m.size() == 0); + assert(m.empty()); + } + { + std::cmatch m; + const char s[] = "aab"; + assert(std::regex_search(s, m, std::regex("ab", std::regex_constants::extended))); + assert(m.size() == 1); + assert(m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 2); + assert(m.position(0) == 1); + assert(m.str(0) == "ab"); + } + { + std::cmatch m; + const char s[] = "aab"; + assert(!std::regex_search(s, m, std::regex("ab", std::regex_constants::extended), + std::regex_constants::match_continuous)); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "abcd"; + assert(std::regex_search(s, m, std::regex("bc", std::regex_constants::extended))); + assert(m.size() == 1); + assert(m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+4); + assert(m.length(0) == 2); + assert(m.position(0) == 1); + assert(m.str(0) == "bc"); + } + { + std::cmatch m; + const char s[] = "abbc"; + assert(std::regex_search(s, m, std::regex("ab*c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+4); + assert(m.length(0) == 4); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "ababc"; + assert(std::regex_search(s, m, std::regex("(ab)*c", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+5); + assert(m.length(0) == 5); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 2); + assert(m.position(1) == 2); + assert(m.str(1) == "ab"); + } + { + std::cmatch m; + const char s[] = "abcdefghijk"; + assert(std::regex_search(s, m, std::regex("cd((e)fg)hi", + std::regex_constants::extended))); + assert(m.size() == 3); + assert(m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+std::regex_traits::length(s)); + assert(m.length(0) == 7); + assert(m.position(0) == 2); + assert(m.str(0) == "cdefghi"); + assert(m.length(1) == 3); + assert(m.position(1) == 4); + assert(m.str(1) == "efg"); + assert(m.length(2) == 1); + assert(m.position(2) == 4); + assert(m.str(2) == "e"); + } + { + std::cmatch m; + const char s[] = "abc"; + assert(std::regex_search(s, m, std::regex("^abc", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "abcd"; + assert(std::regex_search(s, m, std::regex("^abc", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+4); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == "abc"); + } + { + std::cmatch m; + const char s[] = "aabc"; + assert(!std::regex_search(s, m, std::regex("^abc", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "abc"; + assert(std::regex_search(s, m, std::regex("abc$", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "efabc"; + assert(std::regex_search(s, m, std::regex("abc$", std::regex_constants::extended))); + assert(m.size() == 1); + assert(m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+5); + assert(m.length(0) == 3); + assert(m.position(0) == 2); + assert(m.str(0) == s+2); + } + { + std::cmatch m; + const char s[] = "efabcg"; + assert(!std::regex_search(s, m, std::regex("abc$", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "abc"; + assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "acc"; + assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "acc"; + assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+3); + assert(m.length(0) == 3); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "abcdef"; + assert(std::regex_search(s, m, std::regex("(.*).*", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+6); + assert(m.length(0) == 6); + assert(m.position(0) == 0); + assert(m.str(0) == s); + assert(m.length(1) == 6); + assert(m.position(1) == 0); + assert(m.str(1) == s); + } + { + std::cmatch m; + const char s[] = "bc"; + assert(std::regex_search(s, m, std::regex("(a*)*", std::regex_constants::extended))); + assert(m.size() == 2); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == s+2); + assert(m.length(0) == 0); + assert(m.position(0) == 0); + assert(m.str(0) == ""); + assert(m.length(1) == 0); + assert(m.position(1) == 0); + assert(m.str(1) == ""); + } + { + std::cmatch m; + const char s[] = "abbc"; + assert(!std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "abbbc"; + assert(std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "abbbbc"; + assert(std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "abbbbbc"; + assert(std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "adefc"; + assert(!std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "abbbbbbc"; + assert(!std::regex_search(s, m, std::regex("ab{3,5}c", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "adec"; + assert(!std::regex_search(s, m, std::regex("a.{3,5}c", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "adefc"; + assert(std::regex_search(s, m, std::regex("a.{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "adefgc"; + assert(std::regex_search(s, m, std::regex("a.{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "adefghc"; + assert(std::regex_search(s, m, std::regex("a.{3,5}c", std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } + { + std::cmatch m; + const char s[] = "adefghic"; + assert(!std::regex_search(s, m, std::regex("a.{3,5}c", std::regex_constants::extended))); + assert(m.size() == 0); + } + { + std::cmatch m; + const char s[] = "tournament"; + assert(std::regex_search(s, m, std::regex("tour|to|tournament", + std::regex_constants::extended))); + assert(m.size() == 1); + assert(!m.prefix().matched); + assert(m.prefix().first == s); + assert(m.prefix().second == m[0].first); + assert(!m.suffix().matched); + assert(m.suffix().first == m[0].second); + assert(m.suffix().second == m[0].second); + assert(m.length(0) == sizeof(s)-1); + assert(m.position(0) == 0); + assert(m.str(0) == s); + } +} diff --git a/www/libcxx_by_chapter.pdf b/www/libcxx_by_chapter.pdf index a7ba82da5..69f1ee096 100644 Binary files a/www/libcxx_by_chapter.pdf and b/www/libcxx_by_chapter.pdf differ