@@ -36,5 +36,145 @@ template <auto... Str, auto V, typename... Content, size_t Id, typename... Ts, s
36
36
return pcre_context{ctll::push_front (capture_with_name<Id, id<Str...>, Content...>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
37
37
}
38
38
39
+ template <size_t To, auto ... Str, typename T>
40
+ static constexpr auto replace_captures_with_id (T, string<Str...>) { // fallback case, no transform
41
+ return T{};
42
+ }
43
+
44
+ template <size_t To, auto ... Str, size_t From, typename ... Content>
45
+ static constexpr auto replace_captures_with_id (capture<From, Content...>, string<Str...>) {
46
+ return capture<To, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
47
+ }
48
+ // named reseted captures must have same Str... for all instances inside the call (otherwise how would we know how to access which by name?)
49
+ template <size_t To, auto ... Str, size_t From, auto ... Str2, typename ... Content>
50
+ static constexpr auto replace_captures_with_id (capture_with_name<From, id<Str2...>, Content...>, string<Str...>) {
51
+ static_assert ((id<Str...>{} == id<Str2...>{}) && " named captures must be named the same in reset group" );
52
+ return capture_with_name<To, id<Str...>, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
53
+ }
54
+
55
+ template <size_t To, auto ... Str, typename ... Content>
56
+ static constexpr auto replace_captures_with_id (sequence<Content...>, string<Str...>) {
57
+ return sequence<decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
58
+ }
59
+
60
+ template <size_t To, auto ... Str, size_t Id, typename ... Content>
61
+ static constexpr auto replace_captures_with_id (reset_group<Id, Content...>, string<Str...>) {
62
+ return reset_group<To, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
63
+ }
64
+
65
+ template <size_t To, auto ... Str, size_t Id, auto ... Str2, typename ... Content>
66
+ static constexpr auto replace_captures_with_id (reset_group_with_name<Id, id<Str2...>, Content...>, string<Str...>) {
67
+ return reset_group_with_name<To, id<Str...>, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
68
+ }
69
+
70
+ template <size_t To, auto ... Str, typename ... Content>
71
+ static constexpr auto replace_captures_with_id (atomic_group<Content...>, string<Str...>) {
72
+ return atomic_group<decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
73
+ }
74
+
75
+ template <size_t To, auto ... Str, typename ... Content>
76
+ static constexpr auto replace_captures_with_id (lookahead_positive<Content...>, string<Str...>) {
77
+ return lookahead_positive<decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
78
+ }
79
+
80
+ template <size_t To, auto ... Str, typename ... Content>
81
+ static constexpr auto replace_captures_with_id (lookahead_negative<Content...>, string<Str...>) {
82
+ return lookahead_negative<decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
83
+ }
84
+
85
+ template <size_t To, auto ... Str, size_t A, size_t B, typename ... Content>
86
+ static constexpr auto replace_captures_with_id (possessive_repeat<A, B, Content...>, string<Str...>) {
87
+ return possessive_repeat<A, B, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
88
+ }
89
+
90
+ template <size_t To, auto ... Str, size_t A, size_t B, typename ... Content>
91
+ static constexpr auto replace_captures_with_id (repeat<A, B, Content...>, string<Str...>) {
92
+ return repeat<A, B, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
93
+ }
94
+
95
+ template <size_t To, auto ... Str, size_t A, size_t B, typename ... Content>
96
+ static constexpr auto replace_captures_with_id (lazy_repeat<A, B, Content...>, string<Str...>) {
97
+ return lazy_repeat<A, B, decltype (replace_captures_with_id<To>(Content{}, string<Str...>{}))...>{};
98
+ }
99
+
100
+ template <size_t To, auto ... Str, typename ... Opts>
101
+ static constexpr auto replace_captures_with_id (select<Opts...>, string<Str...>) {
102
+ return select <decltype (replace_captures_with_id<To>(Opts{}, string<Str...>{}))...>{};
103
+ }
104
+
105
+ // get name (might be a utility already written)
106
+ template <size_t Idx, auto ... Str>
107
+ static constexpr string<Str...> get_capture_name (captured_content<Idx, id<Str...>>) noexcept {
108
+ return string<Str...>{};
109
+ }
110
+
111
+ template <size_t Idx>
112
+ static constexpr string<> get_capture_name (captured_content<Idx>) noexcept {
113
+ return string<>{};
114
+ }
115
+
116
+ template <typename T>
117
+ static constexpr string<> get_capture_name (T) noexcept {
118
+ return string<>{};
119
+ }
120
+
121
+ template <auto ... Str>
122
+ static constexpr id<Str...> make_id_from_string (string<Str...>) noexcept {
123
+ return id<Str...>{};
124
+ }
125
+
126
+ // find the first named capture
127
+ template <typename H, typename ... Tail>
128
+ static constexpr auto get_capture_with_name (ctll::list<H, Tail...>) noexcept {
129
+ if constexpr (sizeof ...(Tail))
130
+ return get_capture_with_name (ctll::list<Tail...>{});
131
+ else
132
+ return ctll::list<>{};
133
+ }
134
+
135
+ template <size_t Idx, typename Name, typename ... Tail>
136
+ static constexpr auto get_capture_with_name (ctll::list<captured_content<Idx, Name>, Tail...>) noexcept {
137
+ return ctll::list<captured_content<Idx, Name>>{};
138
+ }
139
+
140
+ // reset group start
141
+ template <auto V, typename ... Ts, size_t Counter> static constexpr auto apply (pcre::start_reset_group, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
142
+ return pcre_context{ ctll::push_front (reset_start<Counter+1 >(), ctll::list<Ts...>()), pcre_parameters<Counter>() };
143
+ }
144
+
145
+ // reset group end
146
+ template <auto V, typename A, typename ... Ts, size_t Id, size_t Counter> static constexpr auto apply (pcre::make_reset_group, ctll::term<V>, pcre_context<ctll::list<A, reset_start<Id>, Ts...>, pcre_parameters<Counter>>) {
147
+ using first_capture = decltype (ctll::front (find_captures (A{})));
148
+ if constexpr (::std::is_same_v<first_capture, ctll::_nothing>) {
149
+ // no captures to reset... easy case
150
+ return pcre_context{ ctll::list<sequence<A>, Ts...>(), pcre_parameters<Counter>() };
151
+ } else {
152
+ using first_named_capture = decltype (ctll::front (get_capture_with_name (find_captures (A{}))));
153
+ using capture_name = decltype (get_capture_name (first_named_capture{}));
154
+ if constexpr (::std::is_same_v<first_named_capture, ctll::_nothing> || ::std::is_same_v<capture_name, string<>>) {
155
+ return pcre_context{ ctll::list<reset_group<Id, decltype (replace_captures_with_id<Id>(A{}, string<>{}))>, Ts...>(), pcre_parameters<Counter>() };
156
+ } else {
157
+ return pcre_context{ ctll::list<reset_group_with_name<Id, decltype (make_id_from_string (capture_name{})), decltype (replace_captures_with_id<Id>(A{}, capture_name{}))>, Ts...>(), pcre_parameters<Counter>() };
158
+ }
159
+ }
160
+ }
161
+ // reset group end (sequence)
162
+ template <auto V, typename ... Content, typename ... Ts, size_t Id, size_t Counter> static constexpr auto apply (pcre::make_reset_group, ctll::term<V>, pcre_context<ctll::list<ctre::sequence<Content...>, reset_start<Id>, Ts...>, pcre_parameters<Counter>>) {
163
+ using first_capture = decltype (ctll::front (find_captures (sequence<Content...>{})));
164
+ if constexpr (::std::is_same_v<first_capture, ctll::_nothing>) {
165
+ // no captures to reset... easy case
166
+ return pcre_context{ ctll::list<sequence<Content...>, Ts...>(), pcre_parameters<Counter>() };
167
+ } else {
168
+ using first_named_capture = decltype (ctll::front (get_capture_with_name (find_captures (sequence<Content...>{}))));
169
+ using capture_name = decltype (get_capture_name (first_named_capture{}));
170
+ if constexpr (::std::is_same_v<first_named_capture, ctll::_nothing> || ::std::is_same_v<capture_name, string<>>) {
171
+ return pcre_context{ ctll::list<reset_group<Id, decltype (replace_captures_with_id<Id>(Content{}, string<>{}))...>, Ts...>(), pcre_parameters<Counter>() };
172
+ } else {
173
+ return pcre_context{ ctll::list<reset_group_with_name<Id, decltype (make_id_from_string (capture_name{})), decltype (replace_captures_with_id<Id>(Content{}, capture_name{}))...>, Ts...>(), pcre_parameters<Counter>() };
174
+ }
175
+ }
176
+ }
177
+
178
+
39
179
40
180
#endif
0 commit comments