From a712c724998564430e8b588e1c037010e19017c3 Mon Sep 17 00:00:00 2001 From: Howard Hinnant <hhinnant@apple.com> Date: Mon, 16 Aug 2010 20:21:16 +0000 Subject: [PATCH] [re.regiter] git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@111178 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/regex | 187 +++++++++++++++++- .../re.regiter.cnstr/cnstr.pass.cpp | 44 +++++ .../re.regiter.cnstr/default.pass.cpp | 32 +++ .../re.regiter.comp/tested_elsewhere.pass.cpp | 19 ++ .../re.regiter.deref/deref.pass.cpp | 42 ++++ .../re.regiter/re.regiter.incr/post.pass.cpp | 42 ++++ test/re/re.iter/re.regiter/types.pass.cpp | 45 +++++ 7 files changed, 401 insertions(+), 10 deletions(-) create mode 100644 test/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp create mode 100644 test/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp create mode 100644 test/re/re.iter/re.regiter/re.regiter.comp/tested_elsewhere.pass.cpp create mode 100644 test/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp create mode 100644 test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp create mode 100644 test/re/re.iter/re.regiter/types.pass.cpp diff --git a/include/regex b/include/regex index 032b4d0f..d312468f 100644 --- a/include/regex +++ b/include/regex @@ -830,7 +830,8 @@ enum match_flag_type format_default = 0, format_sed = 1 << 8, format_no_copy = 1 << 9, - format_first_only = 1 << 10 + format_first_only = 1 << 10, + __no_update_pos = 1 << 11 }; inline @@ -5171,6 +5172,7 @@ private: value_type __prefix_; value_type __suffix_; public: + _BidirectionalIterator __position_start_; typedef const value_type& const_reference; typedef const_reference reference; typedef typename __container_type::const_iterator const_iterator; @@ -5199,7 +5201,7 @@ public: difference_type length(size_type __sub = 0) const {return (*this)[__sub].length();} difference_type position(size_type __sub = 0) const - {return _STD::distance(__prefix_.first, (*this)[__sub].first);} + {return _STD::distance(__position_start_, (*this)[__sub].first);} string_type str(size_type __sub = 0) const {return (*this)[__sub].str();} const_reference operator[](size_type __n) const @@ -5252,7 +5254,7 @@ public: template <class _B, class _A> void __assign(_BidirectionalIterator __f, _BidirectionalIterator __l, - const match_results<_B, _A>& __m) + const match_results<_B, _A>& __m, bool __no_update_pos) { _B __mf = __m.prefix().first; __matches_.resize(__m.size()); @@ -5271,11 +5273,14 @@ public: __suffix_.first = next(__f, _STD::distance(__mf, __m.suffix().first)); __suffix_.second = next(__f, _STD::distance(__mf, __m.suffix().second)); __suffix_.matched = __m.suffix().matched; + if (!__no_update_pos) + __position_start_ = __prefix_.first; } private: void __init(unsigned __s, - _BidirectionalIterator __f, _BidirectionalIterator __l); + _BidirectionalIterator __f, _BidirectionalIterator __l, + bool __no_update_pos = false); template <class, class> friend class basic_regex; @@ -5299,14 +5304,16 @@ match_results<_BidirectionalIterator, _Allocator>::match_results( : __matches_(__a), __unmatched_(), __prefix_(), - __suffix_() + __suffix_(), + __position_start_() { } template <class _BidirectionalIterator, class _Allocator> void match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s, - _BidirectionalIterator __f, _BidirectionalIterator __l) + _BidirectionalIterator __f, _BidirectionalIterator __l, + bool __no_update_pos) { __unmatched_.first = __l; __unmatched_.second = __l; @@ -5316,6 +5323,8 @@ match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s, __prefix_.second = __f; __prefix_.matched = false; __suffix_ = __unmatched_; + if (!__no_update_pos) + __position_start_ = __prefix_.first; } template <class _BidirectionalIterator, class _Allocator> @@ -5420,6 +5429,7 @@ match_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m) swap(__unmatched_, __m.__unmatched_); swap(__prefix_, __m.__prefix_); swap(__suffix_, __m.__suffix_); + swap(__position_start_, __m.__position_start_); } typedef match_results<const char*> cmatch; @@ -5434,7 +5444,8 @@ operator==(const match_results<_BidirectionalIterator, _Allocator>& __x, { return __x.__matches_ == __y.__matches_ && __x.__prefix_ == __y.__prefix_ && - __x.__suffix_ == __y.__suffix_; + __x.__suffix_ == __y.__suffix_ && + __x.__position_start_ == __y.__position_start_; } template <class _BidirectionalIterator, class _Allocator> @@ -5708,7 +5719,8 @@ basic_regex<_CharT, _Traits>::__search( { if (__left_anchor_) __flags |= regex_constants::match_continuous; - __m.__init(1 + mark_count(), __first, __last); + __m.__init(1 + mark_count(), __first, __last, + __flags & regex_constants::__no_update_pos); if (__match_at_start(__first, __last, __m, __flags)) { __m.__prefix_.second = __m[0].first; @@ -5749,7 +5761,7 @@ regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last, basic_string<_CharT> __s(__first, __last); match_results<const _CharT*> __mc; bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags); - __m.__assign(__first, __last, __mc); + __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos); return __r; } @@ -5828,7 +5840,7 @@ regex_search(const basic_string<_CharT, _ST, _SA>& __s, { match_results<const _CharT*> __mc; bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags); - __m.__assign(__s.begin(), __s.end(), __mc); + __m.__assign(__s.begin(), __s.end(), __mc, __flags & regex_constants::__no_update_pos); return __r; } @@ -5903,6 +5915,161 @@ regex_match(const basic_string<_CharT, _ST, _SA>& __s, return _STD::regex_match(__s.begin(), __s.end(), __e, __flags); } +// regex_iterator + +template <class _BidirectionalIterator, + class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type, + class _Traits = regex_traits<_CharT> > +class regex_iterator +{ +public: + typedef basic_regex<_CharT, _Traits> regex_type; + typedef match_results<_BidirectionalIterator> value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + +private: + _BidirectionalIterator __begin_; + _BidirectionalIterator __end_; + const regex_type* __pregex_; + regex_constants::match_flag_type __flags_; + value_type __match_; + +public: + regex_iterator(); + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, + regex_constants::match_flag_type __m = regex_constants::match_default); + + bool operator==(const regex_iterator& __x) const; + bool operator!=(const regex_iterator& __x) const {return !(*this == __x);} + + reference operator*() const {return __match_;} + pointer operator->() const {return &__match_;} + + regex_iterator& operator++(); + regex_iterator operator++(int) + { + regex_iterator __t(*this); + ++(*this); + return __t; + } +}; + +template <class _BidirectionalIterator, class _CharT, class _Traits> +regex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator() + : __begin_(), __end_(), __pregex_(nullptr), __flags_(), __match_() +{ +} + +template <class _BidirectionalIterator, class _CharT, class _Traits> +regex_iterator<_BidirectionalIterator, _CharT, _Traits>:: + regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, regex_constants::match_flag_type __m) + : __begin_(__a), + __end_(__b), + __pregex_(&__re), + __flags_(__m) +{ + _STD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_); +} + +template <class _BidirectionalIterator, class _CharT, class _Traits> +bool +regex_iterator<_BidirectionalIterator, _CharT, _Traits>:: + operator==(const regex_iterator& __x) const +{ + if (__match_.empty() && __x.__match_.empty()) + return true; + if (__match_.empty() || __x.__match_.empty()) + return false; + return __begin_ == __x.__begin_ && + __end_ == __x.__end_ && + __pregex_ == __x.__pregex_ && + __flags_ == __x.__flags_ && + __match_[0] == __x.__match_[0]; +} + +template <class _BidirectionalIterator, class _CharT, class _Traits> +regex_iterator<_BidirectionalIterator, _CharT, _Traits>& +regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() +{ + __flags_ |= regex_constants::__no_update_pos; + _BidirectionalIterator __start = __match_[0].second; + if (__match_.length() == 0) + { + if (__start == __end_) + { + __match_ = value_type(); + return *this; + } + else if (_STD::regex_search(__start, __end_, __match_, *__pregex_, + __flags_ | regex_constants::match_not_null | + regex_constants::match_continuous)) + return *this; + else + ++__start; + } + __flags_ |= regex_constants::match_prev_avail; + if (!_STD::regex_search(__start, __end_, __match_, *__pregex_, __flags_)) + __match_ = value_type(); + return *this; +} + +typedef regex_iterator<const char*> cregex_iterator; +typedef regex_iterator<const wchar_t*> wcregex_iterator; +typedef regex_iterator<string::const_iterator> sregex_iterator; +typedef regex_iterator<wstring::const_iterator> wsregex_iterator; + +// regex_token_iterator + +template <class _BidirectionalIterator, + class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type, + class _Traits = regex_traits<_CharT> > +class regex_token_iterator +{ +public: + typedef basic_regex<_CharT, _Traits> regex_type; + typedef sub_match<_BidirectionalIterator> value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef forward_iterator_tag iterator_category; + + regex_token_iterator(); + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, int __submatch = 0, + regex_constants::match_flag_type __m = regex_constants::match_default); + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, const vector<int>& __submatches, + regex_constants::match_flag_type __m = regex_constants::match_default); + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, initializer_list<int> __submatches, + regex_constants::match_flag_type __m = regex_constants::match_default); + template <size_t _N> + regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, + const regex_type& __re, const int (&__submatches)[_N], + regex_constants::match_flag_type __m = regex_constants::match_default); + regex_token_iterator(const regex_token_iterator&); + regex_token_iterator& operator=(const regex_token_iterator&); + + bool operator==(const regex_token_iterator&) const; + bool operator!=(const regex_token_iterator&) const; + + const value_type& operator*() const; + const value_type* operator->() const; + + regex_token_iterator& operator++(); + regex_token_iterator operator++(int); +}; + +typedef regex_token_iterator<const char*> cregex_token_iterator; +typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator; +typedef regex_token_iterator<string::const_iterator> sregex_token_iterator; +typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_REGEX diff --git a/test/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp b/test/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp new file mode 100644 index 00000000..46f4a3eb --- /dev/null +++ b/test/re/re.iter/re.regiter/re.regiter.cnstr/cnstr.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// class regex_iterator<BidirectionalIterator, charT, traits> + +// regex_iterator(BidirectionalIterator a, BidirectionalIterator b, +// const regex_type& re, +// regex_constants::match_flag_type m = regex_constants::match_default); + +#include <regex> +#include <cassert> + +int main() +{ + { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "555-1234, 555-2345, 555-3456"; + std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers); + assert(i != std::cregex_iterator()); + assert(i->size() == 1); + assert(i->position() == 0); + assert(i->str() == "555-1234"); + ++i; + assert(i != std::cregex_iterator()); + assert(i->size() == 1); + assert(i->position() == 10); + assert(i->str() == "555-2345"); + ++i; + assert(i != std::cregex_iterator()); + assert(i->size() == 1); + assert(i->position() == 20); + assert(i->str() == "555-3456"); + ++i; + assert(i == std::cregex_iterator()); + } +} \ No newline at end of file diff --git a/test/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp b/test/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp new file mode 100644 index 00000000..33b0f7e5 --- /dev/null +++ b/test/re/re.iter/re.regiter/re.regiter.cnstr/default.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// class regex_iterator<BidirectionalIterator, charT, traits> + +// regex_iterator(); + +#include <regex> +#include <cassert> + +template <class CharT> +void +test() +{ + typedef std::regex_iterator<const CharT*> I; + I i1; + assert(i1 == I()); +} + +int main() +{ + test<char>(); + test<wchar_t>(); +} \ No newline at end of file diff --git a/test/re/re.iter/re.regiter/re.regiter.comp/tested_elsewhere.pass.cpp b/test/re/re.iter/re.regiter/re.regiter.comp/tested_elsewhere.pass.cpp new file mode 100644 index 00000000..aa4e662d --- /dev/null +++ b/test/re/re.iter/re.regiter/re.regiter.comp/tested_elsewhere.pass.cpp @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// class regex_iterator<BidirectionalIterator, charT, traits> + +// bool operator==(const regex_iterator& right) const; +// bool operator!=(const regex_iterator& right) const; + +int main() +{ +} \ No newline at end of file diff --git a/test/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp b/test/re/re.iter/re.regiter/re.regiter.deref/deref.pass.cpp new file mode 100644 index 00000000..8ea1c587 --- /dev/null +++ b/test/re/re.iter/re.regiter/re.regiter.deref/deref.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. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// class regex_iterator<BidirectionalIterator, charT, traits> + +// const value_type& operator*() const; + +#include <regex> +#include <cassert> + +int main() +{ + { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "555-1234, 555-2345, 555-3456"; + std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers); + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 0); + assert((*i).str() == "555-1234"); + ++i; + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 10); + assert((*i).str() == "555-2345"); + ++i; + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 20); + assert((*i).str() == "555-3456"); + ++i; + assert(i == std::cregex_iterator()); + } +} \ No newline at end of file diff --git a/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp b/test/re/re.iter/re.regiter/re.regiter.incr/post.pass.cpp new file mode 100644 index 00000000..66b3f17b --- /dev/null +++ b/test/re/re.iter/re.regiter/re.regiter.incr/post.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. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// class regex_iterator<BidirectionalIterator, charT, traits> + +// regex_iterator operator++(int); + +#include <regex> +#include <cassert> + +int main() +{ + { + std::regex phone_numbers("\\d{3}-\\d{4}"); + const char phone_book[] = "555-1234, 555-2345, 555-3456"; + std::cregex_iterator i(std::begin(phone_book), std::end(phone_book), phone_numbers); + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 0); + assert((*i).str() == "555-1234"); + i++; + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 10); + assert((*i).str() == "555-2345"); + i++; + assert(i != std::cregex_iterator()); + assert((*i).size() == 1); + assert((*i).position() == 20); + assert((*i).str() == "555-3456"); + i++; + assert(i == std::cregex_iterator()); + } +} \ No newline at end of file diff --git a/test/re/re.iter/re.regiter/types.pass.cpp b/test/re/re.iter/re.regiter/types.pass.cpp new file mode 100644 index 00000000..b89e29a9 --- /dev/null +++ b/test/re/re.iter/re.regiter/types.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <regex> + +// template <class BidirectionalIterator, +// class charT = typename iterator_traits< BidirectionalIterator>::value_type, +// class traits = regex_traits<charT>> +// class regex_iterator +// { +// public: +// typedef basic_regex<charT, traits> regex_type; +// typedef match_results<BidirectionalIterator> value_type; +// typedef ptrdiff_t difference_type; +// typedef const value_type* pointer; +// typedef const value_type& reference; +// typedef forward_iterator_tag iterator_category; + +#include <regex> +#include <type_traits> + +template <class CharT> +void +test() +{ + typedef std::regex_iterator<const CharT*> I; + static_assert((std::is_same<typename I::regex_type, std::basic_regex<CharT> >::value), ""); + static_assert((std::is_same<typename I::value_type, std::match_results<const CharT*> >::value), ""); + static_assert((std::is_same<typename I::difference_type, std::ptrdiff_t>::value), ""); + static_assert((std::is_same<typename I::pointer, const std::match_results<const CharT*>*>::value), ""); + static_assert((std::is_same<typename I::reference, const std::match_results<const CharT*>&>::value), ""); + static_assert((std::is_same<typename I::iterator_category, std::forward_iterator_tag>::value), ""); +} + +int main() +{ + test<char>(); + test<wchar_t>(); +} \ No newline at end of file