[re.regiter]
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@111178 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/regex b/include/regex
index 032b4d0..d312468 100644
--- a/include/regex
+++ b/include/regex
@@ -830,7 +830,8 @@
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 @@
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 @@
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 @@
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 @@
__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 @@
: __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 @@
__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 @@
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 @@
{
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 @@
{
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 @@
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 @@
{
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 @@
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 0000000..46f4a3e
--- /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 0000000..33b0f7e
--- /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 0000000..aa4e662
--- /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 0000000..8ea1c58
--- /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 0000000..66b3f17
--- /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 0000000..b89e29a
--- /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