Skip to content

Commit 62284f8

Browse files
author
Hana Dusíková
committed
for now my own filter
1 parent c967f68 commit 62284f8

File tree

4 files changed

+289
-33
lines changed

4 files changed

+289
-33
lines changed

include/ctre/range.hpp

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ template <typename> constexpr bool is_range = false;
99

1010
template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_range {
1111
BeginIterator _begin;
12-
const EndIterator _end;
12+
EndIterator _end;
1313

1414
constexpr CTRE_FORCE_INLINE regex_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
1515

@@ -25,7 +25,7 @@ template <typename... Ts> constexpr bool is_range<regex_range<Ts...>> = true;
2525

2626
template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_split_range {
2727
BeginIterator _begin;
28-
const EndIterator _end;
28+
EndIterator _end;
2929

3030
constexpr CTRE_FORCE_INLINE regex_split_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
3131

@@ -39,6 +39,97 @@ template <typename BeginIterator, typename EndIterator, typename RE, typename Re
3939

4040
template <typename... Ts> constexpr bool is_range<regex_split_range<Ts...>> = true;
4141

42+
template <typename First, typename Last, typename RE> struct multi_subject_range {
43+
static constexpr bool is_input = std::is_same_v<std::iterator_traits<First>::iterator_category, std::input_iterator_tag>;
44+
45+
struct end_iterator { };
46+
47+
struct iterator {
48+
using value_type = decltype(RE::exec(std::declval<typename std::iterator_traits<First>::value_type>()));
49+
using iterator_category = std::forward_iterator_tag;
50+
using pointer = void;
51+
using reference = const value_type &;
52+
using difference_type = ssize_t;
53+
54+
First first{};
55+
Last last{};
56+
value_type current_result{};
57+
58+
constexpr CTRE_FORCE_INLINE iterator(First f, Last l) noexcept: first{f}, last{l}, current_result{find_first()} {
59+
60+
}
61+
62+
constexpr CTRE_FORCE_INLINE value_type find_first() noexcept {
63+
while (first != last) {
64+
if (auto res = RE::exec(*first)) return res;
65+
else ++first;
66+
}
67+
return {};
68+
}
69+
70+
constexpr CTRE_FORCE_INLINE const value_type & operator*() const noexcept {
71+
return current_result;
72+
}
73+
74+
constexpr CTRE_FORCE_INLINE iterator & operator++() noexcept {
75+
++first;
76+
current_result = find_first();
77+
return *this;
78+
}
79+
constexpr CTRE_FORCE_INLINE iterator operator++(int) noexcept {
80+
auto previous = *this;
81+
this->operator++();
82+
return previous;
83+
}
84+
85+
friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, const iterator & right) noexcept {
86+
return left.first == right.first;
87+
}
88+
friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, const iterator & right) noexcept {
89+
return !(left.first == right.first);
90+
}
91+
friend constexpr CTRE_FORCE_INLINE bool operator<(const iterator & left, const iterator & right) noexcept {
92+
return left.first < right.first;
93+
}
94+
friend constexpr CTRE_FORCE_INLINE bool operator>(const iterator & left, const iterator & right) noexcept {
95+
return left.first > right.first;
96+
}
97+
friend constexpr CTRE_FORCE_INLINE bool operator<=(const iterator & left, const iterator & right) noexcept {
98+
return left.first <= right.first;
99+
}
100+
friend constexpr CTRE_FORCE_INLINE bool operator>=(const iterator & left, const iterator & right) noexcept {
101+
return left.first >= right.first;
102+
}
103+
friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, end_iterator) noexcept {
104+
return left.first == left.last;
105+
}
106+
friend constexpr CTRE_FORCE_INLINE bool operator==(end_iterator, const iterator & right) noexcept {
107+
return right.first == right.last;
108+
}
109+
friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, end_iterator) noexcept {
110+
return left.first != left.last;
111+
}
112+
friend constexpr CTRE_FORCE_INLINE bool operator!=(end_iterator, const iterator & right) noexcept {
113+
return right.first == right.last;
114+
}
115+
};
116+
117+
iterator everything;
118+
119+
constexpr CTRE_FORCE_INLINE multi_subject_range(First f, Last l) noexcept: everything{f,l} { }
120+
121+
constexpr CTRE_FORCE_INLINE auto begin() const noexcept {
122+
return everything;
123+
}
124+
constexpr CTRE_FORCE_INLINE auto end() const noexcept {
125+
return end_iterator{};
126+
}
127+
};
128+
129+
// this is not regex range!
130+
template <typename... Ts> constexpr bool is_range<multi_subject_range<Ts...>> = true;
131+
132+
42133
}
43134

44135
#if __cpp_lib_ranges >= 201911

include/ctre/wrapper.hpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include "return_type.hpp"
88
#include "range.hpp"
99
#include <string_view>
10-
#if __cpp_lib_ranges >= 201911
11-
#include <ranges>
12-
#endif
1310

1411
namespace ctre {
1512

@@ -150,6 +147,9 @@ template <typename RE, typename Method, typename Modifier> struct regular_expres
150147
template <typename ResultIterator, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec_with_result_iterator(IteratorBegin begin, IteratorEnd end) noexcept {
151148
return Method::template exec<Modifier, ResultIterator>(begin, end, RE{});
152149
}
150+
template <typename Range> constexpr CTRE_FORCE_INLINE static auto multi_exec(Range && range) noexcept {
151+
return multi_subject_range<decltype(range.begin()), decltype(range.end()), regular_expression>{range.begin(), range.end()};
152+
}
153153
constexpr CTRE_FORCE_INLINE static auto exec() noexcept {
154154
return Method::template exec();
155155
}
@@ -253,14 +253,9 @@ template <typename Range, typename RE, typename Modifier> constexpr auto operato
253253

254254
template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, iterator_method, Modifier> re) noexcept = delete;
255255

256-
// range filter style API support for tokenize/range/split operations
257-
#if __cpp_lib_ranges >= 201911
258256
template <typename Range, typename RE, typename Method, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, Method, Modifier> re) noexcept {
259-
return std::forward<Range>(range) | std::ranges::views::filter([](const decltype(*range.begin()) & item) -> bool{
260-
return regular_expression<RE, Method, Modifier>{}.exec(item);
261-
});
257+
return re.multi_exec(std::forward<Range>(range));
262258
}
263-
#endif
264259

265260
#if CTRE_CNTTP_COMPILER_CHECK
266261
#define CTRE_REGEX_INPUT_TYPE ctll::fixed_string

single-header/ctre-unicode.hpp

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4637,7 +4637,7 @@ template <typename> constexpr bool is_range = false;
46374637

46384638
template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_range {
46394639
BeginIterator _begin;
4640-
const EndIterator _end;
4640+
EndIterator _end;
46414641

46424642
constexpr CTRE_FORCE_INLINE regex_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
46434643

@@ -4653,7 +4653,7 @@ template <typename... Ts> constexpr bool is_range<regex_range<Ts...>> = true;
46534653

46544654
template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_split_range {
46554655
BeginIterator _begin;
4656-
const EndIterator _end;
4656+
EndIterator _end;
46574657

46584658
constexpr CTRE_FORCE_INLINE regex_split_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
46594659

@@ -4667,6 +4667,96 @@ template <typename BeginIterator, typename EndIterator, typename RE, typename Re
46674667

46684668
template <typename... Ts> constexpr bool is_range<regex_split_range<Ts...>> = true;
46694669

4670+
template <typename First, typename Last, typename RE> struct multi_subject_range {
4671+
static constexpr bool is_input = std::is_same_v<std::iterator_traits<First>::iterator_category, std::input_iterator_tag>;
4672+
4673+
struct end_iterator { };
4674+
4675+
struct iterator {
4676+
using value_type = decltype(RE::exec(std::declval<typename std::iterator_traits<First>::value_type>()));
4677+
using iterator_category = std::forward_iterator_tag;
4678+
using pointer = void;
4679+
using reference = const value_type &;
4680+
using difference_type = ssize_t;
4681+
4682+
First first{};
4683+
Last last{};
4684+
value_type current_result{};
4685+
4686+
constexpr CTRE_FORCE_INLINE iterator(First f, Last l) noexcept: first{f}, last{l}, current_result{find_first()} {
4687+
4688+
}
4689+
4690+
constexpr CTRE_FORCE_INLINE value_type find_first() noexcept {
4691+
while (first != last) {
4692+
if (auto res = RE::exec(*first)) return res;
4693+
else ++first;
4694+
}
4695+
return {};
4696+
}
4697+
4698+
constexpr CTRE_FORCE_INLINE const value_type & operator*() const noexcept {
4699+
return current_result;
4700+
}
4701+
4702+
constexpr CTRE_FORCE_INLINE iterator & operator++() noexcept {
4703+
++first;
4704+
current_result = find_first();
4705+
return *this;
4706+
}
4707+
constexpr CTRE_FORCE_INLINE iterator operator++(int) noexcept {
4708+
auto previous = *this;
4709+
this->operator++();
4710+
return previous;
4711+
}
4712+
4713+
friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, const iterator & right) noexcept {
4714+
return left.first == right.first;
4715+
}
4716+
friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, const iterator & right) noexcept {
4717+
return !(left.first == right.first);
4718+
}
4719+
friend constexpr CTRE_FORCE_INLINE bool operator<(const iterator & left, const iterator & right) noexcept {
4720+
return left.first < right.first;
4721+
}
4722+
friend constexpr CTRE_FORCE_INLINE bool operator>(const iterator & left, const iterator & right) noexcept {
4723+
return left.first > right.first;
4724+
}
4725+
friend constexpr CTRE_FORCE_INLINE bool operator<=(const iterator & left, const iterator & right) noexcept {
4726+
return left.first <= right.first;
4727+
}
4728+
friend constexpr CTRE_FORCE_INLINE bool operator>=(const iterator & left, const iterator & right) noexcept {
4729+
return left.first >= right.first;
4730+
}
4731+
friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, end_iterator) noexcept {
4732+
return left.first == left.last;
4733+
}
4734+
friend constexpr CTRE_FORCE_INLINE bool operator==(end_iterator, const iterator & right) noexcept {
4735+
return right.first == right.last;
4736+
}
4737+
friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, end_iterator) noexcept {
4738+
return left.first != left.last;
4739+
}
4740+
friend constexpr CTRE_FORCE_INLINE bool operator!=(end_iterator, const iterator & right) noexcept {
4741+
return right.first == right.last;
4742+
}
4743+
};
4744+
4745+
iterator everything;
4746+
4747+
constexpr CTRE_FORCE_INLINE multi_subject_range(First f, Last l) noexcept: everything{f,l} { }
4748+
4749+
constexpr CTRE_FORCE_INLINE auto begin() const noexcept {
4750+
return everything;
4751+
}
4752+
constexpr CTRE_FORCE_INLINE auto end() const noexcept {
4753+
return end_iterator{};
4754+
}
4755+
};
4756+
4757+
// this is not regex range!
4758+
template <typename... Ts> constexpr bool is_range<multi_subject_range<Ts...>> = true;
4759+
46704760
}
46714761

46724762
#if __cpp_lib_ranges >= 201911
@@ -4681,9 +4771,6 @@ namespace std::ranges {
46814771
#endif
46824772

46834773
#include <string_view>
4684-
#if __cpp_lib_ranges >= 201911
4685-
#include <ranges>
4686-
#endif
46874774

46884775
namespace ctre {
46894776

@@ -4824,6 +4911,9 @@ template <typename RE, typename Method, typename Modifier> struct regular_expres
48244911
template <typename ResultIterator, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec_with_result_iterator(IteratorBegin begin, IteratorEnd end) noexcept {
48254912
return Method::template exec<Modifier, ResultIterator>(begin, end, RE{});
48264913
}
4914+
template <typename Range> constexpr CTRE_FORCE_INLINE static auto multi_exec(Range && range) noexcept {
4915+
return multi_subject_range<decltype(range.begin()), decltype(range.end()), regular_expression>{range.begin(), range.end()};
4916+
}
48274917
constexpr CTRE_FORCE_INLINE static auto exec() noexcept {
48284918
return Method::template exec();
48294919
}
@@ -4927,14 +5017,9 @@ template <typename Range, typename RE, typename Modifier> constexpr auto operato
49275017

49285018
template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, iterator_method, Modifier> re) noexcept = delete;
49295019

4930-
// range filter style API support for tokenize/range/split operations
4931-
#if __cpp_lib_ranges >= 201911
49325020
template <typename Range, typename RE, typename Method, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, Method, Modifier> re) noexcept {
4933-
return std::forward<Range>(range) | std::ranges::views::filter([](const decltype(*range.begin()) & item) -> bool{
4934-
return regular_expression<RE, Method, Modifier>{}.exec(item);
4935-
});
5021+
return re.multi_exec(std::forward<Range>(range));
49365022
}
4937-
#endif
49385023

49395024
#if CTRE_CNTTP_COMPILER_CHECK
49405025
#define CTRE_REGEX_INPUT_TYPE ctll::fixed_string

0 commit comments

Comments
 (0)