Skip to content

Commit bb12765

Browse files
author
Hana Dusíková
committed
detecting reverse iterators
1 parent 2e8aaf2 commit bb12765

File tree

3 files changed

+96
-70
lines changed

3 files changed

+96
-70
lines changed

include/ctre/return_type.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ namespace ctre {
1818
constexpr bool is_random_accessible(const std::random_access_iterator_tag &) { return true; }
1919
constexpr bool is_random_accessible(...) { return false; }
2020

21+
template <typename T> constexpr bool is_reverse_iterator(const std::reverse_iterator<T> &) { return true; }
22+
constexpr bool is_reverse_iterator(...) { return false; }
2123

2224
struct not_matched_tag_t { };
2325

@@ -66,7 +68,9 @@ template <size_t Id, typename Name = void> struct captured_content {
6668
return _matched;
6769
}
6870

69-
constexpr CTRE_FORCE_INLINE const auto * data_unsafe() const noexcept {
71+
template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data_unsafe() const noexcept {
72+
static_assert(!is_reverse_iterator(It{}), "Iterator in your capture must not be reverse!");
73+
7074
#if __cpp_char8_t >= 201811
7175
if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
7276
return _begin.ptr;
@@ -78,10 +82,10 @@ template <size_t Id, typename Name = void> struct captured_content {
7882
#endif
7983
}
8084

81-
constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
82-
constexpr bool must_be_contiguous_iterator = is_random_accessible(typename std::iterator_traits<Iterator>::iterator_category{});
85+
template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
86+
constexpr bool must_be_contiguous_nonreverse_iterator = is_random_accessible(typename std::iterator_traits<It>::iterator_category{}) && !is_reverse_iterator(It{});
8387

84-
static_assert(must_be_contiguous_iterator, "To access result as a pointer you need to provide a random access iterator/range to regex.");
88+
static_assert(must_be_contiguous_nonreverse_iterator, "To access result as a pointer you need to provide a random access iterator/range to regex (which is not reverse iterator based).");
8589

8690
return data_unsafe();
8791
}
@@ -110,12 +114,14 @@ template <size_t Id, typename Name = void> struct captured_content {
110114
return result;
111115
}
112116
#endif
117+
118+
template <typename T> struct identify;
113119

114120
template <typename It = Iterator> constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
115121
// random access, because C++ (waving hands around)
116-
constexpr bool must_be_contiguous_iterator = is_random_accessible(typename std::iterator_traits<std::remove_const_t<It>>::iterator_category{});
122+
constexpr bool must_be_nonreverse_contiguous_iterator = is_random_accessible(typename std::iterator_traits<std::remove_const_t<It>>::iterator_category{}) && !is_reverse_iterator(It{});
117123

118-
static_assert(must_be_contiguous_iterator, "To convert capture into a basic_string_view you need to provide a pointer or a contiguous iterator/range to regex.");
124+
static_assert(must_be_nonreverse_contiguous_iterator, "To convert capture into a basic_string_view you need to provide a pointer or a contiguous non-reverse iterator/range to regex.");
119125

120126
return std::basic_string_view<char_type>(data_unsafe(), static_cast<size_t>(unit_size()));
121127
}
@@ -379,6 +385,12 @@ template <typename Iterator, typename... Captures> class regex_results {
379385
_captures.template select<Id>().set_end(pos).matched();
380386
return *this;
381387
}
388+
constexpr auto begin() const noexcept {
389+
return _captures.template select<0>().begin();
390+
}
391+
constexpr auto end() const noexcept {
392+
return _captures.template select<0>().end();
393+
}
382394
friend CTRE_FORCE_INLINE constexpr bool operator==(const regex_results & lhs, std::basic_string_view<char_type> rhs) noexcept {
383395
return bool(lhs) ? lhs.view() == rhs : false;
384396
}

0 commit comments

Comments
 (0)