NCBI C++ ToolKit
ctre-unicode.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  Apache License
3  Version 2.0, January 2004
4  http://www.apache.org/licenses/
5 
6  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 
8  1. Definitions.
9 
10  "License" shall mean the terms and conditions for use, reproduction,
11  and distribution as defined by Sections 1 through 9 of this document.
12 
13  "Licensor" shall mean the copyright owner or entity authorized by
14  the copyright owner that is granting the License.
15 
16  "Legal Entity" shall mean the union of the acting entity and all
17  other entities that control, are controlled by, or are under common
18  control with that entity. For the purposes of this definition,
19  "control" means (i) the power, direct or indirect, to cause the
20  direction or management of such entity, whether by contract or
21  otherwise, or (ii) ownership of fifty percent (50%) or more of the
22  outstanding shares, or (iii) beneficial ownership of such entity.
23 
24  "You" (or "Your") shall mean an individual or Legal Entity
25  exercising permissions granted by this License.
26 
27  "Source" form shall mean the preferred form for making modifications,
28  including but not limited to software source code, documentation
29  source, and configuration files.
30 
31  "Object" form shall mean any form resulting from mechanical
32  transformation or translation of a Source form, including but
33  not limited to compiled object code, generated documentation,
34  and conversions to other media types.
35 
36  "Work" shall mean the work of authorship, whether in Source or
37  Object form, made available under the License, as indicated by a
38  copyright notice that is included in or attached to the work
39  (an example is provided in the Appendix below).
40 
41  "Derivative Works" shall mean any work, whether in Source or Object
42  form, that is based on (or derived from) the Work and for which the
43  editorial revisions, annotations, elaborations, or other modifications
44  represent, as a whole, an original work of authorship. For the purposes
45  of this License, Derivative Works shall not include works that remain
46  separable from, or merely link (or bind by name) to the interfaces of,
47  the Work and Derivative Works thereof.
48 
49  "Contribution" shall mean any work of authorship, including
50  the original version of the Work and any modifications or additions
51  to that Work or Derivative Works thereof, that is intentionally
52  submitted to Licensor for inclusion in the Work by the copyright owner
53  or by an individual or Legal Entity authorized to submit on behalf of
54  the copyright owner. For the purposes of this definition, "submitted"
55  means any form of electronic, verbal, or written communication sent
56  to the Licensor or its representatives, including but not limited to
57  communication on electronic mailing lists, source code control systems,
58  and issue tracking systems that are managed by, or on behalf of, the
59  Licensor for the purpose of discussing and improving the Work, but
60  excluding communication that is conspicuously marked or otherwise
61  designated in writing by the copyright owner as "Not a Contribution."
62 
63  "Contributor" shall mean Licensor and any individual or Legal Entity
64  on behalf of whom a Contribution has been received by Licensor and
65  subsequently incorporated within the Work.
66 
67  2. Grant of Copyright License. Subject to the terms and conditions of
68  this License, each Contributor hereby grants to You a perpetual,
69  worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70  copyright license to reproduce, prepare Derivative Works of,
71  publicly display, publicly perform, sublicense, and distribute the
72  Work and such Derivative Works in Source or Object form.
73 
74  3. Grant of Patent License. Subject to the terms and conditions of
75  this License, each Contributor hereby grants to You a perpetual,
76  worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77  (except as stated in this section) patent license to make, have made,
78  use, offer to sell, sell, import, and otherwise transfer the Work,
79  where such license applies only to those patent claims licensable
80  by such Contributor that are necessarily infringed by their
81  Contribution(s) alone or by combination of their Contribution(s)
82  with the Work to which such Contribution(s) was submitted. If You
83  institute patent litigation against any entity (including a
84  cross-claim or counterclaim in a lawsuit) alleging that the Work
85  or a Contribution incorporated within the Work constitutes direct
86  or contributory patent infringement, then any patent licenses
87  granted to You under this License for that Work shall terminate
88  as of the date such litigation is filed.
89 
90  4. Redistribution. You may reproduce and distribute copies of the
91  Work or Derivative Works thereof in any medium, with or without
92  modifications, and in Source or Object form, provided that You
93  meet the following conditions:
94 
95  (a) You must give any other recipients of the Work or
96  Derivative Works a copy of this License; and
97 
98  (b) You must cause any modified files to carry prominent notices
99  stating that You changed the files; and
100 
101  (c) You must retain, in the Source form of any Derivative Works
102  that You distribute, all copyright, patent, trademark, and
103  attribution notices from the Source form of the Work,
104  excluding those notices that do not pertain to any part of
105  the Derivative Works; and
106 
107  (d) If the Work includes a "NOTICE" text file as part of its
108  distribution, then any Derivative Works that You distribute must
109  include a readable copy of the attribution notices contained
110  within such NOTICE file, excluding those notices that do not
111  pertain to any part of the Derivative Works, in at least one
112  of the following places: within a NOTICE text file distributed
113  as part of the Derivative Works; within the Source form or
114  documentation, if provided along with the Derivative Works; or,
115  within a display generated by the Derivative Works, if and
116  wherever such third-party notices normally appear. The contents
117  of the NOTICE file are for informational purposes only and
118  do not modify the License. You may add Your own attribution
119  notices within Derivative Works that You distribute, alongside
120  or as an addendum to the NOTICE text from the Work, provided
121  that such additional attribution notices cannot be construed
122  as modifying the License.
123 
124  You may add Your own copyright statement to Your modifications and
125  may provide additional or different license terms and conditions
126  for use, reproduction, or distribution of Your modifications, or
127  for any such Derivative Works as a whole, provided Your use,
128  reproduction, and distribution of the Work otherwise complies with
129  the conditions stated in this License.
130 
131  5. Submission of Contributions. Unless You explicitly state otherwise,
132  any Contribution intentionally submitted for inclusion in the Work
133  by You to the Licensor shall be under the terms and conditions of
134  this License, without any additional terms or conditions.
135  Notwithstanding the above, nothing herein shall supersede or modify
136  the terms of any separate license agreement you may have executed
137  with Licensor regarding such Contributions.
138 
139  6. Trademarks. This License does not grant permission to use the trade
140  names, trademarks, service marks, or product names of the Licensor,
141  except as required for reasonable and customary use in describing the
142  origin of the Work and reproducing the content of the NOTICE file.
143 
144  7. Disclaimer of Warranty. Unless required by applicable law or
145  agreed to in writing, Licensor provides the Work (and each
146  Contributor provides its Contributions) on an "AS IS" BASIS,
147  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148  implied, including, without limitation, any warranties or conditions
149  of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150  PARTICULAR PURPOSE. You are solely responsible for determining the
151  appropriateness of using or redistributing the Work and assume any
152  risks associated with Your exercise of permissions under this License.
153 
154  8. Limitation of Liability. In no event and under no legal theory,
155  whether in tort (including negligence), contract, or otherwise,
156  unless required by applicable law (such as deliberate and grossly
157  negligent acts) or agreed to in writing, shall any Contributor be
158  liable to You for damages, including any direct, indirect, special,
159  incidental, or consequential damages of any character arising as a
160  result of this License or out of the use or inability to use the
161  Work (including but not limited to damages for loss of goodwill,
162  work stoppage, computer failure or malfunction, or any and all
163  other commercial damages or losses), even if such Contributor
164  has been advised of the possibility of such damages.
165 
166  9. Accepting Warranty or Additional Liability. While redistributing
167  the Work or Derivative Works thereof, You may choose to offer,
168  and charge a fee for, acceptance of support, warranty, indemnity,
169  or other liability obligations and/or rights consistent with this
170  License. However, in accepting such obligations, You may act only
171  on Your own behalf and on Your sole responsibility, not on behalf
172  of any other Contributor, and only if You agree to indemnify,
173  defend, and hold each Contributor harmless for any liability
174  incurred by, or claims asserted against, such Contributor by reason
175  of your accepting any such warranty or additional liability.
176 
177  END OF TERMS AND CONDITIONS
178 
179  APPENDIX: How to apply the Apache License to your work.
180 
181  To apply the Apache License to your work, attach the following
182  boilerplate notice, with the fields enclosed by brackets "[]"
183  replaced with your own identifying information. (Don't include
184  the brackets!) The text should be enclosed in the appropriate
185  comment syntax for the file format. We also recommend that a
186  file or class name and description of purpose be included on the
187  same "printed page" as the copyright notice for easier
188  identification within third-party archives.
189 
190  Copyright [yyyy] [name of copyright owner]
191 
192  Licensed under the Apache License, Version 2.0 (the "License");
193  you may not use this file except in compliance with the License.
194  You may obtain a copy of the License at
195 
196  http://www.apache.org/licenses/LICENSE-2.0
197 
198  Unless required by applicable law or agreed to in writing, software
199  distributed under the License is distributed on an "AS IS" BASIS,
200  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201  See the License for the specific language governing permissions and
202  limitations under the License.
203 
204 
205 --- LLVM Exceptions to the Apache 2.0 License ----
206 
207 As an exception, if, as a result of your compiling your source code, portions
208 of this Software are embedded into an Object form of such source code, you
209 may redistribute such embedded portions in such Object form without complying
210 with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
211 
212 In addition, if you combine or link compiled forms of this Software with
213 software that is licensed under the GPLv2 ("Combined Software") and if a
214 court of competent jurisdiction determines that the patent provision (Section
215 3), the indemnity provision (Section 9) or other Section of the License
216 conflicts with the conditions of the GPLv2, you may retroactively and
217 prospectively choose to deem waived or otherwise exclude such Section(s) of
218 the License, but only in their entirety and only with respect to the Combined
219 Software.
220 */
221 #ifndef CTRE_V2__CTRE_UNICODE__HPP
222 #define CTRE_V2__CTRE_UNICODE__HPP
223 
224 #ifndef CTRE_V2__CTRE__HPP
225 #define CTRE_V2__CTRE__HPP
226 
227 #ifndef CTRE_V2__CTRE__LITERALS__HPP
228 #define CTRE_V2__CTRE__LITERALS__HPP
229 
230 #ifndef CTRE_V2__CTLL__HPP
231 #define CTRE_V2__CTLL__HPP
232 
233 #ifndef CTLL__PARSER__HPP
234 #define CTLL__PARSER__HPP
235 
236 #ifndef CTLL__FIXED_STRING__GPP
237 #define CTLL__FIXED_STRING__GPP
238 
239 #include <utility>
240 #include <cstddef>
241 #include <string_view>
242 #include <cstdint>
243 
244 namespace ctll {
245 
249 };
250 
252  if ((first_unit & 0b1000'0000) == 0b0000'0000) return {static_cast<uint32_t>(first_unit), 1};
253  else if ((first_unit & 0b1110'0000) == 0b1100'0000) return {static_cast<uint32_t>(first_unit & 0b0001'1111), 2};
254  else if ((first_unit & 0b1111'0000) == 0b1110'0000) return {static_cast<uint32_t>(first_unit & 0b0000'1111), 3};
255  else if ((first_unit & 0b1111'1000) == 0b1111'0000) return {static_cast<uint32_t>(first_unit & 0b0000'0111), 4};
256  else if ((first_unit & 0b1111'1100) == 0b1111'1000) return {static_cast<uint32_t>(first_unit & 0b0000'0011), 5};
257  else if ((first_unit & 0b1111'1100) == 0b1111'1100) return {static_cast<uint32_t>(first_unit & 0b0000'0001), 6};
258  else return {0, 0};
259 }
260 
261 constexpr char32_t value_of_trailing_utf8_code_point(uint8_t unit, bool & correct) noexcept {
262  if ((unit & 0b1100'0000) == 0b1000'0000) return unit & 0b0011'1111;
263  else {
264  correct = false;
265  return 0;
266  }
267 }
268 
270  if ((first_unit & 0b1111110000000000) == 0b1101'1000'0000'0000) return {static_cast<uint32_t>(first_unit & 0b0000001111111111), 2};
271  else return {first_unit, 1};
272 }
273 
274 template <size_t N> struct fixed_string {
275  char32_t content[N] = {};
276  size_t real_size{0};
277  bool correct_flag{true};
278  template <typename T> constexpr fixed_string(const T (&input)[N+1]) noexcept {
279  if constexpr (std::is_same_v<T, char>) {
280  #ifdef CTRE_STRING_IS_UTF8
281  size_t out{0};
282  for (size_t i{0}; i < N; ++i) {
283  if ((i == (N-1)) && (input[i] == 0)) break;
285  switch (info.length) {
286  case 6:
287  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
288  [[fallthrough]];
289  case 5:
290  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
291  [[fallthrough]];
292  case 4:
293  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
294  [[fallthrough]];
295  case 3:
296  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
297  [[fallthrough]];
298  case 2:
299  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
300  [[fallthrough]];
301  case 1:
302  content[out++] = static_cast<char32_t>(info.value);
303  real_size++;
304  break;
305  default:
306  correct_flag = false;
307  return;
308  }
309  }
310  #else
311  for (size_t i{0}; i < N; ++i) {
312  content[i] = static_cast<uint8_t>(input[i]);
313  if ((i == (N-1)) && (input[i] == 0)) break;
314  real_size++;
315  }
316  #endif
317  #if __cpp_char8_t
318  } else if constexpr (std::is_same_v<T, char8_t>) {
319  size_t out{0};
320  for (size_t i{0}; i < N; ++i) {
321  if ((i == (N-1)) && (input[i] == 0)) break;
323  switch (info.length) {
324  case 6:
325  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
326  [[fallthrough]];
327  case 5:
328  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
329  [[fallthrough]];
330  case 4:
331  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
332  [[fallthrough]];
333  case 3:
334  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
335  [[fallthrough]];
336  case 2:
337  if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
338  [[fallthrough]];
339  case 1:
340  content[out++] = static_cast<char32_t>(info.value);
341  real_size++;
342  break;
343  default:
344  correct_flag = false;
345  return;
346  }
347  }
348  #endif
349  } else if constexpr (std::is_same_v<T, char16_t>) {
350  size_t out{0};
351  for (size_t i{0}; i < N; ++i) {
353  if (info.length == 2) {
354  if (++i < N) {
355  if ((input[i] & 0b1111'1100'0000'0000) == 0b1101'1100'0000'0000) {
356  content[out++] = ((info.value << 10) | (input[i] & 0b0000'0011'1111'1111)) + 0x10000;
357  } else {
358  correct_flag = false;
359  break;
360  }
361  }
362  } else {
363  if ((i == (N-1)) && (input[i] == 0)) break;
364  content[out++] = info.value;
365  }
366  }
367  real_size = out;
368  } else if constexpr (std::is_same_v<T, wchar_t> || std::is_same_v<T, char32_t>) {
369  for (size_t i{0}; i < N; ++i) {
370  content[i] = static_cast<char32_t>(input[i]);
371  if ((i == (N-1)) && (input[i] == 0)) break;
372  real_size++;
373  }
374  }
375  }
376  constexpr fixed_string(const fixed_string & other) noexcept {
377  for (size_t i{0}; i < N; ++i) {
378  content[i] = other.content[i];
379  }
380  real_size = other.real_size;
381  correct_flag = other.correct_flag;
382  }
383  constexpr bool correct() const noexcept {
384  return correct_flag;
385  }
386  constexpr size_t size() const noexcept {
387  return real_size;
388  }
389  constexpr const char32_t * begin() const noexcept {
390  return content;
391  }
392  constexpr const char32_t * end() const noexcept {
393  return content + size();
394  }
395  constexpr char32_t operator[](size_t i) const noexcept {
396  return content[i];
397  }
398  template <size_t M> constexpr bool is_same_as(const fixed_string<M> & rhs) const noexcept {
399  if (real_size != rhs.size()) return false;
400  for (size_t i{0}; i != real_size; ++i) {
401  if (content[i] != rhs[i]) return false;
402  }
403  return true;
404  }
405  constexpr operator std::basic_string_view<char32_t>() const noexcept {
406  return std::basic_string_view<char32_t>{content, size()};
407  }
408 };
409 
410 template <> class fixed_string<0> {
411  static constexpr char32_t empty[1] = {0};
412 public:
413  template <typename T> constexpr fixed_string(const T *) noexcept {
414 
415  }
416  constexpr fixed_string(std::initializer_list<char32_t>) noexcept {
417 
418  }
419  constexpr fixed_string(const fixed_string &) noexcept {
420 
421  }
422  constexpr bool correct() const noexcept {
423  return true;
424  }
425  constexpr size_t size() const noexcept {
426  return 0;
427  }
428  constexpr const char32_t * begin() const noexcept {
429  return empty;
430  }
431  constexpr const char32_t * end() const noexcept {
432  return empty + size();
433  }
434  constexpr char32_t operator[](size_t) const noexcept {
435  return 0;
436  }
437  constexpr operator std::basic_string_view<char32_t>() const noexcept {
438  return std::basic_string_view<char32_t>{empty, 0};
439  }
440 };
441 
442 template <typename CharT, size_t N> fixed_string(const CharT (&)[N]) -> fixed_string<N-1>;
444 
445 }
446 
447 #endif
448 
449 #ifndef CTLL__TYPE_STACK__HPP
450 #define CTLL__TYPE_STACK__HPP
451 
452 #ifndef CTLL__UTILITIES__HPP
453 #define CTLL__UTILITIES__HPP
454 
455 #include <type_traits>
456 
457 #if defined __cpp_nontype_template_parameter_class
458  #define CTLL_CNTTP_COMPILER_CHECK 1
459 #elif defined __cpp_nontype_template_args
460 // compiler which defines correctly feature test macro (not you clang)
461  #if __cpp_nontype_template_args >= 201911L
462  #define CTLL_CNTTP_COMPILER_CHECK 1
463  #elif __cpp_nontype_template_args >= 201411L
464 // appleclang 13+
465  #if defined __apple_build_version__
466  #if defined __clang_major__ && __clang_major__ >= 13
467 // but only in c++20 and more
468  #if __cplusplus > 201703L
469  #define CTLL_CNTTP_COMPILER_CHECK 1
470  #endif
471  #endif
472  #else
473 // clang 12+
474  #if defined __clang_major__ && __clang_major__ >= 12
475 // but only in c++20 and more
476  #if __cplusplus > 201703L
477  #define CTLL_CNTTP_COMPILER_CHECK 1
478  #endif
479  #endif
480  #endif
481  #endif
482 #endif
483 
484 #ifndef CTLL_CNTTP_COMPILER_CHECK
485  #define CTLL_CNTTP_COMPILER_CHECK 0
486 #endif
487 
488 #ifdef _MSC_VER
489 #define CTLL_FORCE_INLINE __forceinline
490 #else
491 #define CTLL_FORCE_INLINE __attribute__((always_inline))
492 #endif
493 
494 namespace ctll {
495 
496 template <bool> struct conditional_helper;
497 
498 template <> struct conditional_helper<true> {
499  template <typename A, typename> using type = A;
500 };
501 
502 template <> struct conditional_helper<false> {
503  template <typename, typename B> using type = B;
504 };
505 
506 template <bool V, typename A, typename B> using conditional = typename conditional_helper<V>::template type<A,B>;
507 
508 }
509 
510 #endif
511 
512 namespace ctll {
513 
514 template <typename... Ts> struct list { };
515 
516 struct _nothing { };
517 
519 
520 // calculate size of list content
521 template <typename... Ts> constexpr auto size(list<Ts...>) noexcept { return sizeof...(Ts); }
522 
523 
524 // check if the list is empty
525 template <typename... Ts> constexpr bool empty(list<Ts...>) noexcept { return false; }
526 constexpr bool empty(empty_list) { return true; }
527 
528 // concat two lists together left to right
529 template <typename... As, typename... Bs> constexpr auto concat(list<As...>, list<Bs...>) noexcept -> list<As..., Bs...> { return {}; }
530 
531 // push something to the front of a list
532 template <typename T, typename... As> constexpr auto push_front(T, list<As...>) noexcept -> list<T, As...> { return {}; }
533 
534 // pop element from the front of a list
535 template <typename T, typename... As> constexpr auto pop_front(list<T, As...>) noexcept -> list<As...> { return {}; }
536 constexpr auto pop_front(empty_list) -> empty_list;
537 
538 // pop element from the front of a list and return new typelist too
539 template <typename Front, typename List> struct list_pop_pair {
540  Front front{};
541  List list{};
542  constexpr list_pop_pair() = default;
543 };
544 
545 template <typename Head, typename... As, typename T = _nothing> constexpr auto pop_and_get_front(list<Head, As...>, T = T()) noexcept -> list_pop_pair<Head, list<As...>> { return {}; }
546 template <typename T = _nothing> constexpr auto pop_and_get_front(empty_list, T = T()) noexcept -> list_pop_pair<T, empty_list> { return {}; }
547 
548 // return front of the list
549 template <typename Head, typename... As, typename T = _nothing> constexpr auto front(list<Head, As...>, T = T()) noexcept -> Head { return {}; }
550 template <typename T = _nothing> constexpr auto front(empty_list, T = T()) noexcept -> T { return {}; }
551 
552 // rotate list
553 template <typename T> struct rotate_item {
554  template <typename... Ts> friend constexpr auto operator+(list<Ts...>, rotate_item<T>) noexcept -> list<T, Ts...> { return {}; }
555 };
556 
557 template <typename... Ts> constexpr auto rotate(list<Ts...>) -> decltype((list<>{} + ... + rotate_item<Ts>{})) {
558  return {};
559 }
560 
561 // set operations
562 template <typename T> struct item_matcher {
563  struct not_selected {
564  template <typename... Ts> friend constexpr auto operator+(list<Ts...>, not_selected) -> list<Ts...>;
565  };
566  template <typename Y> struct wrapper {
567  template <typename... Ts> friend constexpr auto operator+(list<Ts...>, wrapper<Y>) -> list<Ts...,Y>;
568  };
569 
570  static constexpr auto check(T) { return std::true_type{}; }
571  static constexpr auto check(...) { return std::false_type{}; }
572  static constexpr auto select(T) { return not_selected{}; }
573  template <typename Y> static constexpr auto select(Y) { return wrapper<Y>{}; }
574 };
575 
576 template <typename T, typename... Ts> constexpr bool exists_in(T, list<Ts...>) noexcept {
577  return (item_matcher<T>::check(Ts{}) || ... || false);
578 }
579 
580 template <typename T, typename... Ts> constexpr auto add_item(T item, list<Ts...> l) noexcept {
581  if constexpr (exists_in(item, l)) {
582  return l;
583  } else {
584  return list<Ts..., T>{};
585  }
586 }
587 
588 template <typename T, typename... Ts> constexpr auto remove_item(T, list<Ts...>) noexcept {
589  item_matcher<T> matcher;
590  return decltype((list<>{} + ... + matcher.select(Ts{}))){};
591 }
592 
593 }
594 
595 #endif
596 
597 #ifndef CTLL__GRAMMARS__HPP
598 #define CTLL__GRAMMARS__HPP
599 
600 namespace ctll {
601 
602 // terminal type representing symbol / character of any type
603 template <auto v> struct term {
604  static constexpr auto value = v;
605 };
606 
607 // epsilon = nothing on input tape
608 // also used as an command for parsing means "do nothing"
609 struct epsilon {
610  static constexpr auto value = '-';
611 };
612 
613 // empty_stack_symbol = nothing on stack
615 
616 // push<T...> is alias to list<T...>
617 template <typename... Ts> using push = list<Ts...>;
618 
619 // accept/reject type for controlling output of LL1 machine
620 struct accept { constexpr explicit operator bool() noexcept { return true; } };
621 struct reject { constexpr explicit operator bool() noexcept { return false; } };
622 
623 // action type, every action item in grammar must inherit from
624 struct action {
625  struct action_tag { };
626 };
627 
628 // move one character forward and pop it from stack command
629 struct pop_input {
630  struct pop_input_tag { };
631 };
632 
633 // additional overloads for type list
634 template <typename... Ts> constexpr auto push_front(pop_input, list<Ts...>) -> list<Ts...> { return {}; }
635 
636 template <typename... Ts> constexpr auto push_front(epsilon, list<Ts...>) -> list<Ts...> { return {}; }
637 
638 template <typename... As, typename... Bs> constexpr auto push_front(list<As...>, list<Bs...>) -> list<As..., Bs...> { return {}; }
639 
640 template <typename T, typename... As> constexpr auto pop_front_and_push_front(T item, list<As...> l) {
641  return push_front(item, pop_front(l));
642 }
643 
644 // SPECIAL matching types for nicer grammars
645 
646 // match any term
647 struct anything {
648  constexpr inline anything() noexcept { }
649  template <auto V> constexpr anything(term<V>) noexcept;
650 };
651 
652 // match range of term A-B
653 template <auto A, decltype(A) B> struct range {
654  constexpr inline range() noexcept { }
655  //template <auto V> constexpr range(term<V>) noexcept requires (A <= V) && (V <= B);
656  template <auto V, typename = std::enable_if_t<(A <= V) && (V <= B)>> constexpr inline range(term<V>) noexcept;
657 };
658 
659 #ifdef __EDG__
660 template <auto V, auto... Set> struct contains {
661  static constexpr bool value = ((Set == V) || ... || false);
662 };
663 #endif
664 
665 // match terms defined in set
666 template <auto... Def> struct set {
667  constexpr inline set() noexcept { }
668  #ifdef __EDG__
669  template <auto V, typename = std::enable_if_t<contains<V, Def...>::value>> constexpr inline set(term<V>) noexcept;
670  #else
671  template <auto V, typename = std::enable_if_t<((Def == V) || ... || false)>> constexpr inline set(term<V>) noexcept;
672  #endif
673 };
674 
675 // match terms not defined in set
676 template <auto... Def> struct neg_set {
677  constexpr inline neg_set() noexcept { }
678 
679  #ifdef __EDG__
680  template <auto V, typename = std::enable_if_t<!contains<V, Def...>::value>> constexpr inline neg_set(term<V>) noexcept;
681  #else
682  template <auto V, typename = std::enable_if_t<!((Def == V) || ... || false)>> constexpr inline neg_set(term<V>) noexcept;
683  #endif
684 };
685 
686 // AUGMENTED grammar which completes user-defined grammar for all other cases
687 template <typename Grammar> struct augment_grammar: public Grammar {
688  // start nonterminal is defined in parent type
689  using typename Grammar::_start;
690 
691  // grammar rules are inherited from Grammar parent type
692  using Grammar::rule;
693 
694  // term on stack and on input means pop_input;
695  template <auto A> static constexpr auto rule(term<A>, term<A>) -> ctll::pop_input;
696 
697  // if the type on stack (range, set, neg_set, anything) is constructible from the terminal => pop_input
698  template <typename Expected, auto V> static constexpr auto rule(Expected, term<V>) -> std::enable_if_t<std::is_constructible_v<Expected, term<V>>, ctll::pop_input>;
699 
700  // empty stack and empty input means we are accepting
701  static constexpr auto rule(empty_stack_symbol, epsilon) -> ctll::accept;
702 
703  // not matching anything else => reject
704  static constexpr auto rule(...) -> ctll::reject;
705 
706  // start stack is just a list<Grammar::_start>;
708 };
709 
710 }
711 
712 #endif
713 
714 #ifndef CTLL__ACTIONS__HPP
715 #define CTLL__ACTIONS__HPP
716 
717 namespace ctll {
718  struct empty_subject { };
719 
720  struct empty_actions {
721  // dummy operator so using Actions::operator() later will not give error
722  template <typename Action, typename InputSymbol, typename Subject> static constexpr auto apply(Action, InputSymbol, Subject subject) {
723  return subject;
724  }
725  };
726 
727  template <typename Actions> struct identity: public Actions {
728  using Actions::apply;
729  // allow empty_subject to exists
730  template <typename Action, auto V> constexpr static auto apply(Action, term<V>, empty_subject) -> empty_subject { return {}; }
731  template <typename Action> constexpr static auto apply(Action, epsilon, empty_subject) -> empty_subject { return {}; }
732  };
733 
734  template <typename Actions> struct ignore_unknown: public Actions {
735  using Actions::apply;
736  // allow flow thru unknown actions
737  template <typename Action, auto V, typename Subject> constexpr static auto apply(Action, term<V>, Subject) -> Subject { return {}; }
738  template <typename Action, typename Subject> constexpr static auto apply(Action, epsilon, Subject) -> Subject { return {}; }
739  };
740 }
741 
742 #endif
743 
744 #include <limits>
745 
746 namespace ctll {
747 
748 enum class decision {
749  reject,
750  accept,
751  undecided
752 };
753 
754 struct placeholder { };
755 
756 template <size_t> using index_placeholder = placeholder;
757 
758 #if CTLL_CNTTP_COMPILER_CHECK
759 template <typename Grammar, ctll::fixed_string input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser { // in c++20
760 #else
761 template <typename Grammar, const auto & input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser {
762 #endif
763 
764  #ifdef __GNUC__ // workaround to GCC bug
765  #if CTLL_CNTTP_COMPILER_CHECK
766  static constexpr auto _input = input; // c++20 mode
767  #else
768  static constexpr auto & _input = input; // c++17 mode
769  #endif
770  #else
771  static constexpr auto _input = input; // everyone else
772  #endif
773 
776 
777  template <size_t Pos, typename Stack, typename Subject, decision Decision> struct results {
778 
779  static constexpr bool is_correct = Decision == decision::accept;
780 
781  constexpr inline CTLL_FORCE_INLINE operator bool() const noexcept {
782  return is_correct;
783  }
784 
785  #ifdef __GNUC__ // workaround to GCC bug
786  #if CTLL_CNTTP_COMPILER_CHECK
787  static constexpr auto _input = input; // c++20 mode
788  #else
789  static constexpr auto & _input = input; // c++17 mode
790  #endif
791  #else
792  static constexpr auto _input = input; // everyone else
793  #endif
794 
795  using output_type = Subject;
796  static constexpr size_t position = Pos;
797 
798  constexpr auto operator+(placeholder) const noexcept {
799  if constexpr (Decision == decision::undecided) {
800  // parse for current char (RPos) with previous stack and subject :)
801  return parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template decide<Pos, Stack, Subject>({}, {});
802  } else {
803  // if there is decision already => just push it to the end of fold expression
804  return *this;
805  }
806  }
807  };
808 
809  template <size_t Pos> static constexpr auto get_current_term() noexcept {
810  if constexpr (Pos < input.size()) {
811  constexpr auto value = input[Pos];
812  if constexpr (value <= static_cast<decltype(value)>((std::numeric_limits<char>::max)())) {
813  return term<static_cast<char>(value)>{};
814  } else {
815  return term<value>{};
816  }
817 
818  } else {
819  // return epsilon if we are past the input
820  return epsilon{};
821  }
822  }
823  template <size_t Pos> static constexpr auto get_previous_term() noexcept {
824  if constexpr (Pos == 0) {
825  // there is no previous character on input if we are on start
826  return epsilon{};
827  } else if constexpr ((Pos-1) < input.size()) {
828  constexpr auto value = input[Pos-1];
829  if constexpr (value <= static_cast<decltype(value)>((std::numeric_limits<char>::max)())) {
830  return term<static_cast<char>(value)>{};
831  } else {
832  return term<value>{};
833  }
834  } else {
835  return epsilon{};
836  }
837  }
838  // if rule is accept => return true and subject
839  template <size_t Pos, typename Terminal, typename Stack, typename Subject>
840  static constexpr auto move(ctll::accept, Terminal, Stack, Subject) noexcept {
842  }
843  // if rule is reject => return false and subject
844  template <size_t Pos, typename Terminal, typename Stack, typename Subject>
845  static constexpr auto move(ctll::reject, Terminal, Stack, Subject) noexcept {
847  }
848  // if rule is pop_input => move to next character
849  template <size_t Pos, typename Terminal, typename Stack, typename Subject>
850  static constexpr auto move(ctll::pop_input, Terminal, Stack, Subject) noexcept {
852  }
853  // if rule is string => push it to the front of stack
854  template <size_t Pos, typename... Content, typename Terminal, typename Stack, typename Subject>
855  static constexpr auto move(push<Content...> string, Terminal, Stack stack, Subject subject) noexcept {
856  return decide<Pos>(push_front(string, stack), subject);
857  }
858  // if rule is epsilon (empty string) => continue
859  template <size_t Pos, typename Terminal, typename Stack, typename Subject>
860  static constexpr auto move(epsilon, Terminal, Stack stack, Subject subject) noexcept {
861  return decide<Pos>(stack, subject);
862  }
863  // if rule is string with current character at the beginning (term<V>) => move to next character
864  // and push string without the character (quick LL(1))
865  template <size_t Pos, auto V, typename... Content, typename Stack, typename Subject>
866  static constexpr auto move(push<term<V>, Content...>, term<V>, Stack stack, Subject) noexcept {
867  constexpr auto local_input = input;
869  }
870  // if rule is string with any character at the beginning (compatible with current term<T>) => move to next character
871  // and push string without the character (quick LL(1))
872  template <size_t Pos, auto V, typename... Content, auto T, typename Stack, typename Subject>
873  static constexpr auto move(push<anything, Content...>, term<T>, Stack stack, Subject) noexcept {
874  constexpr auto local_input = input;
876  }
877  // decide if we need to take action or move
878  template <size_t Pos, typename Stack, typename Subject> static constexpr auto decide(Stack previous_stack, Subject previous_subject) noexcept {
879  // each call means we pop something from stack
880  auto top_symbol = decltype(ctll::front(previous_stack, empty_stack_symbol()))();
881  // gcc pedantic warning
882  [[maybe_unused]] auto stack = decltype(ctll::pop_front(previous_stack))();
883 
884  // in case top_symbol is action type (apply it on previous subject and get new one)
885  if constexpr (std::is_base_of_v<ctll::action, decltype(top_symbol)>) {
886  auto subject = Actions::apply(top_symbol, get_previous_term<Pos>(), previous_subject);
887 
888  // in case that semantic action is error => reject input
889  if constexpr (std::is_same_v<ctll::reject, decltype(subject)>) {
891  } else {
892  return decide<Pos>(stack, subject);
893  }
894  } else {
895  // all other cases are ordinary for LL(1) parser
896  auto current_term = get_current_term<Pos>();
897  auto rule = decltype(grammar::rule(top_symbol,current_term))();
898  return move<Pos>(rule, current_term, stack, previous_subject);
899  }
900  }
901 
902  // trampolines with folded expression
903  template <typename Subject, size_t... Pos> static constexpr auto trampoline_decide(Subject, std::index_sequence<Pos...>) noexcept {
904  // parse everything for first char and than for next and next ...
905  // Pos+1 is needed as we want to finish calculation with epsilons on stack
906  auto v = (decide<0, typename grammar::start_stack, Subject>({}, {}) + ... + index_placeholder<Pos+1>());
907  return v;
908  }
909 
910  template <typename Subject = empty_subject> static constexpr auto trampoline_decide(Subject subject = {}) noexcept {
911  // there will be no recursion, just sequence long as the input
912  return trampoline_decide(subject, std::make_index_sequence<input.size()>());
913  }
914 
915  template <typename Subject = empty_subject> using output = decltype(trampoline_decide<Subject>());
916  template <typename Subject = empty_subject> static inline constexpr bool correct_with = trampoline_decide<Subject>();
917 
918 };
919 
920 } // end of ctll namespace
921 
922 #endif
923 
924 #endif
925 
926 #ifndef CTRE__PCRE_ACTIONS__HPP
927 #define CTRE__PCRE_ACTIONS__HPP
928 
929 #ifndef CTRE__PCRE__HPP
930 #define CTRE__PCRE__HPP
931 
932 // THIS FILE WAS GENERATED BY DESATOMAT TOOL, DO NOT MODIFY THIS FILE
933 
934 namespace ctre {
935 
936 struct pcre {
937 
938 // NONTERMINALS:
939  struct a {};
940  struct b {};
941  struct backslash {};
942  struct backslash_range {};
943  struct block {};
944  struct block_name2 {};
945  struct c {};
946  struct class_named_name {};
947  struct content2 {};
948  struct content {};
949  struct content_in_capture {};
950  struct d {};
951  struct e {};
952  struct f {};
953  struct g {};
954  struct h {};
955  struct hexdec_repeat {};
956  struct i {};
957  struct j {};
958  struct k {};
959  struct l {};
960  struct m {};
961  struct mod {};
962  struct mode_switch2 {};
963  struct n {};
964  struct number2 {};
965  struct number {};
966  struct o {};
967  struct p {};
968  struct property_name2 {};
969  struct property_name {};
970  struct property_value2 {};
971  struct property_value {};
972  struct range {};
973  struct repeat {};
974  struct s {}; using _start = s;
975  struct set2a {};
976  struct set2b {};
977  struct string2 {};
978 
979 // 'action' types:
980  struct class_digit: ctll::action {};
981  struct class_horizontal_space: ctll::action {};
982  struct class_named_alnum: ctll::action {};
983  struct class_named_alpha: ctll::action {};
984  struct class_named_ascii: ctll::action {};
985  struct class_named_blank: ctll::action {};
986  struct class_named_cntrl: ctll::action {};
987  struct class_named_digit: ctll::action {};
988  struct class_named_graph: ctll::action {};
989  struct class_named_lower: ctll::action {};
990  struct class_named_print: ctll::action {};
991  struct class_named_punct: ctll::action {};
992  struct class_named_space: ctll::action {};
993  struct class_named_upper: ctll::action {};
994  struct class_named_word: ctll::action {};
995  struct class_named_xdigit: ctll::action {};
996  struct class_non_horizontal_space: ctll::action {};
997  struct class_non_vertical_space: ctll::action {};
998  struct class_nondigit: ctll::action {};
999  struct class_nonnewline: ctll::action {};
1000  struct class_nonspace: ctll::action {};
1001  struct class_nonword: ctll::action {};
1002  struct class_space: ctll::action {};
1003  struct class_vertical_space: ctll::action {};
1004  struct class_word: ctll::action {};
1005  struct create_hexdec: ctll::action {};
1006  struct create_number: ctll::action {};
1007  struct finish_hexdec: ctll::action {};
1008  struct look_finish: ctll::action {};
1009  struct make_alternate: ctll::action {};
1010  struct make_atomic: ctll::action {};
1011  struct make_back_reference: ctll::action {};
1012  struct make_capture: ctll::action {};
1013  struct make_capture_with_name: ctll::action {};
1014  struct make_lazy: ctll::action {};
1015  struct make_optional: ctll::action {};
1016  struct make_possessive: ctll::action {};
1017  struct make_property: ctll::action {};
1018  struct make_property_negative: ctll::action {};
1019  struct make_range: ctll::action {};
1020  struct make_relative_back_reference: ctll::action {};
1021  struct make_sequence: ctll::action {};
1022  struct mode_case_insensitive: ctll::action {};
1023  struct mode_case_sensitive: ctll::action {};
1024  struct mode_multiline: ctll::action {};
1025  struct mode_singleline: ctll::action {};
1026  struct negate_class_named: ctll::action {};
1027  struct prepare_capture: ctll::action {};
1028  struct push_assert_begin: ctll::action {};
1029  struct push_assert_end: ctll::action {};
1030  struct push_assert_subject_begin: ctll::action {};
1031  struct push_assert_subject_end: ctll::action {};
1032  struct push_assert_subject_end_with_lineend: ctll::action {};
1033  struct push_character: ctll::action {};
1034  struct push_character_alarm: ctll::action {};
1035  struct push_character_anything: ctll::action {};
1036  struct push_character_escape: ctll::action {};
1037  struct push_character_formfeed: ctll::action {};
1038  struct push_character_newline: ctll::action {};
1039  struct push_character_null: ctll::action {};
1040  struct push_character_return_carriage: ctll::action {};
1041  struct push_character_tab: ctll::action {};
1042  struct push_empty: ctll::action {};
1043  struct push_hexdec: ctll::action {};
1044  struct push_name: ctll::action {};
1045  struct push_not_word_boundary: ctll::action {};
1046  struct push_number: ctll::action {};
1047  struct push_property_name: ctll::action {};
1048  struct push_property_value: ctll::action {};
1049  struct push_word_boundary: ctll::action {};
1050  struct repeat_ab: ctll::action {};
1051  struct repeat_at_least: ctll::action {};
1052  struct repeat_exactly: ctll::action {};
1053  struct repeat_plus: ctll::action {};
1054  struct repeat_star: ctll::action {};
1055  struct reset_capture: ctll::action {};
1056  struct set_combine: ctll::action {};
1057  struct set_make: ctll::action {};
1058  struct set_make_negative: ctll::action {};
1059  struct set_start: ctll::action {};
1060  struct start_atomic: ctll::action {};
1061  struct start_lookahead_negative: ctll::action {};
1062  struct start_lookahead_positive: ctll::action {};
1063  struct start_lookbehind_negative: ctll::action {};
1064  struct start_lookbehind_positive: ctll::action {};
1065 
1066 // (q)LL1 function:
1067  using _others = ctll::neg_set<'!','$','\x28','\x29','*','+',',','-','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','0','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>;
1069  static constexpr auto rule(s, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
1073  static constexpr auto rule(s, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1074  static constexpr auto rule(s, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1077  static constexpr auto rule(s, ctll::epsilon) -> ctll::push<push_empty>;
1078  static constexpr auto rule(s, ctll::set<'\x29','*','+','?','\x7B','\x7D'>) -> ctll::reject;
1079 
1085  static constexpr auto rule(a, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, content2, make_alternate>;
1088  static constexpr auto rule(a, ctll::term<'\x29'>) -> ctll::push<push_empty, make_alternate>;
1089  static constexpr auto rule(a, ctll::epsilon) -> ctll::push<push_empty, make_alternate>;
1090  static constexpr auto rule(a, ctll::set<'*','+','?','\x7B','|','\x7D'>) -> ctll::reject;
1091 
1092  static constexpr auto rule(b, ctll::term<','>) -> ctll::push<ctll::anything, n>;
1093  static constexpr auto rule(b, ctll::term<'\x7D'>) -> ctll::push<repeat_exactly, ctll::anything>;
1094 
1095  static constexpr auto rule(backslash, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
1096  static constexpr auto rule(backslash, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
1097  static constexpr auto rule(backslash, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
1098  static constexpr auto rule(backslash, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
1099  static constexpr auto rule(backslash, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
1100  static constexpr auto rule(backslash, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
1101  static constexpr auto rule(backslash, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
1102  static constexpr auto rule(backslash, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
1103  static constexpr auto rule(backslash, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
1104  static constexpr auto rule(backslash, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
1105  static constexpr auto rule(backslash, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
1107  static constexpr auto rule(backslash, ctll::term<'g'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, m>;
1108  static constexpr auto rule(backslash, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
1109  static constexpr auto rule(backslash, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
1110  static constexpr auto rule(backslash, ctll::term<'u'>) -> ctll::push<ctll::anything, k>;
1111  static constexpr auto rule(backslash, ctll::term<'x'>) -> ctll::push<ctll::anything, l>;
1112  static constexpr auto rule(backslash, ctll::term<'A'>) -> ctll::push<ctll::anything, push_assert_subject_begin>;
1113  static constexpr auto rule(backslash, ctll::term<'z'>) -> ctll::push<ctll::anything, push_assert_subject_end>;
1115  static constexpr auto rule(backslash, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character>;
1116  static constexpr auto rule(backslash, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm>;
1117  static constexpr auto rule(backslash, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape>;
1118  static constexpr auto rule(backslash, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed>;
1119  static constexpr auto rule(backslash, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline>;
1120  static constexpr auto rule(backslash, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null>;
1121  static constexpr auto rule(backslash, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage>;
1122  static constexpr auto rule(backslash, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab>;
1123  static constexpr auto rule(backslash, ctll::term<'B'>) -> ctll::push<ctll::anything, push_not_word_boundary>;
1124  static constexpr auto rule(backslash, ctll::term<'b'>) -> ctll::push<ctll::anything, push_word_boundary>;
1125 
1126  static constexpr auto rule(backslash_range, ctll::term<'u'>) -> ctll::push<ctll::anything, k>;
1127  static constexpr auto rule(backslash_range, ctll::term<'x'>) -> ctll::push<ctll::anything, l>;
1128  static constexpr auto rule(backslash_range, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character>;
1129  static constexpr auto rule(backslash_range, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm>;
1130  static constexpr auto rule(backslash_range, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape>;
1131  static constexpr auto rule(backslash_range, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed>;
1132  static constexpr auto rule(backslash_range, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline>;
1133  static constexpr auto rule(backslash_range, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null>;
1134  static constexpr auto rule(backslash_range, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage>;
1135  static constexpr auto rule(backslash_range, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab>;
1136 
1139  static constexpr auto rule(block, ctll::term<'?'>) -> ctll::push<ctll::anything, d>;
1143  static constexpr auto rule(block, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
1147  static constexpr auto rule(block, ctll::term<'\x29'>) -> ctll::push<push_empty, make_capture, ctll::anything>;
1148  static constexpr auto rule(block, ctll::set<'*','+','\x7B','\x7D'>) -> ctll::reject;
1149 
1150  static constexpr auto rule(block_name2, ctll::set<'>','\x7D'>) -> ctll::epsilon;
1151  static constexpr auto rule(block_name2, ctll::set<'0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_name, block_name2>;
1152 
1153  static constexpr auto rule(c, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_start, set2b, set_make, ctll::term<']'>>;
1155  static constexpr auto rule(c, ctll::set<'!','0','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, range, set_start, set2b, set_make, ctll::term<']'>>;
1158  static constexpr auto rule(c, ctll::set<'-',']'>) -> ctll::reject;
1159 
1160  static constexpr auto rule(class_named_name, ctll::term<'x'>) -> ctll::push<ctll::anything, ctll::term<'d'>, ctll::term<'i'>, ctll::term<'g'>, ctll::term<'i'>, ctll::term<'t'>, class_named_xdigit>;
1161  static constexpr auto rule(class_named_name, ctll::term<'d'>) -> ctll::push<ctll::anything, ctll::term<'i'>, ctll::term<'g'>, ctll::term<'i'>, ctll::term<'t'>, class_named_digit>;
1162  static constexpr auto rule(class_named_name, ctll::term<'b'>) -> ctll::push<ctll::anything, ctll::term<'l'>, ctll::term<'a'>, ctll::term<'n'>, ctll::term<'k'>, class_named_blank>;
1163  static constexpr auto rule(class_named_name, ctll::term<'c'>) -> ctll::push<ctll::anything, ctll::term<'n'>, ctll::term<'t'>, ctll::term<'r'>, ctll::term<'l'>, class_named_cntrl>;
1164  static constexpr auto rule(class_named_name, ctll::term<'w'>) -> ctll::push<ctll::anything, ctll::term<'o'>, ctll::term<'r'>, ctll::term<'d'>, class_named_word>;
1165  static constexpr auto rule(class_named_name, ctll::term<'l'>) -> ctll::push<ctll::anything, ctll::term<'o'>, ctll::term<'w'>, ctll::term<'e'>, ctll::term<'r'>, class_named_lower>;
1166  static constexpr auto rule(class_named_name, ctll::term<'s'>) -> ctll::push<ctll::anything, ctll::term<'p'>, ctll::term<'a'>, ctll::term<'c'>, ctll::term<'e'>, class_named_space>;
1167  static constexpr auto rule(class_named_name, ctll::term<'u'>) -> ctll::push<ctll::anything, ctll::term<'p'>, ctll::term<'p'>, ctll::term<'e'>, ctll::term<'r'>, class_named_upper>;
1168  static constexpr auto rule(class_named_name, ctll::term<'g'>) -> ctll::push<ctll::anything, ctll::term<'r'>, ctll::term<'a'>, ctll::term<'p'>, ctll::term<'h'>, class_named_graph>;
1169  static constexpr auto rule(class_named_name, ctll::term<'a'>) -> ctll::push<ctll::anything, g>;
1170  static constexpr auto rule(class_named_name, ctll::term<'p'>) -> ctll::push<ctll::anything, h>;
1171 
1172  static constexpr auto rule(content2, ctll::term<'\x29'>) -> ctll::epsilon;
1173  static constexpr auto rule(content2, ctll::epsilon) -> ctll::epsilon;
1174  static constexpr auto rule(content2, ctll::term<'|'>) -> ctll::push<ctll::anything, a>;
1175 
1177  static constexpr auto rule(content, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
1181  static constexpr auto rule(content, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1182  static constexpr auto rule(content, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1184  static constexpr auto rule(content, ctll::set<'\x29','*','+','?','\x7B','|','\x7D'>) -> ctll::reject;
1185 
1186  static constexpr auto rule(content_in_capture, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2>;
1187  static constexpr auto rule(content_in_capture, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
1189  static constexpr auto rule(content_in_capture, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2>;
1190  static constexpr auto rule(content_in_capture, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2>;
1191  static constexpr auto rule(content_in_capture, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1192  static constexpr auto rule(content_in_capture, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
1194  static constexpr auto rule(content_in_capture, ctll::term<'|'>) -> ctll::push<ctll::anything, push_empty, content, make_alternate>;
1195  static constexpr auto rule(content_in_capture, ctll::term<'\x29'>) -> ctll::push<push_empty>;
1196  static constexpr auto rule(content_in_capture, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject;
1197 
1202  static constexpr auto rule(d, ctll::term<'<'>) -> ctll::push<ctll::anything, o>;
1204  static constexpr auto rule(d, ctll::term<'>'>) -> ctll::push<ctll::anything, reset_capture, start_atomic, content_in_capture, make_atomic, ctll::term<'\x29'>>;
1205  static constexpr auto rule(d, ctll::term<'!'>) -> ctll::push<ctll::anything, reset_capture, start_lookahead_negative, content_in_capture, look_finish, ctll::term<'\x29'>>;
1206  static constexpr auto rule(d, ctll::term<'='>) -> ctll::push<ctll::anything, reset_capture, start_lookahead_positive, content_in_capture, look_finish, ctll::term<'\x29'>>;
1207 
1208  static constexpr auto rule(e, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
1209  static constexpr auto rule(e, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
1210  static constexpr auto rule(e, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
1211  static constexpr auto rule(e, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
1212  static constexpr auto rule(e, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
1213  static constexpr auto rule(e, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
1214  static constexpr auto rule(e, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
1215  static constexpr auto rule(e, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
1216  static constexpr auto rule(e, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
1217  static constexpr auto rule(e, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
1218  static constexpr auto rule(e, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
1219  static constexpr auto rule(e, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
1220  static constexpr auto rule(e, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
1221  static constexpr auto rule(e, ctll::term<'u'>) -> ctll::push<ctll::anything, k, range>;
1222  static constexpr auto rule(e, ctll::term<'x'>) -> ctll::push<ctll::anything, l, range>;
1223  static constexpr auto rule(e, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character, range>;
1224  static constexpr auto rule(e, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm, range>;
1225  static constexpr auto rule(e, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape, range>;
1226  static constexpr auto rule(e, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed, range>;
1227  static constexpr auto rule(e, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline, range>;
1228  static constexpr auto rule(e, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null, range>;
1229  static constexpr auto rule(e, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage, range>;
1230  static constexpr auto rule(e, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab, range>;
1231 
1232  static constexpr auto rule(f, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
1233  static constexpr auto rule(f, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
1234  static constexpr auto rule(f, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
1235  static constexpr auto rule(f, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
1236  static constexpr auto rule(f, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
1237  static constexpr auto rule(f, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
1238  static constexpr auto rule(f, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
1239  static constexpr auto rule(f, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
1240  static constexpr auto rule(f, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
1241  static constexpr auto rule(f, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
1242  static constexpr auto rule(f, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
1243  static constexpr auto rule(f, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
1244  static constexpr auto rule(f, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
1245  static constexpr auto rule(f, ctll::term<'u'>) -> ctll::push<ctll::anything, k, range>;
1246  static constexpr auto rule(f, ctll::term<'x'>) -> ctll::push<ctll::anything, l, range>;
1247  static constexpr auto rule(f, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character, range>;
1248  static constexpr auto rule(f, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm, range>;
1249  static constexpr auto rule(f, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape, range>;
1250  static constexpr auto rule(f, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed, range>;
1251  static constexpr auto rule(f, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline, range>;
1252  static constexpr auto rule(f, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null, range>;
1253  static constexpr auto rule(f, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage, range>;
1254  static constexpr auto rule(f, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab, range>;
1255 
1256  static constexpr auto rule(g, ctll::term<'s'>) -> ctll::push<ctll::anything, ctll::term<'c'>, ctll::term<'i'>, ctll::term<'i'>, class_named_ascii>;
1257  static constexpr auto rule(g, ctll::term<'l'>) -> ctll::push<ctll::anything, p>;
1258 
1259  static constexpr auto rule(h, ctll::term<'r'>) -> ctll::push<ctll::anything, ctll::term<'i'>, ctll::term<'n'>, ctll::term<'t'>, class_named_print>;
1260  static constexpr auto rule(h, ctll::term<'u'>) -> ctll::push<ctll::anything, ctll::term<'n'>, ctll::term<'c'>, ctll::term<'t'>, class_named_punct>;
1261 
1262  static constexpr auto rule(hexdec_repeat, ctll::term<'\x7D'>) -> ctll::epsilon;
1263  static constexpr auto rule(hexdec_repeat, ctll::set<'0','A','B','C','D','E','F','a','b','c','d','e','f','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_hexdec, hexdec_repeat>;
1264 
1265  static constexpr auto rule(i, ctll::term<'^'>) -> ctll::push<ctll::anything, class_named_name, negate_class_named, ctll::term<':'>, ctll::term<']'>>;
1266  static constexpr auto rule(i, ctll::term<'x'>) -> ctll::push<ctll::anything, ctll::term<'d'>, ctll::term<'i'>, ctll::term<'g'>, ctll::term<'i'>, ctll::term<'t'>, class_named_xdigit, ctll::term<':'>, ctll::term<']'>>;
1267  static constexpr auto rule(i, ctll::term<'d'>) -> ctll::push<ctll::anything, ctll::term<'i'>, ctll::term<'g'>, ctll::term<'i'>, ctll::term<'t'>, class_named_digit, ctll::term<':'>, ctll::term<']'>>;
1268  static constexpr auto rule(i, ctll::term<'b'>) -> ctll::push<ctll::anything, ctll::term<'l'>, ctll::term<'a'>, ctll::term<'n'>, ctll::term<'k'>, class_named_blank, ctll::term<':'>, ctll::term<']'>>;
1269  static constexpr auto rule(i, ctll::term<'c'>) -> ctll::push<ctll::anything, ctll::term<'n'>, ctll::term<'t'>, ctll::term<'r'>, ctll::term<'l'>, class_named_cntrl, ctll::term<':'>, ctll::term<']'>>;
1270  static constexpr auto rule(i, ctll::term<'w'>) -> ctll::push<ctll::anything, ctll::term<'o'>, ctll::term<'r'>, ctll::term<'d'>, class_named_word, ctll::term<':'>, ctll::term<']'>>;
1271  static constexpr auto rule(i, ctll::term<'l'>) -> ctll::push<ctll::anything, ctll::term<'o'>, ctll::term<'w'>, ctll::term<'e'>, ctll::term<'r'>, class_named_lower, ctll::term<':'>, ctll::term<']'>>;
1272  static constexpr auto rule(i, ctll::term<'s'>) -> ctll::push<ctll::anything, ctll::term<'p'>, ctll::term<'a'>, ctll::term<'c'>, ctll::term<'e'>, class_named_space, ctll::term<':'>, ctll::term<']'>>;
1273  static constexpr auto rule(i, ctll::term<'u'>) -> ctll::push<ctll::anything, ctll::term<'p'>, ctll::term<'p'>, ctll::term<'e'>, ctll::term<'r'>, class_named_upper, ctll::term<':'>, ctll::term<']'>>;
1274  static constexpr auto rule(i, ctll::term<'g'>) -> ctll::push<ctll::anything, ctll::term<'r'>, ctll::term<'a'>, ctll::term<'p'>, ctll::term<'h'>, class_named_graph, ctll::term<':'>, ctll::term<']'>>;
1275  static constexpr auto rule(i, ctll::term<'a'>) -> ctll::push<ctll::anything, g, ctll::term<':'>, ctll::term<']'>>;
1276  static constexpr auto rule(i, ctll::term<'p'>) -> ctll::push<ctll::anything, h, ctll::term<':'>, ctll::term<']'>>;
1277 
1278  static constexpr auto rule(j, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash_range, make_range>;
1279  static constexpr auto rule(j, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, make_range>;
1280  static constexpr auto rule(j, _others) -> ctll::push<ctll::anything, push_character, make_range>;
1281  static constexpr auto rule(j, ctll::set<'-','[',']'>) -> ctll::reject;
1282 
1283  static constexpr auto rule(k, ctll::term<'\x7B'>) -> ctll::push<create_hexdec, ctll::anything, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, hexdec_repeat, ctll::term<'\x7D'>, finish_hexdec>;
1284  static constexpr auto rule(k, ctll::set<'0','A','B','C','D','E','F','a','b','c','d','e','f','1','2','3','4','5','6','7','8','9'>) -> ctll::push<create_hexdec, ctll::anything, push_hexdec, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, finish_hexdec>;
1285 
1286  static constexpr auto rule(l, ctll::term<'\x7B'>) -> ctll::push<create_hexdec, ctll::anything, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, hexdec_repeat, ctll::term<'\x7D'>, finish_hexdec>;
1287  static constexpr auto rule(l, ctll::set<'0','A','B','C','D','E','F','a','b','c','d','e','f','1','2','3','4','5','6','7','8','9'>) -> ctll::push<create_hexdec, ctll::anything, push_hexdec, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>, push_hexdec, finish_hexdec>;
1288 
1289  static constexpr auto rule(m, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, number2, ctll::term<'\x7D'>, make_back_reference>;
1290  static constexpr auto rule(m, ctll::term<'-'>) -> ctll::push<ctll::anything, number, ctll::term<'\x7D'>, make_relative_back_reference>;
1291  static constexpr auto rule(m, ctll::set<'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'>) -> ctll::push<ctll::anything, push_name, block_name2, ctll::term<'\x7D'>, make_back_reference>;
1292 
1293  static constexpr auto rule(mod, ctll::set<'!','$','\x28','\x29',',','-','.','/','0',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon;
1294  static constexpr auto rule(mod, ctll::epsilon) -> ctll::epsilon;
1295  static constexpr auto rule(mod, _others) -> ctll::epsilon;
1296  static constexpr auto rule(mod, ctll::term<'?'>) -> ctll::push<ctll::anything, make_lazy>;
1297  static constexpr auto rule(mod, ctll::term<'+'>) -> ctll::push<ctll::anything, make_possessive>;
1298  static constexpr auto rule(mod, ctll::set<'*','\x7B','\x7D'>) -> ctll::reject;
1299 
1300  static constexpr auto rule(mode_switch2, ctll::term<'i'>) -> ctll::push<ctll::anything, mode_case_insensitive, mode_switch2>;
1301  static constexpr auto rule(mode_switch2, ctll::term<'c'>) -> ctll::push<ctll::anything, mode_case_sensitive, mode_switch2>;
1302  static constexpr auto rule(mode_switch2, ctll::term<'m'>) -> ctll::push<ctll::anything, mode_multiline, mode_switch2>;
1303  static constexpr auto rule(mode_switch2, ctll::term<'s'>) -> ctll::push<ctll::anything, mode_singleline, mode_switch2>;
1304  static constexpr auto rule(mode_switch2, ctll::term<'\x29'>) -> ctll::push<ctll::anything>;
1305 
1306  static constexpr auto rule(n, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, number2, repeat_ab, ctll::term<'\x7D'>, mod>;
1307  static constexpr auto rule(n, ctll::term<'\x7D'>) -> ctll::push<repeat_at_least, ctll::anything, mod>;
1308 
1309  static constexpr auto rule(number2, ctll::set<',','\x7D'>) -> ctll::epsilon;
1310  static constexpr auto rule(number2, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_number, number2>;
1311 
1312  static constexpr auto rule(number, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, number2>;
1313 
1314  static constexpr auto rule(o, ctll::set<'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'>) -> ctll::push<ctll::anything, push_name, block_name2, ctll::term<'>'>, content_in_capture, make_capture_with_name, ctll::term<'\x29'>>;
1315  static constexpr auto rule(o, ctll::term<'!'>) -> ctll::push<ctll::anything, reset_capture, start_lookbehind_negative, content_in_capture, look_finish, ctll::term<'\x29'>>;
1316  static constexpr auto rule(o, ctll::term<'='>) -> ctll::push<ctll::anything, reset_capture, start_lookbehind_positive, content_in_capture, look_finish, ctll::term<'\x29'>>;
1317 
1318  static constexpr auto rule(p, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'h'>, ctll::term<'a'>, class_named_alpha>;
1319  static constexpr auto rule(p, ctll::term<'n'>) -> ctll::push<ctll::anything, ctll::term<'u'>, ctll::term<'m'>, class_named_alnum>;
1320 
1321  static constexpr auto rule(property_name2, ctll::term<'\x7D'>) -> ctll::epsilon;
1322  static constexpr auto rule(property_name2, ctll::term<'='>) -> ctll::push<ctll::anything, property_value>;
1323  static constexpr auto rule(property_name2, ctll::set<'0','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_property_name, property_name2>;
1324 
1325  static constexpr auto rule(property_name, ctll::set<'0','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_property_name, property_name2>;
1326 
1327  static constexpr auto rule(property_value2, ctll::term<'\x7D'>) -> ctll::epsilon;
1328  static constexpr auto rule(property_value2, ctll::set<'0','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_property_value, property_value2>;
1329 
1330  static constexpr auto rule(property_value, ctll::set<'0','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_property_value, property_value2>;
1331 
1332  static constexpr auto rule(range, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon;
1333  static constexpr auto rule(range, ctll::epsilon) -> ctll::epsilon;
1334  static constexpr auto rule(range, _others) -> ctll::epsilon;
1335  static constexpr auto rule(range, ctll::term<'-'>) -> ctll::push<ctll::anything, j>;
1336 
1337  static constexpr auto rule(repeat, ctll::set<'!','$','\x28','\x29',',','-','.','/','0',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon;
1338  static constexpr auto rule(repeat, ctll::epsilon) -> ctll::epsilon;
1339  static constexpr auto rule(repeat, _others) -> ctll::epsilon;
1340  static constexpr auto rule(repeat, ctll::term<'?'>) -> ctll::push<ctll::anything, make_optional, mod>;
1341  static constexpr auto rule(repeat, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, b>;
1342  static constexpr auto rule(repeat, ctll::term<'+'>) -> ctll::push<ctll::anything, repeat_plus, mod>;
1343  static constexpr auto rule(repeat, ctll::term<'*'>) -> ctll::push<ctll::anything, repeat_star, mod>;
1344  static constexpr auto rule(repeat, ctll::term<'\x7D'>) -> ctll::reject;
1345 
1346  static constexpr auto rule(set2a, ctll::term<']'>) -> ctll::epsilon;
1347  static constexpr auto rule(set2a, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_start, set2b>;
1348  static constexpr auto rule(set2a, ctll::term<'\\'>) -> ctll::push<ctll::anything, f, set_start, set2b>;
1349  static constexpr auto rule(set2a, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, range, set_start, set2b>;
1350  static constexpr auto rule(set2a, _others) -> ctll::push<ctll::anything, push_character, range, set_start, set2b>;
1351  static constexpr auto rule(set2a, ctll::term<'-'>) -> ctll::reject;
1352 
1353  static constexpr auto rule(set2b, ctll::term<']'>) -> ctll::epsilon;
1354  static constexpr auto rule(set2b, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_combine, set2b>;
1355  static constexpr auto rule(set2b, ctll::term<'\\'>) -> ctll::push<ctll::anything, f, set_combine, set2b>;
1356  static constexpr auto rule(set2b, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, range, set_combine, set2b>;
1357  static constexpr auto rule(set2b, _others) -> ctll::push<ctll::anything, push_character, range, set_combine, set2b>;
1358  static constexpr auto rule(set2b, ctll::term<'-'>) -> ctll::reject;
1359 
1360  static constexpr auto rule(string2, ctll::set<'\x29','|'>) -> ctll::epsilon;
1361  static constexpr auto rule(string2, ctll::epsilon) -> ctll::epsilon;
1362  static constexpr auto rule(string2, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, make_sequence>;
1363  static constexpr auto rule(string2, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, make_sequence>;
1364  static constexpr auto rule(string2, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, make_sequence>;
1365  static constexpr auto rule(string2, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, make_sequence>;
1366  static constexpr auto rule(string2, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, make_sequence>;
1367  static constexpr auto rule(string2, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_character, repeat, string2, make_sequence>;
1368  static constexpr auto rule(string2, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, make_sequence>;
1369  static constexpr auto rule(string2, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, make_sequence>;
1370  static constexpr auto rule(string2, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject;
1371 
1372 };
1373 
1374 }
1375 
1376 #endif //CTRE__PCRE__HPP
1377 
1378 #ifndef CTRE__ROTATE__HPP
1379 #define CTRE__ROTATE__HPP
1380 
1381 #ifndef CTRE__ATOMS__HPP
1382 #define CTRE__ATOMS__HPP
1383 
1384 #ifndef CTRE__ATOMS_CHARACTERS__HPP
1385 #define CTRE__ATOMS_CHARACTERS__HPP
1386 
1387 #ifndef CTRE__UTILITY__HPP
1388 #define CTRE__UTILITY__HPP
1389 
1390 #define CTRE_CNTTP_COMPILER_CHECK CTLL_CNTTP_COMPILER_CHECK
1391 
1392 #if __GNUC__ > 9
1393 #if __has_cpp_attribute(likely)
1394 #define CTRE_LIKELY [[likely]]
1395 #else
1396 #define CTRE_LIKELY
1397 #endif
1398 
1399 #if __has_cpp_attribute(unlikely)
1400 #define CTRE_UNLIKELY [[unlikely]]
1401 #else
1402 #define CTRE_UNLIKELY
1403 #endif
1404 #else
1405 #define CTRE_LIKELY
1406 #define CTRE_UNLIKELY
1407 #endif
1408 
1409 #ifdef _MSC_VER
1410 #define CTRE_FORCE_INLINE __forceinline
1411 #if _MSC_VER >= 1930
1412 #define CTRE_FLATTEN [[msvc::flatten]]
1413 #else
1414 #define CTRE_FLATTEN
1415 #endif
1416 #else
1417 #define CTRE_FORCE_INLINE inline __attribute__((always_inline))
1418 #define CTRE_FLATTEN __attribute__((flatten))
1419 #endif
1420 
1421 #endif
1422 
1423 #ifndef CTRE_V2__CTRE__FLAGS_AND_MODES__HPP
1424 #define CTRE_V2__CTRE__FLAGS_AND_MODES__HPP
1425 
1426 namespace ctre {
1427 
1428 struct singleline { };
1429 struct multiline { };
1430 
1431 struct case_sensitive { };
1432 struct case_insensitive { };
1433 
1434 using ci = case_insensitive;
1435 using cs = case_sensitive;
1436 
1437 template <typename... Flags> struct flag_list { };
1438 
1439 struct flags {
1440  bool block_empty_match = false;
1441  bool multiline = false;
1442  bool case_insensitive = false;
1443 
1444  constexpr flags() = default;
1445  constexpr flags(const flags &) = default;
1446  constexpr flags(flags &&) = default;
1447 
1448  constexpr CTRE_FORCE_INLINE flags(ctre::singleline v) noexcept { set_flag(v); }
1449  constexpr CTRE_FORCE_INLINE flags(ctre::multiline v) noexcept { set_flag(v); }
1450  constexpr CTRE_FORCE_INLINE flags(ctre::case_sensitive v) noexcept { set_flag(v); }
1451  constexpr CTRE_FORCE_INLINE flags(ctre::case_insensitive v) noexcept { set_flag(v); }
1452 
1453 
1454  template <typename... Args> constexpr CTRE_FORCE_INLINE flags(ctll::list<Args...>) noexcept {
1455  (this->set_flag(Args{}), ...);
1456  }
1457 
1458  constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_insensitive) noexcept {
1459  f.case_insensitive = true;
1460  return f;
1461  }
1462 
1463  constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_sensitive) noexcept {
1464  f.case_insensitive = false;
1465  return f;
1466  }
1467 
1468  constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_singleline) noexcept {
1469  f.multiline = false;
1470  return f;
1471  }
1472 
1473  constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_multiline) noexcept {
1474  f.multiline = true;
1475  return f;
1476  }
1477 
1478  constexpr CTRE_FORCE_INLINE void set_flag(ctre::singleline) noexcept {
1479  multiline = false;
1480  }
1481 
1482  constexpr CTRE_FORCE_INLINE void set_flag(ctre::multiline) noexcept {
1483  multiline = true;
1484  }
1485 
1486  constexpr CTRE_FORCE_INLINE void set_flag(ctre::case_insensitive) noexcept {
1487  case_insensitive = true;
1488  }
1489 
1490  constexpr CTRE_FORCE_INLINE void set_flag(ctre::case_sensitive) noexcept {
1491  case_insensitive = false;
1492  }
1493 };
1494 
1495 constexpr CTRE_FORCE_INLINE auto not_empty_match(flags f) {
1496  f.block_empty_match = true;
1497  return f;
1498 }
1499 
1500 constexpr CTRE_FORCE_INLINE auto consumed_something(flags f, bool condition = true) {
1501  if (condition) f.block_empty_match = false;
1502  return f;
1503 }
1504 
1505 constexpr CTRE_FORCE_INLINE bool cannot_be_empty_match(flags f) {
1506  return f.block_empty_match;
1507 }
1508 
1509 constexpr CTRE_FORCE_INLINE bool multiline_mode(flags f) {
1510  return f.multiline;
1511 }
1512 
1513 constexpr CTRE_FORCE_INLINE bool is_case_insensitive(flags f) {
1514  return f.case_insensitive;
1515 }
1516 
1517 } // namespace ctre
1518 
1519 #endif
1520 #include <cstdint>
1521 
1522 namespace ctre {
1523 
1524 // sfinae check for types here
1525 
1526 template <typename T> class MatchesCharacter {
1527  template <typename Y, typename CharT> static auto test(CharT c) -> decltype(Y::match_char(c, std::declval<const flags &>()), std::true_type());
1528  template <typename> static auto test(...) -> std::false_type;
1529 public:
1530  template <typename CharT> static inline constexpr bool value = decltype(test<T>(std::declval<CharT>()))();
1531 };
1532 
1533 template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha(T v) {
1534  return ((v >= static_cast<T>('a') && v <= static_cast<T>('z')) || (v >= static_cast<T>('A') && v <= static_cast<T>('Z')));
1535 }
1536 
1537 template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha_lowercase(T v) {
1538  return (v >= static_cast<T>('a')) && (v <= static_cast<T>('z'));
1539 }
1540 
1541 template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha_uppercase(T v) {
1542  return (v >= static_cast<T>('A')) && v <= (static_cast<T>('Z'));
1543 }
1544 
1545 template <auto V> struct character {
1546  template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
1547  if constexpr (is_ascii_alpha(V)) {
1548  if (is_case_insensitive(f)) {
1549  if (value == (V ^ static_cast<decltype(V)>(0x20))) {
1550  return true;//
1551  }
1552  }
1553  }
1554  return value == V;
1555  }
1556 };
1557 
1558 template <typename... Content> struct negative_set {
1559  template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
1560  return !(Content::match_char(value, f) || ... || false);
1561  }
1562 };
1563 
1564 template <typename... Content> struct set {
1565  template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
1566  return (Content::match_char(value, f) || ... || false);
1567  }
1568 };
1569 
1570 template <auto... Cs> struct enumeration : set<character<Cs>...> { };
1571 
1572 template <typename... Content> struct negate {
1573  template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
1574  return !(Content::match_char(value, f) || ... || false);
1575  }
1576 };
1577 
1578 template <auto A, auto B> struct char_range {
1579  template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
1580  if constexpr (is_ascii_alpha_lowercase(A) && is_ascii_alpha_lowercase(B)) {
1581  if (is_case_insensitive(f)) {
1582  if (value >= (A ^ static_cast<decltype(A)>(0x20)) && value <= (B ^ static_cast<decltype(B)>(0x20))) {
1583  return true;//
1584  }
1585  }
1586  } else if constexpr (is_ascii_alpha_uppercase(A) && is_ascii_alpha_uppercase(B)) {
1587  if (is_case_insensitive(f)) {
1588  if (value >= (A ^ static_cast<decltype(A)>(0x20)) && value <= (B ^ static_cast<decltype(B)>(0x20))) {
1589  return true;//
1590  }
1591  }
1592  }
1593  return (value >= A) && (value <= B);
1594  }
1595 };
1596 using word_chars = set<char_range<'A','Z'>, char_range<'a','z'>, char_range<'0','9'>, character<'_'> >;
1597 
1598 using space_chars = enumeration<' ', '\t', '\n', '\v', '\f', '\r'>;
1599 
1600 using vertical_space_chars = enumeration<
1601  char{0x000A}, // Linefeed (LF)
1602  char{0x000B}, // Vertical tab (VT)
1603  char{0x000C}, // Form feed (FF)
1604  char{0x000D}, // Carriage return (CR)
1605  char32_t{0x0085}, // Next line (NEL)
1606  char32_t{0x2028}, // Line separator
1607  char32_t{0x2029} // Paragraph separator
1608 >;
1609 
1610 using horizontal_space_chars = enumeration<
1611  char{0x0009}, // Horizontal tab (HT)
1612  char{0x0020}, // Space
1613  char32_t{0x00A0}, // Non-break space
1614  char32_t{0x1680}, // Ogham space mark
1615  char32_t{0x180E}, // Mongolian vowel separator
1616  char32_t{0x2000}, // En quad
1617  char32_t{0x2001}, // Em quad
1618  char32_t{0x2002}, // En space
1619  char32_t{0x2003}, // Em space
1620  char32_t{0x2004}, // Three-per-em space
1621  char32_t{0x2005}, // Four-per-em space
1622  char32_t{0x2006}, // Six-per-em space
1623  char32_t{0x2007}, // Figure space
1624  char32_t{0x2008}, // Punctuation space
1625  char32_t{0x2009}, // Thin space
1626  char32_t{0x200A}, // Hair space
1627  char32_t{0x202F}, // Narrow no-break space
1628  char32_t{0x205F}, // Medium mathematical space
1629  char32_t{0x3000} // Ideographic space
1630 >;
1631 
1632 using alphanum_chars = set<char_range<'A','Z'>, char_range<'a','z'>, char_range<'0','9'> >;
1633 
1634 using alpha_chars = set<char_range<'A','Z'>, char_range<'a','z'> >;
1635 
1636 using xdigit_chars = set<char_range<'A','F'>, char_range<'a','f'>, char_range<'0','9'> >;
1637 
1638 using punct_chars
1639  = enumeration<'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
1640  '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']',
1641  '^', '_', '`', '{', '|', '}', '~'>;
1642 
1643 using digit_chars = char_range<'0','9'>;
1644 
1645 using ascii_chars = char_range<'\x00','\x7F'>;
1646 
1647 }
1648 
1649 #endif
1650 
1651 #include <cstdint>
1652 
1653 namespace ctre {
1654 
1655 // special helpers for matching
1656 struct accept { };
1657 struct reject { };
1658 struct start_mark { };
1659 struct end_mark { };
1660 struct end_cycle_mark { };
1661 struct end_lookahead_mark { };
1662 struct end_lookbehind_mark { };
1663 template <size_t Id> struct numeric_mark { };
1664 
1665 struct any { };
1666 
1667 // actual AST of regexp
1668 template <auto... Str> struct string { };
1669 template <typename... Opts> struct select { };
1670 template <typename... Content> struct sequence { };
1671 struct empty { };
1672 
1673 template <size_t a, size_t b, typename... Content> struct repeat { };
1674 template <typename... Content> using plus = repeat<1,0,Content...>;
1675 template <typename... Content> using star = repeat<0,0,Content...>;
1676 
1677 template <size_t a, size_t b, typename... Content> struct lazy_repeat { };
1678 template <typename... Content> using lazy_plus = lazy_repeat<1,0,Content...>;
1679 template <typename... Content> using lazy_star = lazy_repeat<0,0,Content...>;
1680 
1681 template <size_t a, size_t b, typename... Content> struct possessive_repeat { };
1682 template <typename... Content> using possessive_plus = possessive_repeat<1,0,Content...>;
1683 template <typename... Content> using possessive_star = possessive_repeat<0,0,Content...>;
1684 
1685 template <typename... Content> using optional = repeat<0,1,Content...>;
1686 template <typename... Content> using lazy_optional = lazy_repeat<0,1,Content...>;
1687 template <typename... Content> using possessive_optional = possessive_repeat<0,1,Content...>;
1688 
1689 template <size_t Index, typename... Content> struct capture { };
1690 
1691 template <size_t Index, typename Name, typename... Content> struct capture_with_name { };
1692 
1693 template <size_t Index> struct back_reference { };
1694 template <typename Name> struct back_reference_with_name { };
1695 
1696 template <typename Type> struct look_start { };
1697 
1698 template <typename... Content> struct lookahead_positive { };
1699 template <typename... Content> struct lookahead_negative { };
1700 
1701 template <typename... Content> struct lookbehind_positive { };
1702 template <typename... Content> struct lookbehind_negative { };
1703 
1704 struct atomic_start { };
1705 
1706 template <typename... Content> struct atomic_group { };
1707 
1708 template <typename... Content> struct boundary { };
1709 template <typename... Content> struct not_boundary { };
1710 
1711 using word_boundary = boundary<word_chars>;
1712 using not_word_boundary = not_boundary<word_chars>;
1713 
1714 struct assert_subject_begin { };
1715 struct assert_subject_end { };
1716 struct assert_subject_end_line{ };
1717 struct assert_line_begin { };
1718 struct assert_line_end { };
1719 
1720 template <typename> struct mode_switch { };
1721 
1722 }
1723 
1724 #endif
1725 
1726 #ifndef CTRE__ATOMS_UNICODE__HPP
1727 #define CTRE__ATOMS_UNICODE__HPP
1728 
1729 // master branch is not including unicode db (for now)
1730 #ifndef H_COR3NTIN_UNICODE_SYNOPSYS
1731 #define H_COR3NTIN_UNICODE_SYNOPSYS
1732 
1733 #include <string_view>
1734 
1735 namespace uni
1736 {
1737  enum class category;
1738  enum class property;
1739  enum class version : unsigned char;
1740  enum class script ;
1741  enum class block;
1742 
1743  struct script_extensions_view {
1744  constexpr script_extensions_view(char32_t);
1745 
1746  struct sentinel {};
1747  struct iterator {
1748 
1749  constexpr iterator(char32_t c);
1750  constexpr script operator*() const;
1751 
1752  constexpr iterator& operator++(int);
1753 
1754  constexpr iterator operator++();
1755 
1756  constexpr bool operator==(sentinel) const;
1757  constexpr bool operator!=(sentinel) const;
1758 
1759  private:
1760  char32_t m_c;
1761  script m_script;
1762  int idx = 1;
1763  };
1764 
1765  constexpr iterator begin() const;
1766  constexpr sentinel end() const;
1767 
1768  private:
1769  char32_t c;
1770  };
1771 
1772  struct numeric_value {
1773 
1774  constexpr double value() const;
1775  constexpr long long numerator() const;
1776  constexpr int denominator() const;
1777  constexpr bool is_valid() const;
1778 
1779  protected:
1780  constexpr numeric_value() = default;
1781  constexpr numeric_value(long long n, int16_t d);
1782 
1783  long long _n = 0;
1784  int16_t _d = 0;
1785  friend constexpr numeric_value cp_numeric_value(char32_t cp);
1786  };
1787 
1788  constexpr category cp_category(char32_t cp);
1789  constexpr script cp_script(char32_t cp);
1790  constexpr script_extensions_view cp_script_extensions(char32_t cp);
1791  constexpr version cp_age(char32_t cp);
1792  constexpr block cp_block(char32_t cp);
1793  constexpr bool cp_is_valid(char32_t cp);
1794  constexpr bool cp_is_assigned(char32_t cp);
1795  constexpr bool cp_is_ascii(char32_t cp);
1796  constexpr numeric_value cp_numeric_value(char32_t cp);
1797 
1798  template<script>
1799  constexpr bool cp_script_is(char32_t);
1800  template<property>
1801  constexpr bool cp_property_is(char32_t);
1802  template<category>
1803  constexpr bool cp_category_is(char32_t);
1804 
1805  namespace detail
1806  {
1807  enum class binary_prop;
1808  constexpr int propnamecomp(std::string_view sa, std::string_view sb);
1809  constexpr binary_prop binary_prop_from_string(std::string_view s);
1810 
1811  template<binary_prop p>
1812  constexpr bool get_binary_prop(char32_t) = delete;
1813 
1814  constexpr script script_from_string(std::string_view s);
1815  constexpr block block_from_string(std::string_view s);
1816  constexpr version age_from_string(std::string_view a);
1817  constexpr category category_from_string(std::string_view a);
1818 
1819  constexpr bool is_unassigned(category cat);
1820  constexpr bool is_unknown(script s);
1821  constexpr bool is_unknown(block b);
1822  constexpr bool is_unassigned(version v);
1823  constexpr bool is_unknown(binary_prop s);
1824  }
1825 }
1826 
1827 #endif
1828 
1829 namespace ctre {
1830 
1831 // properties name & value
1832 
1833 template <auto... Str> struct property_name { };
1834 template <auto... Str> struct property_value { };
1835 
1836 template <size_t Sz> constexpr std::string_view get_string_view(const char (& arr)[Sz]) noexcept {
1837  return std::string_view(arr, Sz);
1838 }
1839 
1840 // basic support for binary and type-value properties
1841 
1842 template <typename T, T Type> struct binary_property;
1843 template <typename T, T Type, auto Value> struct property;
1844 
1845 template <auto Type> using make_binary_property = binary_property<std::remove_const_t<decltype(Type)>, Type>;
1846 template <auto Type, auto Value> using make_property = property<std::remove_const_t<decltype(Type)>, Type, Value>;
1847 
1848 // unicode TS#18 level 1.2 general_category
1849 template <uni::detail::binary_prop Property> struct binary_property<uni::detail::binary_prop, Property> {
1850  template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
1851  return uni::detail::get_binary_prop<Property>(static_cast<char32_t>(c));
1852  }
1853 };
1854 
1855 // unicode TS#18 level 1.2.2
1856 
1857 enum class property_type {
1858  script, script_extension, age, block, unknown
1859 };
1860 
1861 // unicode TS#18 level 1.2.2
1862 
1863 template <uni::script Script> struct binary_property<uni::script, Script> {
1864  template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
1865  return uni::cp_script(c) == Script;
1866  }
1867 };
1868 
1869 template <uni::script Script> struct property<property_type, property_type::script_extension, Script> {
1870  template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
1871  for (uni::script sc: uni::cp_script_extensions(c)) {
1872  if (sc == Script) return true;
1873  }
1874  return false;
1875  }
1876 };
1877 
1878 template <uni::version Age> struct binary_property<uni::version, Age> {
1879  template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
1880  return uni::cp_age(c) <= Age;
1881  }
1882 };
1883 
1884 template <uni::block Block> struct binary_property<uni::block, Block> {
1885  template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
1886  return uni::cp_block(c) == Block;
1887  }
1888 };
1889 
1890 // nonbinary properties
1891 
1892 template <typename = void> // Make it always a template as propnamecomp isn't defined yet
1893 constexpr property_type property_type_from_name(std::string_view str) noexcept {
1894  using namespace std::string_view_literals;
1895  if (uni::detail::propnamecomp(str, "script"sv) == 0 || uni::detail::propnamecomp(str, "sc"sv) == 0) {
1896  return property_type::script;
1897  } else if (uni::detail::propnamecomp(str, "script_extension"sv) == 0 || uni::detail::propnamecomp(str, "scx"sv) == 0) {
1898  return property_type::script_extension;
1899  } else if (uni::detail::propnamecomp(str, "age"sv) == 0) {
1900  return property_type::age;
1901  } else if (uni::detail::propnamecomp(str, "block"sv) == 0) {
1902  return property_type::block;
1903  } else {
1904  return property_type::unknown;
1905  }
1906 }
1907 
1908 template <property_type Property> struct property_type_builder {
1909  template <auto... Value> static constexpr auto get() {
1910  return ctll::reject{};
1911  }
1912 };
1913 
1914 template <auto... Name> struct property_builder {
1915  static constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
1916  static constexpr property_type type = property_type_from_name(get_string_view(name));
1917 
1918  using helper = property_type_builder<type>;
1919 
1920  template <auto... Value> static constexpr auto get() {
1921  return helper::template get<Value...>();
1922  }
1923 };
1924 
1925 // unicode TS#18 level 1.2.2 script support
1926 
1927 template <> struct property_type_builder<property_type::script> {
1928  template <auto... Value> static constexpr auto get() {
1929  constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
1930  constexpr auto sc = uni::detail::script_from_string(get_string_view(value));
1931  if constexpr (uni::detail::is_unknown(sc)) {
1932  return ctll::reject{};
1933  } else {
1934  return make_binary_property<sc>();
1935  }
1936  }
1937 };
1938 
1939 template <> struct property_type_builder<property_type::script_extension> {
1940  template <auto... Value> static constexpr auto get() {
1941  constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
1942  constexpr auto sc = uni::detail::script_from_string(get_string_view(value));
1943  if constexpr (uni::detail::is_unknown(sc)) {
1944  return ctll::reject{};
1945  } else {
1946  return make_property<property_type::script_extension, sc>();
1947  }
1948  }
1949 };
1950 
1951 template <> struct property_type_builder<property_type::age> {
1952  template <auto... Value> static constexpr auto get() {
1953  constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
1954  constexpr auto age = uni::detail::age_from_string(get_string_view(value));
1955  if constexpr (uni::detail::is_unassigned(age)) {
1956  return ctll::reject{};
1957  } else {
1958  return make_binary_property<age>();
1959  }
1960  }
1961 };
1962 
1963 template <> struct property_type_builder<property_type::block> {
1964  template <auto... Value> static constexpr auto get() {
1965  constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
1966  constexpr auto block = uni::detail::block_from_string(get_string_view(value));
1967  if constexpr (uni::detail::is_unknown(block)) {
1968  return ctll::reject{};
1969  } else {
1970  return make_binary_property<block>();
1971  }
1972  }
1973 };
1974 
1975 }
1976 
1977 #endif
1978 
1979 namespace ctre {
1980 
1981 // helper functions
1982 template <size_t Index, typename... Content> auto convert_to_capture(ctll::list<Content...>) -> capture<Index, Content...>;
1983 template <size_t Index, typename Name, typename... Content> auto convert_to_named_capture(ctll::list<Content...>) -> capture_with_name<Index, Name, Content...>;
1984 template <template <size_t, size_t, typename...> typename CycleType, size_t A, size_t B, typename... Content> auto convert_to_repeat(ctll::list<Content...>) -> CycleType<A, B, Content...>;
1985 template <template <typename...> typename ListType, typename... Content> auto convert_to_basic_list(ctll::list<Content...>) -> ListType<Content...>;
1986 
1987 template <auto V> struct rotate_value {
1988  template <auto... Vs> friend constexpr auto operator+(string<Vs...>, rotate_value<V>) noexcept -> string<V, Vs...> { return {}; }
1989 };
1990 
1991 struct rotate_for_lookbehind {
1992 
1993 // from atoms_characters.hpp
1994 template <auto V> static auto rotate(character<V>) -> character<V>;
1995 template <typename... Content> static auto rotate(negative_set<Content...>) -> negative_set<Content...>;
1996 template <typename... Content> static auto rotate(set<Content...>) -> set<Content...>;
1997 template <auto... Cs> static auto rotate(enumeration<Cs...>) -> enumeration<Cs...>;
1998 template <typename... Content> static auto rotate(negate<Content...>) -> negate<Content...>;
1999 template <auto A, auto B> static auto rotate(char_range<A,B>) -> char_range<A,B>;
2000 
2001 // from atoms_unicode.hpp
2002 template <auto... Str> static auto rotate(property_name<Str...>) -> property_name<Str...>;
2003 template <auto... Str> static auto rotate(property_value<Str...>) -> property_value<Str...>;
2004 template <typename T, T Type> static auto rotate(binary_property<T, Type>) -> binary_property<T, Type>;
2005 template <typename T, T Type, auto Value> static auto rotate(property<T, Type, Value>) -> property<T, Type, Value>;
2006 
2007 // from atoms.hpp
2008 static auto rotate(accept) -> accept;
2009 static auto rotate(reject) -> reject;
2010 static auto rotate(start_mark) -> start_mark;
2011 static auto rotate(end_mark) -> end_mark;
2012 static auto rotate(end_cycle_mark) -> end_cycle_mark;
2013 static auto rotate(end_lookahead_mark) -> end_lookahead_mark;
2014 static auto rotate(end_lookbehind_mark) -> end_lookbehind_mark;
2015 template <size_t Id> static auto rotate(numeric_mark<Id>) -> numeric_mark<Id>;
2016 static auto rotate(any) -> any;
2017 
2018 template <typename... Content> static auto rotate(select<Content...>) -> select<Content...>;
2019 static auto rotate(empty) -> empty;
2020 
2021 template <size_t a, size_t b, typename... Content> static auto rotate(repeat<a,b,Content...>) -> decltype(ctre::convert_to_repeat<repeat, a, b>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{})));
2022 template <size_t a, size_t b, typename... Content> static auto rotate(lazy_repeat<a,b,Content...>) -> decltype(ctre::convert_to_repeat<lazy_repeat, a, b>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{})));
2023 template <size_t a, size_t b, typename... Content> static auto rotate(possessive_repeat<a,b,Content...>) -> decltype(ctre::convert_to_repeat<possessive_repeat, a, b>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{})));
2024 
2025 template <size_t Index, typename... Content> static auto rotate(capture<Index, Content...>) {
2026  return ctre::convert_to_capture<Index>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
2027 }
2028 
2029 template <size_t Index, typename Name, typename... Content> static auto rotate(capture_with_name<Index, Name, Content...>) {
2030  return ctre::convert_to_named_capture<Index, Name>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
2031 }
2032 
2033 template <size_t Index> static auto rotate(back_reference<Index>) -> back_reference<Index>;
2034 template <typename Name> static auto rotate(back_reference_with_name<Name>) -> back_reference_with_name<Name>;
2035 
2036 template <typename... Content> static auto rotate(look_start<Content...>) -> look_start<Content...>;
2037 
2038 template <auto... Str> static auto rotate(string<Str...>) -> decltype((string<>{} + ... + rotate_value<Str>{}));
2039 
2040 template <typename... Content> static auto rotate(sequence<Content...>) {
2041  return ctre::convert_to_basic_list<sequence>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
2042 }
2043 
2044 // we don't rotate lookaheads
2045 template <typename... Content> static auto rotate(lookahead_positive<Content...>) -> lookahead_positive<Content...>;
2046 template <typename... Content> static auto rotate(lookahead_negative<Content...>) -> lookahead_negative<Content...>;
2047 template <typename... Content> static auto rotate(lookbehind_positive<Content...>) -> lookbehind_positive<Content...>;
2048 template <typename... Content> static auto rotate(lookbehind_negative<Content...>) -> lookbehind_negative<Content...>;
2049 
2050 static auto rotate(atomic_start) -> atomic_start;
2051 
2052 template <typename... Content> static auto rotate(atomic_group<Content...>) {
2053  return ctre::convert_to_basic_list<atomic_group>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
2054 }
2055 
2056 template <typename... Content> static auto rotate(boundary<Content...>) -> boundary<Content...>;
2057 template <typename... Content> static auto rotate(not_boundary<Content...>) -> not_boundary<Content...>;
2058 
2059 static auto rotate(assert_subject_begin) -> assert_subject_begin;
2060 static auto rotate(assert_subject_end) -> assert_subject_end;
2061 static auto rotate(assert_subject_end_line) -> assert_subject_end_line;
2062 static auto rotate(assert_line_begin) -> assert_line_begin;
2063 static auto rotate(assert_line_end) -> assert_line_end;
2064 
2065 };
2066 
2067 }
2068 
2069 #endif
2070 
2071 #ifndef CTRE__ID__HPP
2072 #define CTRE__ID__HPP
2073 
2074 #include <type_traits>
2075 
2076 namespace ctre {
2077 
2078 template <auto... Name> struct id {
2079  static constexpr auto name = ctll::fixed_string<sizeof...(Name)>{{Name...}};
2080 
2081  friend constexpr auto operator==(id<Name...>, id<Name...>) noexcept -> std::true_type { return {}; }
2082 
2083  template <auto... Other> friend constexpr auto operator==(id<Name...>, id<Other...>) noexcept -> std::false_type { return {}; }
2084 
2085  template <typename T> friend constexpr auto operator==(id<Name...>, T) noexcept -> std::false_type { return {}; }
2086 
2087  template <typename T> friend constexpr auto operator==(T, id<Name...>) noexcept -> std::false_type { return {}; }
2088 };
2089 
2090 }
2091 
2092 #endif
2093 
2094 #include <cstdint>
2095 #include <limits>
2096 
2097 namespace ctre {
2098 
2099 template <size_t Counter> struct pcre_parameters {
2100  static constexpr size_t current_counter = Counter;
2101 };
2102 
2103 template <typename Stack = ctll::list<>, typename Parameters = pcre_parameters<0>, typename Mode = ctll::list<>> struct pcre_context {
2104  using stack_type = Stack;
2105  using parameters_type = Parameters;
2106  using mode_list = Mode;
2107  static constexpr inline auto stack = stack_type();
2108  static constexpr inline auto parameters = parameters_type();
2109  static constexpr inline auto mode = mode_list();
2110  constexpr pcre_context() noexcept { }
2111  constexpr pcre_context(Stack, Parameters) noexcept { }
2112  constexpr pcre_context(Stack, Parameters, Mode) noexcept { }
2113 };
2114 
2115 template <typename... Content, typename Parameters> pcre_context(ctll::list<Content...>, Parameters) -> pcre_context<ctll::list<Content...>, Parameters>;
2116 
2117 template <size_t Value> struct number { };
2118 
2119 template <size_t Id> struct capture_id { };
2120 
2121 struct pcre_actions {
2122 // i know it's ugly, but it's more readable
2123 #ifndef CTRE__ACTIONS__ASSERTS__HPP
2124 #define CTRE__ACTIONS__ASSERTS__HPP
2125 
2126 // push_assert_begin
2127 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_assert_begin, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2128  return pcre_context{ctll::push_front(assert_line_begin(), subject.stack), subject.parameters};
2129 }
2130 
2131 // push_assert_end
2132 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_assert_end, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2133  return pcre_context{ctll::push_front(assert_line_end(), subject.stack), subject.parameters};
2134 }
2135 
2136 // push_assert_begin
2137 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_assert_subject_begin, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2138  return pcre_context{ctll::push_front(assert_subject_begin(), subject.stack), subject.parameters};
2139 }
2140 
2141 // push_assert_subject_end
2142 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_assert_subject_end, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2143  return pcre_context{ctll::push_front(assert_subject_end(), subject.stack), subject.parameters};
2144 }
2145 
2146 // push_assert_subject_end_with_lineend
2147 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_assert_subject_end_with_lineend, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2148  return pcre_context{ctll::push_front(assert_subject_end_line(), subject.stack), subject.parameters};
2149 }
2150 
2151 #endif
2152 
2153 #ifndef CTRE__ACTIONS__ATOMIC_GROUP__HPP
2154 #define CTRE__ACTIONS__ATOMIC_GROUP__HPP
2155 
2156 // atomic start
2157 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::start_atomic, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2158  return pcre_context{ctll::list<atomic_start, Ts...>(), pcre_parameters<Counter>()};
2159 }
2160 
2161 // atomic
2162 template <auto V, typename Atomic, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_atomic, ctll::term<V>, pcre_context<ctll::list<Atomic, atomic_start, Ts...>, pcre_parameters<Counter>>) {
2163  return pcre_context{ctll::list<atomic_group<Atomic>, Ts...>(), pcre_parameters<Counter>()};
2164 }
2165 
2166 // atomic sequence
2167 template <auto V, typename... Atomic, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_atomic, ctll::term<V>, pcre_context<ctll::list<sequence<Atomic...>, atomic_start, Ts...>, pcre_parameters<Counter>>) {
2168  return pcre_context{ctll::list<atomic_group<Atomic...>, Ts...>(), pcre_parameters<Counter>()};
2169 }
2170 
2171 #endif
2172 
2173 #ifndef CTRE__ACTIONS__BACKREFERENCE__HPP
2174 #define CTRE__ACTIONS__BACKREFERENCE__HPP
2175 
2176 // backreference with name
2177 template <auto... Str, auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_back_reference, ctll::term<V>, pcre_context<ctll::list<id<Str...>, Ts...>, pcre_parameters<Counter>>) {
2178  return pcre_context{ctll::push_front(back_reference_with_name<id<Str...>>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2179 }
2180 
2181 // with just a number
2182 template <auto V, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_back_reference, ctll::term<V>, pcre_context<ctll::list<number<Id>, Ts...>, pcre_parameters<Counter>>) {
2183  // if we are looking outside of existing list of Ids ... reject input during parsing
2184  if constexpr (Counter < Id) {
2185  return ctll::reject{};
2186  } else {
2187  return pcre_context{ctll::push_front(back_reference<Id>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2188  }
2189 }
2190 
2191 // relative backreference
2192 template <auto V, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_relative_back_reference, ctll::term<V>, [[maybe_unused]] pcre_context<ctll::list<number<Id>, Ts...>, pcre_parameters<Counter>>) {
2193  // if we are looking outside of existing list of Ids ... reject input during parsing
2194  if constexpr (Counter < Id) {
2195  return ctll::reject{};
2196  } else {
2197  constexpr size_t absolute_id = (Counter + 1) - Id;
2198  return pcre_context{ctll::push_front(back_reference<absolute_id>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2199  }
2200 }
2201 
2202 #endif
2203 
2204 #ifndef CTRE__ACTIONS__BOUNDARIES__HPP
2205 #define CTRE__ACTIONS__BOUNDARIES__HPP
2206 
2207 // push_word_boundary
2208 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_word_boundary, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2209  return pcre_context{ctll::push_front(boundary<word_chars>(), subject.stack), subject.parameters};
2210 }
2211 
2212 // push_not_word_boundary
2213 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_not_word_boundary, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2214  return pcre_context{ctll::push_front(boundary<negative_set<word_chars>>(), subject.stack), subject.parameters};
2215 }
2216 
2217 #endif
2218 
2219 #ifndef CTRE__ACTIONS__CAPTURE__HPP
2220 #define CTRE__ACTIONS__CAPTURE__HPP
2221 
2222 // prepare_capture
2223 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::prepare_capture, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2224  return pcre_context{ctll::push_front(capture_id<Counter+1>(), ctll::list<Ts...>()), pcre_parameters<Counter+1>()};
2225 }
2226 
2227 // reset_capture
2228 template <auto V, typename... Ts, size_t Id, size_t Counter> static constexpr auto apply(pcre::reset_capture, ctll::term<V>, pcre_context<ctll::list<capture_id<Id>, Ts...>, pcre_parameters<Counter>>) {
2229  return pcre_context{ctll::list<Ts...>(), pcre_parameters<Counter-1>()};
2230 }
2231 
2232 // capture
2233 template <auto V, typename A, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_capture, ctll::term<V>, pcre_context<ctll::list<A, capture_id<Id>, Ts...>, pcre_parameters<Counter>>) {
2234  return pcre_context{ctll::push_front(capture<Id, A>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2235 }
2236 // capture (sequence)
2237 template <auto V, typename... Content, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_capture, ctll::term<V>, pcre_context<ctll::list<sequence<Content...>, capture_id<Id>, Ts...>, pcre_parameters<Counter>>) {
2238  return pcre_context{ctll::push_front(capture<Id, Content...>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2239 }
2240 // push_name
2241 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_name, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2242  return pcre_context{ctll::push_front(id<V>(), subject.stack), subject.parameters};
2243 }
2244 // push_name (concat)
2245 template <auto... Str, auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_name, ctll::term<V>, pcre_context<ctll::list<id<Str...>, Ts...>, Parameters> subject) {
2246  return pcre_context{ctll::push_front(id<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
2247 }
2248 // capture with name
2249 template <auto... Str, auto V, typename A, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_capture_with_name, ctll::term<V>, pcre_context<ctll::list<A, id<Str...>, capture_id<Id>, Ts...>, pcre_parameters<Counter>>) {
2250  return pcre_context{ctll::push_front(capture_with_name<Id, id<Str...>, A>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2251 }
2252 // capture with name (sequence)
2253 template <auto... Str, auto V, typename... Content, size_t Id, typename... Ts, size_t Counter> static constexpr auto apply(pcre::make_capture_with_name, ctll::term<V>, pcre_context<ctll::list<sequence<Content...>, id<Str...>, capture_id<Id>, Ts...>, pcre_parameters<Counter>>) {
2254  return pcre_context{ctll::push_front(capture_with_name<Id, id<Str...>, Content...>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
2255 }
2256 
2257 #endif
2258 
2259 #ifndef CTRE__ACTIONS__CHARACTERS__HPP
2260 #define CTRE__ACTIONS__CHARACTERS__HPP
2261 
2262 // push character
2263 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2264  return pcre_context{ctll::push_front(character<V>(), subject.stack), subject.parameters};
2265 }
2266 // push_any_character
2267 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_anything, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2268  return pcre_context{ctll::push_front(any(), subject.stack), subject.parameters};
2269 }
2270 // character_alarm
2271 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_alarm, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2272  return pcre_context{ctll::push_front(character<'\x07'>(), subject.stack), subject.parameters};
2273 }
2274 // character_escape
2275 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_escape, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2276  return pcre_context{ctll::push_front(character<'\x14'>(), subject.stack), subject.parameters};
2277 }
2278 // character_formfeed
2279 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_formfeed, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2280  return pcre_context{ctll::push_front(character<'\x0C'>(), subject.stack), subject.parameters};
2281 }
2282 // push_character_newline
2283 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_newline, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2284  return pcre_context{ctll::push_front(character<'\x0A'>(), subject.stack), subject.parameters};
2285 }
2286 // push_character_null
2287 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_null, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2288  return pcre_context{ctll::push_front(character<'\0'>(), subject.stack), subject.parameters};
2289 }
2290 // push_character_return_carriage
2291 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_return_carriage, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2292  return pcre_context{ctll::push_front(character<'\x0D'>(), subject.stack), subject.parameters};
2293 }
2294 // push_character_tab
2295 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character_tab, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2296  return pcre_context{ctll::push_front(character<'\x09'>(), subject.stack), subject.parameters};
2297 }
2298 
2299 #endif
2300 
2301 #ifndef CTRE__ACTIONS__CLASS__HPP
2302 #define CTRE__ACTIONS__CLASS__HPP
2303 
2304 // class_digit
2305 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_digit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2306  return pcre_context{ctll::push_front(ctre::set<ctre::digit_chars>(), subject.stack), subject.parameters};
2307 }
2308 // class_non_digit
2309 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nondigit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2310  return pcre_context{ctll::push_front(ctre::negative_set<ctre::digit_chars>(), subject.stack), subject.parameters};
2311 }
2312 // class_space
2313 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2314  return pcre_context{ctll::push_front(ctre::set<ctre::space_chars>(), subject.stack), subject.parameters};
2315 }
2316 // class_nonspace
2317 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonspace, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2318  return pcre_context{ctll::push_front(ctre::negative_set<ctre::space_chars>(), subject.stack), subject.parameters};
2319 }
2320 
2321 // class_horizontal_space
2322 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_horizontal_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2323  return pcre_context{ctll::push_front(ctre::set<ctre::horizontal_space_chars>(), subject.stack), subject.parameters};
2324 }
2325 // class_horizontal_nonspace
2326 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_non_horizontal_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2327  return pcre_context{ctll::push_front(ctre::negative_set<ctre::horizontal_space_chars>(), subject.stack), subject.parameters};
2328 }
2329 // class_vertical_space
2330 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_vertical_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2331  return pcre_context{ctll::push_front(ctre::set<ctre::vertical_space_chars>(), subject.stack), subject.parameters};
2332 }
2333 // class_vertical_nonspace
2334 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_non_vertical_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2335  return pcre_context{ctll::push_front(ctre::negative_set<ctre::vertical_space_chars>(), subject.stack), subject.parameters};
2336 }
2337 
2338 // class_word
2339 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_word, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2340  return pcre_context{ctll::push_front(ctre::set<ctre::word_chars>(), subject.stack), subject.parameters};
2341 }
2342 // class_nonword
2343 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonword, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2344  return pcre_context{ctll::push_front(ctre::negative_set<ctre::word_chars>(), subject.stack), subject.parameters};
2345 }
2346 // class_nonnewline
2347 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonnewline, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2348  return pcre_context{ctll::push_front(ctre::negative_set<character<'\n'>>(), subject.stack), subject.parameters};
2349 }
2350 
2351 #endif
2352 
2353 #ifndef CTRE__ACTIONS__FUSION__HPP
2354 #define CTRE__ACTIONS__FUSION__HPP
2355 
2356 static constexpr size_t combine_max_repeat_length(size_t A, size_t B) {
2357  if (A && B) return A+B;
2358  else return 0;
2359 }
2360 
2361 template <size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content> static constexpr auto combine_repeat(repeat<MinA, MaxA, Content...>, repeat<MinB, MaxB, Content...>) {
2362  return repeat<MinA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
2363 }
2364 
2365 template <size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content> static constexpr auto combine_repeat(lazy_repeat<MinA, MaxA, Content...>, lazy_repeat<MinB, MaxB, Content...>) {
2366  return lazy_repeat<MinA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
2367 }
2368 
2369 template <size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content> static constexpr auto combine_repeat(possessive_repeat<MinA, MaxA, Content...>, possessive_repeat<MinB, MaxB, Content...>) {
2370  [[maybe_unused]] constexpr bool first_is_unbounded = (MaxA == 0);
2371  [[maybe_unused]] constexpr bool second_is_nonempty = (MinB > 0);
2372  [[maybe_unused]] constexpr bool second_can_be_empty = (MinB == 0);
2373 
2374  if constexpr (first_is_unbounded && second_is_nonempty) {
2375  // will always reject, but I keep the content, so I have some amount of captures
2376  return sequence<reject, Content...>();
2377  } else if constexpr (first_is_unbounded) {
2378  return possessive_repeat<MinA, MaxA, Content...>();
2379  } else if constexpr (second_can_be_empty) {
2380  return possessive_repeat<MinA, combine_max_repeat_length(MaxA, MaxB), Content...>();
2381  } else {
2382  return possessive_repeat<MaxA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
2383  }
2384 }
2385 
2386 // concat repeat sequences
2387 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<repeat<MinB, MaxB, Content...>, repeat<MinA, MaxA, Content...>, Ts...>, Parameters> subject) {
2388  return pcre_context{ctll::push_front(combine_repeat(repeat<MinA, MaxA, Content...>(), repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
2389 }
2390 
2391 // concat lazy repeat sequences
2392 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<lazy_repeat<MinB, MaxB, Content...>, lazy_repeat<MinA, MaxA, Content...>, Ts...>, Parameters> subject) {
2393  return pcre_context{ctll::push_front(combine_repeat(lazy_repeat<MinA, MaxA, Content...>(), lazy_repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
2394 }
2395 
2396 // concat possessive repeat seqeunces
2397 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<possessive_repeat<MinB, MaxB, Content...>, possessive_repeat<MinA, MaxA, Content...>, Ts...>, Parameters> subject) {
2398  return pcre_context{ctll::push_front(combine_repeat(possessive_repeat<MinA, MaxA, Content...>(), possessive_repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
2399 }
2400 
2401 // concat repeat sequences into sequence
2402 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... As, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<repeat<MinB, MaxB, Content...>, As...>,repeat<MinA, MaxA, Content...>,Ts...>, Parameters> subject) {
2403  using result = decltype(combine_repeat(repeat<MinB, MaxB, Content...>(), repeat<MinA, MaxA, Content...>()));
2404 
2405  return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
2406 }
2407 
2408 // concat lazy repeat sequences into sequence
2409 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... As, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<lazy_repeat<MinB, MaxB, Content...>, As...>,lazy_repeat<MinA, MaxA, Content...>,Ts...>, Parameters> subject) {
2410  using result = decltype(combine_repeat(lazy_repeat<MinB, MaxB, Content...>(), lazy_repeat<MinA, MaxA, Content...>()));
2411 
2412  return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
2413 }
2414 
2415 // concat possessive repeat sequences into sequence
2416 template <auto V, size_t MinA, size_t MaxA, size_t MinB, size_t MaxB, typename... Content, typename... As, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<possessive_repeat<MinB, MaxB, Content...>, As...>,possessive_repeat<MinA, MaxA, Content...>,Ts...>, Parameters> subject) {
2417  using result = decltype(combine_repeat(possessive_repeat<MinB, MaxB, Content...>(), possessive_repeat<MinA, MaxA, Content...>()));
2418 
2419  return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
2420 }
2421 
2422 #endif
2423 
2424 #ifndef CTRE__ACTIONS__HEXDEC__HPP
2425 #define CTRE__ACTIONS__HEXDEC__HPP
2426 
2427 // hexdec character support (seed)
2428 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::create_hexdec, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2429  return pcre_context{ctll::push_front(number<0ull>(), subject.stack), subject.parameters};
2430 }
2431 // hexdec character support (push value)
2432 template <auto V, size_t N, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_hexdec, ctll::term<V>, pcre_context<ctll::list<number<N>, Ts...>, Parameters> subject) {
2433  constexpr auto previous = N << 4ull;
2434  if constexpr (V >= 'a' && V <= 'f') {
2435  return pcre_context{ctll::push_front(number<(previous + (V - 'a' + 10))>(), ctll::list<Ts...>()), subject.parameters};
2436  } else if constexpr (V >= 'A' && V <= 'F') {
2437  return pcre_context{ctll::push_front(number<(previous + (V - 'A' + 10))>(), ctll::list<Ts...>()), subject.parameters};
2438  } else {
2439  return pcre_context{ctll::push_front(number<(previous + (V - '0'))>(), ctll::list<Ts...>()), subject.parameters};
2440  }
2441 }
2442 // hexdec character support (convert to character)
2443 template <auto V, size_t N, typename... Ts, typename Parameters> static constexpr auto apply(pcre::finish_hexdec, ctll::term<V>, pcre_context<ctll::list<number<N>, Ts...>, Parameters> subject) {
2444  constexpr size_t max_char = (std::numeric_limits<char>::max)();
2445  if constexpr (N <= max_char) {
2446  return pcre_context{ctll::push_front(character<char{N}>(), ctll::list<Ts...>()), subject.parameters};
2447  } else {
2448  return pcre_context{ctll::push_front(character<char32_t{N}>(), ctll::list<Ts...>()), subject.parameters};
2449  }
2450 }
2451 
2452 #endif
2453 
2454 #ifndef CTRE__ACTIONS__LOOKAHEAD__HPP
2455 #define CTRE__ACTIONS__LOOKAHEAD__HPP
2456 
2457 // lookahead positive start
2458 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::start_lookahead_positive, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2459  return pcre_context{ctll::list<look_start<lookahead_positive<>>, Ts...>(), pcre_parameters<Counter>()};
2460 }
2461 
2462 // lookahead positive end
2463 template <auto V, typename Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<Look, look_start<lookahead_positive<>>, Ts...>, pcre_parameters<Counter>>) {
2464  return pcre_context{ctll::list<lookahead_positive<Look>, Ts...>(), pcre_parameters<Counter>()};
2465 }
2466 
2467 // lookahead positive end (sequence)
2468 template <auto V, typename... Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<ctre::sequence<Look...>, look_start<lookahead_positive<>>, Ts...>, pcre_parameters<Counter>>) {
2469  return pcre_context{ctll::list<lookahead_positive<Look...>, Ts...>(), pcre_parameters<Counter>()};
2470 }
2471 
2472 // lookahead negative start
2473 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::start_lookahead_negative, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2474  return pcre_context{ctll::list<look_start<lookahead_negative<>>, Ts...>(), pcre_parameters<Counter>()};
2475 }
2476 
2477 // lookahead negative end
2478 template <auto V, typename Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<Look, look_start<lookahead_negative<>>, Ts...>, pcre_parameters<Counter>>) {
2479  return pcre_context{ctll::list<lookahead_negative<Look>, Ts...>(), pcre_parameters<Counter>()};
2480 }
2481 
2482 // lookahead negative end (sequence)
2483 template <auto V, typename... Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<ctre::sequence<Look...>, look_start<lookahead_negative<>>, Ts...>, pcre_parameters<Counter>>) {
2484  return pcre_context{ctll::list<lookahead_negative<Look...>, Ts...>(), pcre_parameters<Counter>()};
2485 }
2486 
2487 // LOOKBEHIND
2488 
2489 // lookbehind positive start
2490 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::start_lookbehind_positive, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2491  return pcre_context{ctll::list<look_start<lookbehind_positive<>>, Ts...>(), pcre_parameters<Counter>()};
2492 }
2493 
2494 // lookbehind positive end
2495 template <auto V, typename Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<Look, look_start<lookbehind_positive<>>, Ts...>, pcre_parameters<Counter>>) {
2496  return pcre_context{ctll::list<lookbehind_positive<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))>, Ts...>(), pcre_parameters<Counter>()};
2497 }
2498 
2499 // lookbehind positive end (sequence)
2500 template <auto V, typename... Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<ctre::sequence<Look...>, look_start<lookbehind_positive<>>, Ts...>, pcre_parameters<Counter>>) {
2501  using my_lookbehind = decltype(ctre::convert_to_basic_list<lookbehind_positive>(ctll::rotate(ctll::list<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))...>{})));
2502  return pcre_context{ctll::list<my_lookbehind, Ts...>(), pcre_parameters<Counter>()};
2503 }
2504 
2505 // lookbehind negative start
2506 template <auto V, typename... Ts, size_t Counter> static constexpr auto apply(pcre::start_lookbehind_negative, ctll::term<V>, pcre_context<ctll::list<Ts...>, pcre_parameters<Counter>>) {
2507  return pcre_context{ctll::list<look_start<lookbehind_negative<>>, Ts...>(), pcre_parameters<Counter>()};
2508 }
2509 
2510 // lookbehind negative end
2511 template <auto V, typename Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<Look, look_start<lookbehind_negative<>>, Ts...>, pcre_parameters<Counter>>) {
2512  return pcre_context{ctll::list<lookbehind_negative<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))>, Ts...>(), pcre_parameters<Counter>()};
2513 }
2514 
2515 // lookbehind negative end (sequence)
2516 template <auto V, typename... Look, typename... Ts, size_t Counter> static constexpr auto apply(pcre::look_finish, ctll::term<V>, pcre_context<ctll::list<ctre::sequence<Look...>, look_start<lookbehind_negative<>>, Ts...>, pcre_parameters<Counter>>) {
2517  using my_lookbehind = decltype(ctre::convert_to_basic_list<lookbehind_negative>(ctll::rotate(ctll::list<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))...>{})));
2518  return pcre_context{ctll::list<my_lookbehind, Ts...>(), pcre_parameters<Counter>()};
2519 }
2520 
2521 #endif
2522 
2523 #ifndef CTRE__ACTIONS__NAMED_CLASS__HPP
2524 #define CTRE__ACTIONS__NAMED_CLASS__HPP
2525 
2526 // class_named_alnum
2527 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_alnum, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2528  return pcre_context{ctll::push_front(ctre::alphanum_chars(), subject.stack), subject.parameters};
2529 }
2530 // class_named_alpha
2531 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_alpha, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2532  return pcre_context{ctll::push_front(ctre::alpha_chars(), subject.stack), subject.parameters};
2533 }
2534 // class_named_digit
2535 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_digit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2536  return pcre_context{ctll::push_front(ctre::digit_chars(), subject.stack), subject.parameters};
2537 }
2538 // class_named_ascii
2539 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_ascii, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2540  return pcre_context{ctll::push_front(ctre::ascii_chars(), subject.stack), subject.parameters};
2541 }
2542 // class_named_blank
2543 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_blank, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2544  return pcre_context{ctll::push_front(ctre::enumeration<' ','\t'>(), subject.stack), subject.parameters};
2545 }
2546 // class_named_cntrl
2547 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_cntrl, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2548  return pcre_context{ctll::push_front(ctre::set<ctre::char_range<'\x00','\x1F'>, ctre::character<'\x7F'>>(), subject.stack), subject.parameters};
2549 }
2550 // class_named_graph
2551 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_graph, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2552  return pcre_context{ctll::push_front(ctre::char_range<'\x21','\x7E'>(), subject.stack), subject.parameters};
2553 }
2554 // class_named_lower
2555 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_lower, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2556  return pcre_context{ctll::push_front(ctre::char_range<'a','z'>(), subject.stack), subject.parameters};
2557 }
2558 // class_named_upper
2559 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_upper, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2560  return pcre_context{ctll::push_front(ctre::char_range<'A','Z'>(), subject.stack), subject.parameters};
2561 }
2562 // class_named_print
2563 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_print, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2564  return pcre_context{ctll::push_front(ctre::char_range<'\x20','\x7E'>(), subject.stack), subject.parameters};
2565 }
2566 // class_named_space
2567 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2568  return pcre_context{ctll::push_front(space_chars(), subject.stack), subject.parameters};
2569 }
2570 // class_named_word
2571 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_word, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2572  return pcre_context{ctll::push_front(word_chars(), subject.stack), subject.parameters};
2573 }
2574 // class_named_punct
2575 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_punct, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2576  return pcre_context{ctll::push_front(punct_chars(), subject.stack), subject.parameters};
2577 }
2578 // class_named_xdigit
2579 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_named_xdigit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2580  return pcre_context{ctll::push_front(xdigit_chars(), subject.stack), subject.parameters};
2581 }
2582 
2583 #endif
2584 
2585 #ifndef CTRE__ACTIONS__OPTIONS__HPP
2586 #define CTRE__ACTIONS__OPTIONS__HPP
2587 
2588 // empty option for alternate
2589 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_empty, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2590  return pcre_context{ctll::push_front(empty(), subject.stack), subject.parameters};
2591 }
2592 
2593 // empty option for empty regex
2594 template <typename Parameters> static constexpr auto apply(pcre::push_empty, ctll::epsilon, pcre_context<ctll::list<>, Parameters> subject) {
2595  return pcre_context{ctll::push_front(empty(), subject.stack), subject.parameters};
2596 }
2597 
2598 // make_alternate (A|B)
2599 template <auto V, typename A, typename B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<B, A, Ts...>, Parameters> subject) {
2600  return pcre_context{ctll::push_front(select<A,B>(), ctll::list<Ts...>()), subject.parameters};
2601 }
2602 // make_alternate (As..)|B => (As..|B)
2603 template <auto V, typename A, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<ctre::select<Bs...>, A, Ts...>, Parameters> subject) {
2604  return pcre_context{ctll::push_front(select<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
2605 }
2606 
2607 // make_optional
2608 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_optional, ctll::term<V>, pcre_context<ctll::list<A, Ts...>, Parameters> subject) {
2609  return pcre_context{ctll::push_front(optional<A>(), ctll::list<Ts...>()), subject.parameters};
2610 }
2611 
2612 template <auto V, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_optional, ctll::term<V>, pcre_context<ctll::list<sequence<Content...>, Ts...>, Parameters> subject) {
2613  return pcre_context{ctll::push_front(optional<Content...>(), ctll::list<Ts...>()), subject.parameters};
2614 }
2615 
2616 // prevent from creating wrapped optionals
2617 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_optional, ctll::term<V>, pcre_context<ctll::list<optional<A>, Ts...>, Parameters> subject) {
2618  return pcre_context{ctll::push_front(optional<A>(), ctll::list<Ts...>()), subject.parameters};
2619 }
2620 
2621 // in case inner optional is lazy, result should be lazy too
2622 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_optional, ctll::term<V>, pcre_context<ctll::list<lazy_optional<A>, Ts...>, Parameters> subject) {
2623  return pcre_context{ctll::push_front(lazy_optional<A>(), ctll::list<Ts...>()), subject.parameters};
2624 }
2625 
2626 // make_lazy (optional)
2627 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_lazy, ctll::term<V>, pcre_context<ctll::list<optional<Subject...>, Ts...>, Parameters> subject) {
2628  return pcre_context{ctll::push_front(lazy_optional<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2629 }
2630 
2631 // if you already got a lazy optional, make_lazy is no-op
2632 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_lazy, ctll::term<V>, pcre_context<ctll::list<lazy_optional<Subject...>, Ts...>, Parameters> subject) {
2633  return pcre_context{ctll::push_front(lazy_optional<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2634 }
2635 
2636 #endif
2637 
2638 #ifndef CTRE__ACTIONS__PROPERTIES__HPP
2639 #define CTRE__ACTIONS__PROPERTIES__HPP
2640 
2641 // push_property_name
2642 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_property_name, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2643  return pcre_context{ctll::push_front(property_name<V>(), subject.stack), subject.parameters};
2644 }
2645 // push_property_name (concat)
2646 template <auto... Str, auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_property_name, ctll::term<V>, pcre_context<ctll::list<property_name<Str...>, Ts...>, Parameters> subject) {
2647  return pcre_context{ctll::push_front(property_name<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
2648 }
2649 
2650 // push_property_value
2651 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_property_value, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2652  return pcre_context{ctll::push_front(property_value<V>(), subject.stack), subject.parameters};
2653 }
2654 // push_property_value (concat)
2655 template <auto... Str, auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_property_value, ctll::term<V>, pcre_context<ctll::list<property_value<Str...>, Ts...>, Parameters> subject) {
2656  return pcre_context{ctll::push_front(property_value<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
2657 }
2658 
2659 // make_property
2660 template <auto V, auto... Name, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_property, ctll::term<V>, [[maybe_unused]] pcre_context<ctll::list<property_name<Name...>, Ts...>, Parameters> subject) {
2661  //return ctll::reject{};
2662  constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
2663  constexpr auto p = uni::detail::binary_prop_from_string(get_string_view(name));
2664 
2665  if constexpr (uni::detail::is_unknown(p)) {
2666  return ctll::reject{};
2667  } else {
2668  return pcre_context{ctll::push_front(make_binary_property<p>(), ctll::list<Ts...>()), subject.parameters};
2669  }
2670 }
2671 
2672 // make_property
2673 template <auto V, auto... Value, auto... Name, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_property, ctll::term<V>, [[maybe_unused]] pcre_context<ctll::list<property_value<Value...>, property_name<Name...>, Ts...>, Parameters> subject) {
2674  //return ctll::reject{};
2675  constexpr auto prop = property_builder<Name...>::template get<Value...>();
2676 
2677  if constexpr (std::is_same_v<decltype(prop), ctll::reject>) {
2678  return ctll::reject{};
2679  } else {
2680  return pcre_context{ctll::push_front(prop, ctll::list<Ts...>()), subject.parameters};
2681  }
2682 }
2683 
2684 // make_property_negative
2685 template <auto V, auto... Name, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_property_negative, ctll::term<V>, [[maybe_unused]] pcre_context<ctll::list<property_name<Name...>, Ts...>, Parameters> subject) {
2686  //return ctll::reject{};
2687  constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
2688  constexpr auto p = uni::detail::binary_prop_from_string(get_string_view(name));
2689 
2690  if constexpr (uni::detail::is_unknown(p)) {
2691  return ctll::reject{};
2692  } else {
2693  return pcre_context{ctll::push_front(negate<make_binary_property<p>>(), ctll::list<Ts...>()), subject.parameters};
2694  }
2695 }
2696 
2697 // make_property_negative
2698 template <auto V, auto... Value, auto... Name, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_property_negative, ctll::term<V>, [[maybe_unused]] pcre_context<ctll::list<property_value<Value...>, property_name<Name...>, Ts...>, Parameters> subject) {
2699  //return ctll::reject{};
2700  constexpr auto prop = property_builder<Name...>::template get<Value...>();
2701 
2702  if constexpr (std::is_same_v<decltype(prop), ctll::reject>) {
2703  return ctll::reject{};
2704  } else {
2705  return pcre_context{ctll::push_front(negate<decltype(prop)>(), ctll::list<Ts...>()), subject.parameters};
2706  }
2707 }
2708 
2709 #endif
2710 
2711 #ifndef CTRE__ACTIONS__REPEAT__HPP
2712 #define CTRE__ACTIONS__REPEAT__HPP
2713 
2714 // repeat 1..N
2715 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_plus, ctll::term<V>, pcre_context<ctll::list<A, Ts...>, Parameters> subject) {
2716  return pcre_context{ctll::push_front(plus<A>(), ctll::list<Ts...>()), subject.parameters};
2717 }
2718 // repeat 1..N (sequence)
2719 template <auto V, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_plus, ctll::term<V>, pcre_context<ctll::list<sequence<Content...>, Ts...>, Parameters> subject) {
2720  return pcre_context{ctll::push_front(plus<Content...>(), ctll::list<Ts...>()), subject.parameters};
2721 }
2722 
2723 // repeat 0..N
2724 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_star, ctll::term<V>, pcre_context<ctll::list<A, Ts...>, Parameters> subject) {
2725  return pcre_context{ctll::push_front(star<A>(), ctll::list<Ts...>()), subject.parameters};
2726 }
2727 // repeat 0..N (sequence)
2728 template <auto V, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_star, ctll::term<V>, pcre_context<ctll::list<sequence<Content...>, Ts...>, Parameters> subject) {
2729  return pcre_context{ctll::push_front(star<Content...>(), ctll::list<Ts...>()), subject.parameters};
2730 }
2731 
2732 // create_number (seed)
2733 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::create_number, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
2734  return pcre_context{ctll::push_front(number<static_cast<size_t>(V - '0')>(), subject.stack), subject.parameters};
2735 }
2736 // push_number
2737 template <auto V, size_t N, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_number, ctll::term<V>, pcre_context<ctll::list<number<N>, Ts...>, Parameters> subject) {
2738  constexpr size_t previous = N * 10ull;
2739  return pcre_context{ctll::push_front(number<(previous + (V - '0'))>(), ctll::list<Ts...>()), subject.parameters};
2740 }
2741 
2742 // repeat A..B
2743 template <auto V, typename Subject, size_t A, size_t B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_ab, ctll::term<V>, pcre_context<ctll::list<number<B>, number<A>, Subject, Ts...>, Parameters> subject) {
2744  return pcre_context{ctll::push_front(repeat<A,B,Subject>(), ctll::list<Ts...>()), subject.parameters};
2745 }
2746 // repeat A..B (sequence)
2747 template <auto V, typename... Content, size_t A, size_t B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_ab, ctll::term<V>, pcre_context<ctll::list<number<B>, number<A>, sequence<Content...>, Ts...>, Parameters> subject) {
2748  return pcre_context{ctll::push_front(repeat<A,B,Content...>(), ctll::list<Ts...>()), subject.parameters};
2749 }
2750 
2751 // repeat_exactly
2752 template <auto V, typename Subject, size_t A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_exactly, ctll::term<V>, pcre_context<ctll::list<number<A>, Subject, Ts...>, Parameters> subject) {
2753  return pcre_context{ctll::push_front(repeat<A,A,Subject>(), ctll::list<Ts...>()), subject.parameters};
2754 }
2755 // repeat_exactly A..B (sequence)
2756 template <auto V, typename... Content, size_t A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_exactly, ctll::term<V>, pcre_context<ctll::list<number<A>, sequence<Content...>, Ts...>, Parameters> subject) {
2757  return pcre_context{ctll::push_front(repeat<A,A,Content...>(), ctll::list<Ts...>()), subject.parameters};
2758 }
2759 
2760 // repeat_at_least (A+)
2761 template <auto V, typename Subject, size_t A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_at_least, ctll::term<V>, pcre_context<ctll::list<number<A>, Subject, Ts...>, Parameters> subject) {
2762  return pcre_context{ctll::push_front(repeat<A,0,Subject>(), ctll::list<Ts...>()), subject.parameters};
2763 }
2764 // repeat_at_least (A+) (sequence)
2765 template <auto V, typename... Content, size_t A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::repeat_at_least, ctll::term<V>, pcre_context<ctll::list<number<A>, sequence<Content...>, Ts...>, Parameters> subject) {
2766  return pcre_context{ctll::push_front(repeat<A,0,Content...>(), ctll::list<Ts...>()), subject.parameters};
2767 }
2768 
2769 // make_lazy (plus)
2770 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_lazy, ctll::term<V>, pcre_context<ctll::list<plus<Subject...>, Ts...>, Parameters> subject) {
2771  return pcre_context{ctll::push_front(lazy_plus<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2772 }
2773 
2774 // make_lazy (star)
2775 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_lazy, ctll::term<V>, pcre_context<ctll::list<star<Subject...>, Ts...>, Parameters> subject) {
2776  return pcre_context{ctll::push_front(lazy_star<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2777 }
2778 
2779 // make_lazy (repeat<A,B>)
2780 template <auto V, typename... Subject, size_t A, size_t B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_lazy, ctll::term<V>, pcre_context<ctll::list<repeat<A,B,Subject...>, Ts...>, Parameters> subject) {
2781  return pcre_context{ctll::push_front(lazy_repeat<A,B,Subject...>(), ctll::list<Ts...>()), subject.parameters};
2782 }
2783 
2784 // make_possessive (plus)
2785 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_possessive, ctll::term<V>, pcre_context<ctll::list<plus<Subject...>, Ts...>, Parameters> subject) {
2786  return pcre_context{ctll::push_front(possessive_plus<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2787 }
2788 
2789 // make_possessive (star)
2790 template <auto V, typename... Subject, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_possessive, ctll::term<V>, pcre_context<ctll::list<star<Subject...>, Ts...>, Parameters> subject) {
2791  return pcre_context{ctll::push_front(possessive_star<Subject...>(), ctll::list<Ts...>()), subject.parameters};
2792 }
2793 
2794 // make_possessive (repeat<A,B>)
2795 template <auto V, typename... Subject, size_t A, size_t B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_possessive, ctll::term<V>, pcre_context<ctll::list<repeat<A,B,Subject...>, Ts...>, Parameters> subject) {
2796  return pcre_context{ctll::push_front(possessive_repeat<A,B,Subject...>(), ctll::list<Ts...>()), subject.parameters};
2797 }
2798 
2799 #endif
2800 
2801 #ifndef CTRE__ACTIONS__SEQUENCE__HPP
2802 #define CTRE__ACTIONS__SEQUENCE__HPP
2803 
2804 // make_sequence
2805 template <auto V, typename A, typename B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<B,A,Ts...>, Parameters> subject) {
2806  return pcre_context{ctll::push_front(sequence<A,B>(), ctll::list<Ts...>()), subject.parameters};
2807 }
2808 // make_sequence (concat)
2809 template <auto V, typename A, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<Bs...>,A,Ts...>, Parameters> subject) {
2810  return pcre_context{ctll::push_front(sequence<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
2811 }
2812 
2813 // make_sequence (make string)
2814 template <auto V, auto A, auto B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<character<B>,character<A>,Ts...>, Parameters> subject) {
2815  return pcre_context{ctll::push_front(string<A,B>(), ctll::list<Ts...>()), subject.parameters};
2816 }
2817 // make_sequence (concat string)
2818 template <auto V, auto A, auto... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<string<Bs...>,character<A>,Ts...>, Parameters> subject) {
2819  return pcre_context{ctll::push_front(string<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
2820 }
2821 
2822 // make_sequence (make string in front of different items)
2823 template <auto V, auto A, auto B, typename... Sq, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<character<B>,Sq...>,character<A>,Ts...>, Parameters> subject) {
2824  return pcre_context{ctll::push_front(sequence<string<A,B>,Sq...>(), ctll::list<Ts...>()), subject.parameters};
2825 }
2826 // make_sequence (concat string in front of different items)
2827 template <auto V, auto A, auto... Bs, typename... Sq, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_sequence, ctll::term<V>, pcre_context<ctll::list<sequence<string<Bs...>,Sq...>,character<A>,Ts...>, Parameters> subject) {
2828  return pcre_context{ctll::push_front(sequence<string<A,Bs...>,Sq...>(), ctll::list<Ts...>()), subject.parameters};
2829 }
2830 
2831 #endif
2832 
2833 #ifndef CTRE__ACTIONS__SET__HPP
2834 #define CTRE__ACTIONS__SET__HPP
2835 
2836 // UTILITY
2837 // add into set if not exists
2838 template <template <typename...> typename SetType, typename T, typename... As, bool Exists = (std::is_same_v<T, As> || ... || false)> static constexpr auto push_back_into_set(T, SetType<As...>) -> ctll::conditional<Exists, SetType<As...>, SetType<As...,T>> { return {}; }
2839 
2840 //template <template <typename...> typename SetType, typename A, typename BHead, typename... Bs> struct set_merge_helper {
2841 // using step = decltype(push_back_into_set<SetType>(BHead(), A()));
2842 // using type = ctll::conditional<(sizeof...(Bs) > 0), set_merge_helper<SetType, step, Bs...>, step>;
2843 //};
2844 //
2845 //// add set into set if not exists
2846 //template <template <typename...> typename SetType, typename... As, typename... Bs> static constexpr auto push_back_into_set(SetType<As...>, SetType<Bs...>) -> typename set_merge_helper<SetType, SetType<As...>, Bs...>::type { return pcre_context{{};), subject.parameters}}
2847 //
2848 //template <template <typename...> typename SetType, typename... As> static constexpr auto push_back_into_set(SetType<As...>, SetType<>) -> SetType<As...> { return pcre_context{{};), subject.parameters}}
2849 
2850 // END OF UTILITY
2851 
2852 // set_start
2853 template <auto V, typename A,typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_start, ctll::term<V>, pcre_context<ctll::list<A,Ts...>, Parameters> subject) {
2854  return pcre_context{ctll::push_front(set<A>(), ctll::list<Ts...>()), subject.parameters};
2855 }
2856 // set_make
2857 template <auto V, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_make, ctll::term<V>, pcre_context<ctll::list<set<Content...>, Ts...>, Parameters> subject) {
2858  return pcre_context{ctll::push_front(set<Content...>(), ctll::list<Ts...>()), subject.parameters};
2859 }
2860 // set_make_negative
2861 template <auto V, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_make_negative, ctll::term<V>, pcre_context<ctll::list<set<Content...>, Ts...>, Parameters> subject) {
2862  return pcre_context{ctll::push_front(negative_set<Content...>(), ctll::list<Ts...>()), subject.parameters};
2863 }
2864 // set{A...} + B = set{A,B}
2865 template <auto V, typename A, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_combine, ctll::term<V>, pcre_context<ctll::list<A,set<Content...>,Ts...>, Parameters> subject) {
2866  auto new_set = push_back_into_set<set>(A(), set<Content...>());
2867  return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
2868 }
2869 // TODO checkme
2870 //// set{A...} + set{B...} = set{A...,B...}
2871 //template <auto V, typename... As, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_combine, ctll::term<V>, pcre_context<ctll::list<set<As...>,set<Bs...>,Ts...>, Parameters> subject) {
2872 // auto new_set = push_back_into_set<set>(set<As...>(), set<Bs...>());
2873 // return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
2874 //}
2875 
2876 // negative_set{A...} + B = negative_set{A,B}
2877 template <auto V, typename A, typename... Content, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_combine, ctll::term<V>, pcre_context<ctll::list<A,negative_set<Content...>,Ts...>, Parameters> subject) {
2878  auto new_set = push_back_into_set<set>(A(), set<Content...>());
2879  return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
2880 }
2881 // TODO checkme
2882 //// negative_set{A...} + negative_set{B...} = negative_set{A...,B...}
2883 //template <auto V, typename... As, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_combine, ctll::term<V>, pcre_context<ctll::list<negative_set<As...>,negative_set<Bs...>,Ts...>, Parameters> subject) {
2884 // auto new_set = push_back_into_set<negative_set>(negative_set<As...>(), negative_set<Bs...>());
2885 // return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
2886 //}
2887 // negate_class_named: [[^:digit:]] = [^[:digit:]]
2888 template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::negate_class_named, ctll::term<V>, pcre_context<ctll::list<A, Ts...>, Parameters> subject) {
2889  return pcre_context{ctll::push_front(negate<A>(), ctll::list<Ts...>()), subject.parameters};
2890 }
2891 
2892 // add range to set
2893 template <auto V, auto B, auto A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_range, ctll::term<V>, pcre_context<ctll::list<character<B>,character<A>, Ts...>, Parameters> subject) {
2894  return pcre_context{ctll::push_front(char_range<A,B>(), ctll::list<Ts...>()), subject.parameters};
2895 }
2896 
2897 #endif
2898 
2899 #ifndef CTRE__ACTIONS__MODE__HPP
2900 #define CTRE__ACTIONS__MODE__HPP
2901 
2902 // we need to reset counter and wrap Mode into mode_switch
2903 template <typename Mode, typename... Ts, typename Parameters> static constexpr auto apply_mode(Mode, ctll::list<Ts...>, Parameters) {
2904  return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, Parameters>{};
2905 }
2906 
2907 template <typename Mode, typename... Ts, size_t Id, size_t Counter> static constexpr auto apply_mode(Mode, ctll::list<capture_id<Id>, Ts...>, pcre_parameters<Counter>) {
2908  return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, pcre_parameters<Counter-1>>{};
2909 }
2910 
2911 // catch a semantic action into mode
2912 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_case_insensitive mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2913  return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2914 }
2915 
2916 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_case_sensitive mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2917  return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2918 }
2919 
2920 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_singleline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2921  return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2922 }
2923 
2924 template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_multiline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2925  return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2926 }
2927 
2928 // to properly reset capture
2929 
2930 #endif
2931 
2932 };
2933 
2934 }
2935 
2936 #endif
2937 
2938 #ifndef CTRE__EVALUATION__HPP
2939 #define CTRE__EVALUATION__HPP
2940 
2941 #ifndef CTRE__STARTS_WITH_ANCHOR__HPP
2942 #define CTRE__STARTS_WITH_ANCHOR__HPP
2943 
2944 namespace ctre {
2945 
2946 template <typename... Content>
2947 constexpr bool starts_with_anchor(const flags &, ctll::list<Content...>) noexcept {
2948  return false;
2949 }
2950 
2951 template <typename... Content>
2952 constexpr bool starts_with_anchor(const flags &, ctll::list<assert_subject_begin, Content...>) noexcept {
2953  // yes! start subject anchor is here
2954  return true;
2955 }
2956 
2957 template <typename... Content>
2958 constexpr bool starts_with_anchor(const flags & f, ctll::list<assert_line_begin, Content...>) noexcept {
2959  // yes! start line anchor is here
2960  return !ctre::multiline_mode(f) || starts_with_anchor(f, ctll::list<Content...>{});
2961 }
2962 
2963 template <typename CharLike, typename... Content>
2964 constexpr bool starts_with_anchor(const flags & f, ctll::list<boundary<CharLike>, Content...>) noexcept {
2965  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2966  return starts_with_anchor(f, ctll::list<Content...>{});
2967 }
2968 
2969 template <typename... Options, typename... Content>
2970 constexpr bool starts_with_anchor(const flags & f, ctll::list<select<Options...>, Content...>) noexcept {
2971  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2972  return (starts_with_anchor(f, ctll::list<Options, Content...>{}) && ... && true);
2973 }
2974 
2975 template <typename... Optional, typename... Content>
2976 constexpr bool starts_with_anchor(const flags & f, ctll::list<optional<Optional...>, Content...>) noexcept {
2977  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2978  return starts_with_anchor(f, ctll::list<Optional..., Content...>{}) && starts_with_anchor(f, ctll::list<Content...>{});
2979 }
2980 
2981 template <typename... Optional, typename... Content>
2982 constexpr bool starts_with_anchor(const flags & f, ctll::list<lazy_optional<Optional...>, Content...>) noexcept {
2983  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2984  return starts_with_anchor(f, ctll::list<Optional..., Content...>{}) && starts_with_anchor(f, ctll::list<Content...>{});
2985 }
2986 
2987 template <typename... Seq, typename... Content>
2988 constexpr bool starts_with_anchor(const flags & f, ctll::list<sequence<Seq...>, Content...>) noexcept {
2989  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2990  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
2991 }
2992 
2993 template <size_t A, size_t B, typename... Seq, typename... Content>
2994 constexpr bool starts_with_anchor(const flags & f, ctll::list<repeat<A, B, Seq...>, Content...>) noexcept {
2995  // check if all options starts with anchor or if they are empty, there is an anchor behind them
2996  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
2997 }
2998 
2999 template <size_t A, size_t B, typename... Seq, typename... Content>
3000 constexpr bool starts_with_anchor(const flags & f, ctll::list<lazy_repeat<A, B, Seq...>, Content...>) noexcept {
3001  // check if all options starts with anchor or if they are empty, there is an anchor behind them
3002  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
3003 }
3004 
3005 template <size_t A, size_t B, typename... Seq, typename... Content>
3006 constexpr bool starts_with_anchor(const flags & f, ctll::list<possessive_repeat<A, B, Seq...>, Content...>) noexcept {
3007  // check if all options starts with anchor or if they are empty, there is an anchor behind them
3008  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
3009 }
3010 
3011 template <size_t Index, typename... Seq, typename... Content>
3012 constexpr bool starts_with_anchor(const flags & f, ctll::list<capture<Index, Seq...>, Content...>) noexcept {
3013  // check if all options starts with anchor or if they are empty, there is an anchor behind them
3014  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
3015 }
3016 
3017 template <size_t Index, typename... Seq, typename... Content>
3018 constexpr bool starts_with_anchor(const flags & f, ctll::list<capture_with_name<Index, Seq...>, Content...>) noexcept {
3019  // check if all options starts with anchor or if they are empty, there is an anchor behind them
3020  return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
3021 }
3022 
3023 }
3024 
3025 #endif
3026 
3027 #ifndef CTRE__RETURN_TYPE__HPP
3028 #define CTRE__RETURN_TYPE__HPP
3029 
3030 #ifndef CTRE__UTF8__HPP
3031 #define CTRE__UTF8__HPP
3032 
3033 #if __cpp_char8_t >= 201811
3034 
3035 #include <string_view>
3036 #include <iterator>
3037 
3038 #if __cpp_lib_char8_t >= 201811L
3039 #define CTRE_ENABLE_UTF8_RANGE
3040 #endif
3041 
3042 namespace ctre {
3043 
3044 struct utf8_iterator {
3045  using self_type = utf8_iterator;
3046  using value_type = char8_t;
3047  using reference = char8_t;
3048  using pointer = const char8_t *;
3049  using iterator_category = std::bidirectional_iterator_tag;
3050  using difference_type = int;
3051 
3052  struct sentinel {
3053  // this is here only because I want to support std::make_reverse_iterator
3054  using self_type = utf8_iterator;
3055  using value_type = char8_t;
3056  using reference = char8_t &;
3057  using pointer = const char8_t *;
3058  using iterator_category = std::bidirectional_iterator_tag;
3059  using difference_type = int;
3060 
3061  // it's just sentinel it won't be ever called
3062  auto operator++() noexcept -> self_type &;
3063  auto operator++(int) noexcept -> self_type;
3064  auto operator--() noexcept -> self_type &;
3065  auto operator--(int) noexcept -> self_type;
3066  friend auto operator==(self_type, self_type) noexcept -> bool;
3067  auto operator*() noexcept -> reference;
3068 
3069  friend constexpr auto operator==(self_type, const char8_t * other_ptr) noexcept {
3070  return *other_ptr == char8_t{0};
3071  }
3072  };
3073 
3074  const char8_t * ptr{nullptr};
3075  const char8_t * end{nullptr};
3076 
3077  constexpr friend bool operator!=(const utf8_iterator & lhs, sentinel) {
3078  return lhs.ptr < lhs.end;
3079  }
3080 
3081  constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) {
3082  return rhs.ptr < rhs.end;
3083  }
3084 
3085  constexpr friend bool operator!=(const utf8_iterator & lhs, const utf8_iterator & rhs) {
3086  return lhs.ptr != rhs.ptr;
3087  }
3088 
3089  constexpr friend bool operator==(const utf8_iterator & lhs, sentinel) {
3090  return lhs.ptr >= lhs.end;
3091  }
3092 
3093  constexpr friend bool operator==(sentinel, const utf8_iterator & rhs) {
3094  return rhs.ptr >= rhs.end;
3095  }
3096 
3097  constexpr utf8_iterator & operator=(const char8_t * rhs) {
3098  ptr = rhs;
3099  return *this;
3100  }
3101 
3102  constexpr operator const char8_t *() const noexcept {
3103  return ptr;
3104  }
3105 
3106  constexpr utf8_iterator & operator++() noexcept {
3107  // the contant is mapping from first 5 bits of first code unit to length of UTF8 code point -1
3108  // xxxxx -> yy (5 bits to 2 bits)
3109  // 5 bits are 32 combination, and for each I need 2 bits, hence 64 bit constant
3110  // (*ptr >> 2) & 0b111110 look at the left 5 bits ignoring the least significant
3111  // & 0b11u selects only needed two bits
3112  // +1 because each iteration is at least one code unit forward
3113 
3114  ptr += ((0x3A55000000000000ull >> ((*ptr >> 2) & 0b111110u)) & 0b11u) + 1;
3115  return *this;
3116  }
3117 
3118  constexpr utf8_iterator & operator--() noexcept {
3119  if (ptr > end) {
3120  ptr = end-1;
3121  } else {
3122  --ptr;
3123  }
3124 
3125  while ((*ptr & 0b11000000u) == 0b10'000000) {
3126  --ptr;
3127  }
3128 
3129  return *this;
3130  }
3131 
3132  constexpr utf8_iterator operator--(int) noexcept {
3133  auto self = *this;
3134  this->operator--();
3135  return self;
3136  }
3137 
3138  constexpr utf8_iterator operator++(int) noexcept {
3139  auto self = *this;
3140  this->operator++();
3141  return self;
3142  }
3143 
3144  constexpr utf8_iterator operator+(unsigned step) const noexcept {
3145  utf8_iterator result = *this;
3146  while (step > 0) {
3147  ++result;
3148  step--;
3149  }
3150  return result;
3151  }
3152 
3153  constexpr utf8_iterator operator-(unsigned step) const noexcept {
3154  utf8_iterator result = *this;
3155  while (step > 0) {
3156  --result;
3157  step--;
3158  }
3159  return result;
3160  }
3161 
3162  constexpr char32_t operator*() const noexcept {
3163  constexpr char32_t mojibake = 0xFFFDull;
3164 
3165  // quickpath
3166  if (!(*ptr & 0b1000'0000u)) CTRE_LIKELY {
3167  return *ptr;
3168  }
3169 
3170  // calculate length based on first 5 bits
3171  const unsigned length = ((0x3A55000000000000ull >> ((*ptr >> 2) & 0b111110u)) & 0b11u);
3172 
3173  // actual length is number + 1 bytes
3174 
3175  // length 0 here means it's a bad front unit
3176  if (!length) CTRE_UNLIKELY {
3177  return mojibake;
3178  }
3179 
3180  // if part of the utf-8 sequence is past the end
3181  if (((ptr + length) >= end)) CTRE_UNLIKELY {
3182  return mojibake;
3183  }
3184 
3185  if ((ptr[1] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
3186  return mojibake;
3187  }
3188 
3189  const char8_t mask = static_cast<char8_t>(0b0011'1111u >> length);
3190 
3191  // length = 1 (2 bytes) mask = 0b0001'1111u
3192  // length = 2 (3 bytes) mask = 0b0000'1111u
3193  // length = 3 (4 bytes) mask = 0b0000'0111u
3194 
3195  // remove utf8 front bits, get only significant part
3196  // and add first trailing unit
3197 
3198  char32_t result = static_cast<char32_t>((ptr[0] & mask) << 6u) | (ptr[1] & 0b0011'1111u);
3199 
3200  // add rest of trailing units
3201  if (length == 1) CTRE_LIKELY {
3202  return result;
3203  }
3204 
3205  if ((ptr[2] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
3206  return mojibake;
3207  }
3208 
3209  result = (result << 6) | (ptr[2] & 0b0011'1111u);
3210 
3211  if (length == 2) CTRE_LIKELY {
3212  return result;
3213  }
3214 
3215  if ((ptr[3] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
3216  return mojibake;
3217  }
3218 
3219  return (result << 6) | (ptr[3] & 0b0011'1111u);
3220  }
3221 };
3222 
3223 #ifdef CTRE_ENABLE_UTF8_RANGE
3224 struct utf8_range {
3225  std::u8string_view range;
3226  constexpr utf8_range(std::u8string_view r) noexcept: range{r} { }
3227 
3228  constexpr auto begin() const noexcept {
3229  return utf8_iterator{range.data(), range.data() + range.size()};
3230  }
3231  constexpr auto end() const noexcept {
3232  return utf8_iterator::sentinel{};
3233  }
3234 };
3235 #endif
3236 
3237 }
3238 
3239 #endif
3240 
3241 #endif
3242 
3243 #include <type_traits>
3244 #include <tuple>
3245 #include <string_view>
3246 #include <string>
3247 #include <iterator>
3248 #include <iosfwd>
3249 #if __has_include(<charconv>)
3250 #include <charconv>
3251 #endif
3252 
3253 namespace ctre {
3254 
3255 constexpr auto is_random_accessible_f(const std::random_access_iterator_tag &) { return std::true_type{}; }
3256 constexpr auto is_random_accessible_f(...) { return std::false_type{}; }
3257 
3258 template <typename T> constexpr auto is_reverse_iterator_f(const std::reverse_iterator<T> &) { return std::true_type{}; }
3259 constexpr auto is_reverse_iterator_f(...) { return std::false_type{}; }
3260 
3261 template <typename T> constexpr bool is_random_accessible = decltype(is_random_accessible_f(std::declval<const T &>())){};
3262 template <typename T> constexpr bool is_reverse_iterator = decltype(is_reverse_iterator_f(std::declval<const T &>())){};
3263 
3264 struct not_matched_tag_t { };
3265 
3266 constexpr inline auto not_matched = not_matched_tag_t{};
3267 
3268 template <size_t Id, typename Name = void> struct captured_content {
3269  template <typename Iterator> class storage {
3270  Iterator _begin{};
3271  Iterator _end{};
3272 
3273  bool _matched{false};
3274  public:
3276 
3277  using name = Name;
3278 
3279  constexpr CTRE_FORCE_INLINE storage() noexcept {}
3280 
3281  constexpr CTRE_FORCE_INLINE void matched() noexcept {
3282  _matched = true;
3283  }
3284  constexpr CTRE_FORCE_INLINE void unmatch() noexcept {
3285  _matched = false;
3286  }
3287  constexpr CTRE_FORCE_INLINE void set_start(Iterator pos) noexcept {
3288  _begin = pos;
3289  }
3290  constexpr CTRE_FORCE_INLINE storage & set_end(Iterator pos) noexcept {
3291  _end = pos;
3292  return *this;
3293  }
3294  constexpr CTRE_FORCE_INLINE Iterator get_end() const noexcept {
3295  return _end;
3296  }
3297 
3298 
3299  constexpr auto begin() const noexcept {
3300  return _begin;
3301  }
3302  constexpr auto end() const noexcept {
3303  return _end;
3304  }
3305 
3306  constexpr explicit CTRE_FORCE_INLINE operator bool() const noexcept {
3307  return _matched;
3308  }
3309 
3310  template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data_unsafe() const noexcept {
3311  static_assert(!is_reverse_iterator<It>, "Iterator in your capture must not be reverse!");
3312 
3313  #if __cpp_char8_t >= 201811
3314  if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
3315  return _begin.ptr;
3316  } else {
3317  return &*_begin;
3318  }
3319  #else
3320  return &*_begin;
3321  #endif
3322  }
3323 
3324  template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
3325  constexpr bool must_be_contiguous_nonreverse_iterator = is_random_accessible<typename std::iterator_traits<It>::iterator_category> && !is_reverse_iterator<It>;
3326 
3327  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).");
3328 
3329  return data_unsafe();
3330  }
3331 
3332  constexpr CTRE_FORCE_INLINE auto size() const noexcept {
3333  return static_cast<size_t>(std::distance(begin(), end()));
3334  }
3335 
3336  constexpr CTRE_FORCE_INLINE size_t unit_size() const noexcept {
3337  #if __cpp_char8_t >= 201811
3338  if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
3339  return static_cast<size_t>(std::distance(_begin.ptr, _end.ptr));
3340  } else {
3341  return static_cast<size_t>(std::distance(begin(), end()));
3342  }
3343  #else
3344  return static_cast<size_t>(std::distance(begin(), end()));
3345  #endif
3346  }
3347 
3348 #if __has_include(<charconv>)
3349  template <typename R = int> constexpr CTRE_FORCE_INLINE auto to_number(int base = 10) const noexcept -> R {
3350  R result{0};
3351  const auto view = to_view();
3352  std::from_chars(view.data(), view.data() + view.size(), result, base);
3353  return result;
3354  }
3355 #endif
3356 
3357  template <typename T> struct identify;
3358 
3359  template <typename It = Iterator> constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
3360  // random access, because C++ (waving hands around)
3361  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>;
3362 
3363  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.");
3364 
3365  return std::basic_string_view<char_type>(data_unsafe(), static_cast<size_t>(unit_size()));
3366  }
3367 
3368  constexpr CTRE_FORCE_INLINE std::basic_string<char_type> to_string() const noexcept {
3369  #if __cpp_char8_t >= 201811
3370  if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
3371  return std::basic_string<char_type>(data_unsafe(), static_cast<size_t>(unit_size()));
3372  } else {
3373  return std::basic_string<char_type>(begin(), end());
3374  }
3375  #else
3376  return std::basic_string<char_type>(begin(), end());
3377  #endif
3378  }
3379 
3380  constexpr CTRE_FORCE_INLINE auto view() const noexcept {
3381  return to_view();
3382  }
3383 
3384  constexpr CTRE_FORCE_INLINE auto str() const noexcept {
3385  return to_string();
3386  }
3387 
3388  constexpr CTRE_FORCE_INLINE operator std::basic_string_view<char_type>() const noexcept {
3389  return to_view();
3390  }
3391 
3392  constexpr CTRE_FORCE_INLINE explicit operator std::basic_string<char_type>() const noexcept {
3393  return to_string();
3394  }
3395 
3396  constexpr CTRE_FORCE_INLINE static size_t get_id() noexcept {
3397  return Id;
3398  }
3399 
3400  friend CTRE_FORCE_INLINE constexpr bool operator==(const storage & lhs, std::basic_string_view<char_type> rhs) noexcept {
3401  return bool(lhs) ? lhs.view() == rhs : false;
3402  }
3403  friend CTRE_FORCE_INLINE constexpr bool operator!=(const storage & lhs, std::basic_string_view<char_type> rhs) noexcept {
3404  return bool(lhs) ? lhs.view() != rhs : false;
3405  }
3406  friend CTRE_FORCE_INLINE constexpr bool operator==(std::basic_string_view<char_type> lhs, const storage & rhs) noexcept {
3407  return bool(rhs) ? lhs == rhs.view() : false;
3408  }
3409  friend CTRE_FORCE_INLINE constexpr bool operator!=(std::basic_string_view<char_type> lhs, const storage & rhs) noexcept {
3410  return bool(rhs) ? lhs != rhs.view() : false;
3411  }
3412  friend CTRE_FORCE_INLINE std::ostream & operator<<(std::ostream & str, const storage & rhs) {
3413  return str << rhs.view();
3414  }
3415  };
3416 };
3417 
3418 struct capture_not_exists_tag { };
3419 
3420 static constexpr inline auto capture_not_exists = capture_not_exists_tag{};
3421 
3422 template <typename... Captures> struct captures;
3423 
3424 template <typename Head, typename... Tail> struct captures<Head, Tail...>: captures<Tail...> {
3425  Head head{};
3426  constexpr CTRE_FORCE_INLINE captures() noexcept { }
3427  template <size_t id> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3428  if constexpr (id == Head::get_id()) {
3429  return true;
3430  } else {
3431  return captures<Tail...>::template exists<id>();
3432  }
3433  }
3434  template <typename Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3435  if constexpr (std::is_same_v<Name, typename Head::name>) {
3436  return true;
3437  } else {
3438  return captures<Tail...>::template exists<Name>();
3439  }
3440  }
3441 #if CTRE_CNTTP_COMPILER_CHECK
3442  template <ctll::fixed_string Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3443 #else
3444  template <const auto & Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3445 #endif
3446  if constexpr (std::is_same_v<typename Head::name, void>) {
3447  return captures<Tail...>::template exists<Name>();
3448  } else {
3449  if constexpr (Head::name::name.is_same_as(Name)) {
3450  return true;
3451  } else {
3452  return captures<Tail...>::template exists<Name>();
3453  }
3454  }
3455  }
3456  template <size_t id> CTRE_FORCE_INLINE constexpr auto & select() noexcept {
3457  if constexpr (id == Head::get_id()) {
3458  return head;
3459  } else {
3460  return captures<Tail...>::template select<id>();
3461  }
3462  }
3463  template <typename Name> CTRE_FORCE_INLINE constexpr auto & select() noexcept {
3464  if constexpr (std::is_same_v<Name, typename Head::name>) {
3465  return head;
3466  } else {
3467  return captures<Tail...>::template select<Name>();
3468  }
3469  }
3470  template <size_t id> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3471  if constexpr (id == Head::get_id()) {
3472  return head;
3473  } else {
3474  return captures<Tail...>::template select<id>();
3475  }
3476  }
3477  template <typename Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3478  if constexpr (std::is_same_v<Name, typename Head::name>) {
3479  return head;
3480  } else {
3481  return captures<Tail...>::template select<Name>();
3482  }
3483  }
3484 #if CTRE_CNTTP_COMPILER_CHECK
3485  template <ctll::fixed_string Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3486 #else
3487  template <const auto & Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3488 #endif
3489  if constexpr (std::is_same_v<typename Head::name, void>) {
3490  return captures<Tail...>::template select<Name>();
3491  } else {
3492  if constexpr (Head::name::name.is_same_as(Name)) {
3493  return head;
3494  } else {
3495  return captures<Tail...>::template select<Name>();
3496  }
3497  }
3498  }
3499 };
3500 
3501 template <> struct captures<> {
3502  constexpr CTRE_FORCE_INLINE captures() noexcept { }
3503  template <size_t> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3504  return false;
3505  }
3506  template <typename> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3507  return false;
3508  }
3509 #if CTRE_CNTTP_COMPILER_CHECK
3510  template <ctll::fixed_string> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3511 #else
3512  template <const auto &> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
3513 #endif
3514  return false;
3515  }
3516  template <size_t> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3517  return capture_not_exists;
3518  }
3519  template <typename> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3520  return capture_not_exists;
3521  }
3522 #if CTRE_CNTTP_COMPILER_CHECK
3523  template <ctll::fixed_string> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3524 #else
3525  template <const auto &> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
3526 #endif
3527  return capture_not_exists;
3528  }
3529 };
3530 
3531 template <typename Iterator, typename... Captures> class regex_results {
3532  captures<captured_content<0>::template storage<Iterator>, typename Captures::template storage<Iterator>...> _captures{};
3533 public:
3535 
3536  constexpr CTRE_FORCE_INLINE regex_results() noexcept { }
3537  constexpr CTRE_FORCE_INLINE regex_results(not_matched_tag_t) noexcept { }
3538 
3539  // special constructor for deducting
3540  constexpr CTRE_FORCE_INLINE regex_results(Iterator, ctll::list<Captures...>) noexcept { }
3541 
3542  template <size_t Id, typename = std::enable_if_t<decltype(_captures)::template exists<Id>()>> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
3543  return _captures.template select<Id>();
3544  }
3545  template <typename Name, typename = std::enable_if_t<decltype(_captures)::template exists<Name>()>> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
3546  return _captures.template select<Name>();
3547  }
3548 #if CTRE_CNTTP_COMPILER_CHECK
3549  template <ctll::fixed_string Name, typename = std::enable_if_t<decltype(_captures)::template exists<Name>()>> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
3550 #else
3551  template <const auto & Name, typename = std::enable_if_t<decltype(_captures)::template exists<Name>()>> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
3552 #endif
3553  return _captures.template select<Name>();
3554  }
3555  static constexpr size_t count() noexcept {
3556  return sizeof...(Captures) + 1;
3557  }
3558  constexpr CTRE_FORCE_INLINE regex_results & matched() noexcept {
3559  _captures.template select<0>().matched();
3560  return *this;
3561  }
3562  constexpr CTRE_FORCE_INLINE regex_results & unmatch() noexcept {
3563  _captures.template select<0>().unmatch();
3564  return *this;
3565  }
3566  constexpr CTRE_FORCE_INLINE operator bool() const noexcept {
3567  return bool(_captures.template select<0>());
3568  }
3569 
3570  constexpr CTRE_FORCE_INLINE operator std::basic_string_view<char_type>() const noexcept {
3571  return to_view();
3572  }
3573 
3574  constexpr CTRE_FORCE_INLINE explicit operator std::basic_string<char_type>() const noexcept {
3575  return to_string();
3576  }
3577 
3578 #if __has_include(<charconv>)
3579  template <typename R = int> constexpr CTRE_FORCE_INLINE auto to_number(int base = 10) const noexcept -> R {
3580  return _captures.template select<0>().template to_number<R>(base);
3581  }
3582 #endif
3583 
3584  constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
3585  return _captures.template select<0>().to_view();
3586  }
3587 
3588  constexpr CTRE_FORCE_INLINE auto to_string() const noexcept {
3589  return _captures.template select<0>().to_string();
3590  }
3591 
3592  constexpr CTRE_FORCE_INLINE auto view() const noexcept {
3593  return _captures.template select<0>().view();
3594  }
3595 
3596  constexpr CTRE_FORCE_INLINE auto str() const noexcept {
3597  return _captures.template select<0>().to_string();
3598  }
3599 
3600  constexpr CTRE_FORCE_INLINE size_t size() const noexcept {
3601  return _captures.template select<0>().size();
3602  }
3603 
3604  constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
3605  return _captures.template select<0>().data();
3606  }
3607 
3608  constexpr CTRE_FORCE_INLINE regex_results & set_start_mark(Iterator pos) noexcept {
3609  _captures.template select<0>().set_start(pos);
3610  return *this;
3611  }
3612  constexpr CTRE_FORCE_INLINE regex_results & set_end_mark(Iterator pos) noexcept {
3613  _captures.template select<0>().set_end(pos);
3614  return *this;
3615  }
3616  constexpr CTRE_FORCE_INLINE Iterator get_end_position() const noexcept {
3617  return _captures.template select<0>().get_end();
3618  }
3619  template <size_t Id> CTRE_FORCE_INLINE constexpr regex_results & start_capture(Iterator pos) noexcept {
3620  _captures.template select<Id>().set_start(pos);
3621  return *this;
3622  }
3623  template <size_t Id> CTRE_FORCE_INLINE constexpr regex_results & end_capture(Iterator pos) noexcept {
3624  _captures.template select<Id>().set_end(pos).matched();
3625  return *this;
3626  }
3627  constexpr auto begin() const noexcept {
3628  return _captures.template select<0>().begin();
3629  }
3630  constexpr auto end() const noexcept {
3631  return _captures.template select<0>().end();
3632  }
3633  friend CTRE_FORCE_INLINE constexpr bool operator==(const regex_results & lhs, std::basic_string_view<char_type> rhs) noexcept {
3634  return bool(lhs) ? lhs.view() == rhs : false;
3635  }
3636  friend CTRE_FORCE_INLINE constexpr bool operator!=(const regex_results & lhs, std::basic_string_view<char_type> rhs) noexcept {
3637  return bool(lhs) ? lhs.view() != rhs : true;
3638  }
3639  friend CTRE_FORCE_INLINE constexpr bool operator==(std::basic_string_view<char_type> lhs, const regex_results & rhs) noexcept {
3640  return bool(rhs) ? lhs == rhs.view() : false;
3641  }
3642  friend CTRE_FORCE_INLINE constexpr bool operator!=(std::basic_string_view<char_type> lhs, const regex_results & rhs) noexcept {
3643  return bool(rhs) ? lhs != rhs.view() : true;
3644  }
3645  friend CTRE_FORCE_INLINE std::ostream & operator<<(std::ostream & str, const regex_results & rhs) {
3646  return str << rhs.view();
3647  }
3648 };
3649 
3650 template <size_t Id, typename Iterator, typename... Captures> constexpr auto get(const regex_results<Iterator, Captures...> & results) noexcept {
3651  return results.template get<Id>();
3652 }
3653 
3654 template <typename Iterator, typename... Captures> regex_results(Iterator, ctll::list<Captures...>) -> regex_results<Iterator, Captures...>;
3655 
3656 template <typename ResultIterator, typename Pattern> using return_type = decltype(regex_results(std::declval<ResultIterator>(), find_captures(Pattern{})));
3657 
3658 }
3659 
3660 // support for structured bindings
3661 
3662 #ifndef __EDG__
3663 #ifdef __clang__
3664 #pragma clang diagnostic push
3665 #pragma clang diagnostic ignored "-Wmismatched-tags"
3666 #endif
3667 
3668 namespace std {
3669  template <typename... Captures> struct tuple_size<ctre::regex_results<Captures...>> : public std::integral_constant<size_t, ctre::regex_results<Captures...>::count()> { };
3670 
3671  template <size_t N, typename... Captures> struct tuple_element<N, ctre::regex_results<Captures...>> {
3672  public:
3673  using type = decltype(
3674  std::declval<const ctre::regex_results<Captures...> &>().template get<N>()
3675  );
3676  };
3677 }
3678 
3679 #ifdef __clang__
3680 #pragma clang diagnostic pop
3681 #endif
3682 #endif
3683 
3684 #endif
3685 
3686 #ifndef CTRE__FIND_CAPTURES__HPP
3687 #define CTRE__FIND_CAPTURES__HPP
3688 
3689 namespace ctre {
3690 
3691 template <typename Pattern> constexpr auto find_captures(Pattern) noexcept {
3692  return find_captures(ctll::list<Pattern>(), ctll::list<>());
3693 }
3694 
3695 template <typename... Output> constexpr auto find_captures(ctll::list<>, ctll::list<Output...> output) noexcept {
3696  return output;
3697 }
3698 
3699 template <auto... String, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<string<String...>, Tail...>, Output output) noexcept {
3700  return find_captures(ctll::list<Tail...>(), output);
3701 }
3702 
3703 template <typename... Options, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<select<Options...>, Tail...>, Output output) noexcept {
3704  return find_captures(ctll::list<Options..., Tail...>(), output);
3705 }
3706 
3707 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<optional<Content...>, Tail...>, Output output) noexcept {
3708  return find_captures(ctll::list<Content..., Tail...>(), output);
3709 }
3710 
3711 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_optional<Content...>, Tail...>, Output output) noexcept {
3712  return find_captures(ctll::list<Content..., Tail...>(), output);
3713 }
3714 
3715 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<sequence<Content...>, Tail...>, Output output) noexcept {
3716  return find_captures(ctll::list<Content..., Tail...>(), output);
3717 }
3718 
3719 template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<empty, Tail...>, Output output) noexcept {
3720  return find_captures(ctll::list<Tail...>(), output);
3721 }
3722 
3723 template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<assert_subject_begin, Tail...>, Output output) noexcept {
3724  return find_captures(ctll::list<Tail...>(), output);
3725 }
3726 
3727 template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<assert_subject_end, Tail...>, Output output) noexcept {
3728  return find_captures(ctll::list<Tail...>(), output);
3729 }
3730 
3731 // , typename = std::enable_if_t<(MatchesCharacter<CharacterLike>::template value<char>)
3732 template <typename CharacterLike, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<CharacterLike, Tail...>, Output output) noexcept {
3733  return find_captures(ctll::list<Tail...>(), output);
3734 }
3735 
3736 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<plus<Content...>, Tail...>, Output output) noexcept {
3737  return find_captures(ctll::list<Content..., Tail...>(), output);
3738 }
3739 
3740 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<star<Content...>, Tail...>, Output output) noexcept {
3741  return find_captures(ctll::list<Content..., Tail...>(), output);
3742 }
3743 
3744 template <size_t A, size_t B, typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<repeat<A,B,Content...>, Tail...>, Output output) noexcept {
3745  return find_captures(ctll::list<Content..., Tail...>(), output);
3746 }
3747 
3748 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_plus<Content...>, Tail...>, Output output) noexcept {
3749  return find_captures(ctll::list<Content..., Tail...>(), output);
3750 }
3751 
3752 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_star<Content...>, Tail...>, Output output) noexcept {
3753  return find_captures(ctll::list<Content..., Tail...>(), output);
3754 }
3755 
3756 template <size_t A, size_t B, typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_repeat<A,B,Content...>, Tail...>, Output output) noexcept {
3757  return find_captures(ctll::list<Content..., Tail...>(), output);
3758 }
3759 
3760 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<possessive_plus<Content...>, Tail...>, Output output) noexcept {
3761  return find_captures(ctll::list<Content..., Tail...>(), output);
3762 }
3763 
3764 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<possessive_star<Content...>, Tail...>, Output output) noexcept {
3765  return find_captures(ctll::list<Content..., Tail...>(), output);
3766 }
3767 
3768 template <size_t A, size_t B, typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<possessive_repeat<A,B,Content...>, Tail...>, Output output) noexcept {
3769  return find_captures(ctll::list<Content..., Tail...>(), output);
3770 }
3771 
3772 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lookahead_positive<Content...>, Tail...>, Output output) noexcept {
3773  return find_captures(ctll::list<Content..., Tail...>(), output);
3774 }
3775 
3776 template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lookahead_negative<Content...>, Tail...>, Output output) noexcept {
3777  return find_captures(ctll::list<Content..., Tail...>(), output);
3778 }
3779 
3780 template <size_t Id, typename... Content, typename... Tail, typename... Output> constexpr auto find_captures(ctll::list<capture<Id,Content...>, Tail...>, ctll::list<Output...>) noexcept {
3781  return find_captures(ctll::list<Content..., Tail...>(), ctll::list<Output..., captured_content<Id>>());
3782 }
3783 
3784 template <size_t Id, typename Name, typename... Content, typename... Tail, typename... Output> constexpr auto find_captures(ctll::list<capture_with_name<Id,Name,Content...>, Tail...>, ctll::list<Output...>) noexcept {
3785  return find_captures(ctll::list<Content..., Tail...>(), ctll::list<Output..., captured_content<Id, Name>>());
3786 }
3787 
3788 }
3789 
3790 #endif
3791 
3792 #ifndef CTRE__FIRST__HPP
3793 #define CTRE__FIRST__HPP
3794 
3795 namespace ctre {
3796 
3797 struct can_be_anything {};
3798 
3799 
3800 template <typename... Content>
3801 constexpr auto first(ctll::list<Content...> l, ctll::list<>) noexcept {
3802  return l;
3803 }
3804 
3805 template <typename... Content, typename... Tail>
3806 constexpr auto first(ctll::list<Content...> l, ctll::list<accept, Tail...>) noexcept {
3807  return l;
3808 }
3809 
3810 template <typename... Content, typename... Tail>
3811 constexpr auto first(ctll::list<Content...> l, ctll::list<end_mark, Tail...>) noexcept {
3812  return l;
3813 }
3814 
3815 template <typename... Content, typename... Tail>
3817  return l;
3818 }
3819 
3820 template <typename... Content, typename... Tail>
3822  return l;
3823 }
3824 
3825 template <typename... Content, size_t Id, typename... Tail>
3826 constexpr auto first(ctll::list<Content...> l, ctll::list<numeric_mark<Id>, Tail...>) noexcept {
3827  return first(l, ctll::list<Tail...>{});
3828 }
3829 
3830 // empty
3831 template <typename... Content, typename... Tail>
3832 constexpr auto first(ctll::list<Content...> l, ctll::list<empty, Tail...>) noexcept {
3833  return first(l, ctll::list<Tail...>{});
3834 }
3835 
3836 // boundary
3837 template <typename... Content, typename CharLike, typename... Tail>
3838 constexpr auto first(ctll::list<Content...> l, ctll::list<boundary<CharLike>, Tail...>) noexcept {
3839  return first(l, ctll::list<Tail...>{});
3840 }
3841 
3842 // asserts
3843 template <typename... Content, typename... Tail>
3845  return first(l, ctll::list<Tail...>{});
3846 }
3847 
3848 template <typename... Content, typename... Tail>
3850  return l;
3851 }
3852 
3853 template <typename... Content, typename... Tail>
3855  // FIXME allow endline here
3856  return l;
3857 }
3858 
3859 template <typename... Content, typename... Tail>
3861  // FIXME line begin is a bit different than subject begin
3862  return first(l, ctll::list<Tail...>{});
3863 }
3864 
3865 template <typename... Content, typename... Tail>
3867  // FIXME line end is a bit different than subject begin
3868  return l;
3869 }
3870 
3871 // sequence
3872 template <typename... Content, typename... Seq, typename... Tail>
3873 constexpr auto first(ctll::list<Content...> l, ctll::list<sequence<Seq...>, Tail...>) noexcept {
3874  return first(l, ctll::list<Seq..., Tail...>{});
3875 }
3876 
3877 // plus
3878 template <typename... Content, typename... Seq, typename... Tail>
3879 constexpr auto first(ctll::list<Content...> l, ctll::list<plus<Seq...>, Tail...>) noexcept {
3880  return first(l, ctll::list<Seq..., Tail...>{});
3881 }
3882 
3883 // lazy_plus
3884 template <typename... Content, typename... Seq, typename... Tail>
3885 constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_plus<Seq...>, Tail...>) noexcept {
3886  return first(l, ctll::list<Seq..., Tail...>{});
3887 }
3888 
3889 // possessive_plus
3890 template <typename... Content, typename... Seq, typename... Tail>
3891 constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_plus<Seq...>, Tail...>) noexcept {
3892  return first(l, ctll::list<Seq..., Tail...>{});
3893 }
3894 
3895 // star
3896 template <typename... Content, typename... Seq, typename... Tail>
3897 constexpr auto first(ctll::list<Content...> l, ctll::list<star<Seq...>, Tail...>) noexcept {
3899 }
3900 
3901 // lazy_star
3902 template <typename... Content, typename... Seq, typename... Tail>
3903 constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_star<Seq...>, Tail...>) noexcept {
3905 }
3906 
3907 // possessive_star
3908 template <typename... Content, typename... Seq, typename... Tail>
3909 constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_star<Seq...>, Tail...>) noexcept {
3911 }
3912 
3913 // lazy_repeat
3914 template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail>
3915 constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_repeat<A, B, Seq...>, Tail...>) noexcept {
3916  return first(l, ctll::list<Seq..., Tail...>{});
3917 }
3918 
3919 template <typename... Content, size_t B, typename... Seq, typename... Tail>
3920 constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_repeat<0, B, Seq...>, Tail...>) noexcept {
3922 }
3923 
3924 // possessive_repeat
3925 template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail>
3926 constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_repeat<A, B, Seq...>, Tail...>) noexcept {
3927  return first(l, ctll::list<Seq..., Tail...>{});
3928 }
3929 
3930 template <typename... Content, size_t B, typename... Seq, typename... Tail>
3931 constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_repeat<0, B, Seq...>, Tail...>) noexcept {
3933 }
3934 
3935 // repeat
3936 template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail>
3937 constexpr auto first(ctll::list<Content...> l, ctll::list<repeat<A, B, Seq...>, Tail...>) noexcept {
3938  return first(l, ctll::list<Seq..., Tail...>{});
3939 }
3940 
3941 template <typename... Content, size_t B, typename... Seq, typename... Tail>
3942 constexpr auto first(ctll::list<Content...> l, ctll::list<repeat<0, B, Seq...>, Tail...>) noexcept {
3944 }
3945 
3946 // lookahead_positive
3947 template <typename... Content, typename... Seq, typename... Tail>
3948 constexpr auto first(ctll::list<Content...>, ctll::list<lookahead_positive<Seq...>, Tail...>) noexcept {
3949  return ctll::list<can_be_anything>{};
3950 }
3951 
3952 // lookbehind_negative TODO fixme
3953 template <typename... Content, typename... Seq, typename... Tail>
3954 constexpr auto first(ctll::list<Content...>, ctll::list<lookbehind_negative<Seq...>, Tail...>) noexcept {
3955  return ctll::list<can_be_anything>{};
3956 }
3957 
3958 // lookbehind_positive
3959 template <typename... Content, typename... Seq, typename... Tail>
3960 constexpr auto first(ctll::list<Content...>, ctll::list<lookbehind_positive<Seq...>, Tail...>) noexcept {
3961  return ctll::list<can_be_anything>{};
3962 }
3963 
3964 // lookahead_negative TODO fixme
3965 template <typename... Content, typename... Seq, typename... Tail>
3966 constexpr auto first(ctll::list<Content...>, ctll::list<lookahead_negative<Seq...>, Tail...>) noexcept {
3967  return ctll::list<can_be_anything>{};
3968 }
3969 
3970 // capture
3971 template <typename... Content, size_t Id, typename... Seq, typename... Tail>
3972 constexpr auto first(ctll::list<Content...> l, ctll::list<capture<Id, Seq...>, Tail...>) noexcept {
3973  return first(l, ctll::list<Seq..., Tail...>{});
3974 }
3975 
3976 template <typename... Content, size_t Id, typename Name, typename... Seq, typename... Tail>
3977 constexpr auto first(ctll::list<Content...> l, ctll::list<capture_with_name<Id, Name, Seq...>, Tail...>) noexcept {
3978  return first(l, ctll::list<Seq..., Tail...>{});
3979 }
3980 
3981 // backreference
3982 template <typename... Content, size_t Id, typename... Tail>
3983 constexpr auto first(ctll::list<Content...>, ctll::list<back_reference<Id>, Tail...>) noexcept {
3984  return ctll::list<can_be_anything>{};
3985 }
3986 
3987 template <typename... Content, typename Name, typename... Tail>
3988 constexpr auto first(ctll::list<Content...>, ctll::list<back_reference_with_name<Name>, Tail...>) noexcept {
3989  return ctll::list<can_be_anything>{};
3990 }
3991 
3992 // string First extraction
3993 template <typename... Content, auto First, auto... String, typename... Tail>
3994 constexpr auto first(ctll::list<Content...>, ctll::list<string<First, String...>, Tail...>) noexcept {
3995  return ctll::list<Content..., character<First>>{};
3996 }
3997 
3998 template <typename... Content, typename... Tail>
3999 constexpr auto first(ctll::list<Content...> l, ctll::list<string<>, Tail...>) noexcept {
4000  return first(l, ctll::list<Tail...>{});
4001 }
4002 
4003 // optional
4004 template <typename... Content, typename... Opt, typename... Tail>
4005 constexpr auto first(ctll::list<Content...> l, ctll::list<optional<Opt...>, Tail...>) noexcept {
4007 }
4008 
4009 template <typename... Content, typename... Opt, typename... Tail>
4010 constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_optional<Opt...>, Tail...>) noexcept {
4012 }
4013 
4014 // select (alternation)
4015 template <typename... Content, typename SHead, typename... STail, typename... Tail>
4016 constexpr auto first(ctll::list<Content...> l, ctll::list<select<SHead, STail...>, Tail...>) noexcept {
4017  return first(first(l, ctll::list<SHead, Tail...>{}), ctll::list<select<STail...>, Tail...>{});
4018 }
4019 
4020 template <typename... Content, typename... Tail>
4021 constexpr auto first(ctll::list<Content...> l, ctll::list<select<>, Tail...>) noexcept {
4022  return l;
4023 }
4024 
4025 // unicode property => anything
4026 template <typename... Content, typename PropertyType, PropertyType Property, typename... Tail>
4027 constexpr auto first(ctll::list<Content...>, ctll::list<ctre::binary_property<PropertyType, Property>, Tail...>) noexcept {
4028  return ctll::list<can_be_anything>{};
4029 }
4030 
4031 template <typename... Content, typename PropertyType, PropertyType Property, auto Value, typename... Tail>
4032 constexpr auto first(ctll::list<Content...>, ctll::list<ctre::property<PropertyType, Property, Value>, Tail...>) noexcept {
4033  return ctll::list<can_be_anything>{};
4034 }
4035 
4036 // characters / sets
4037 
4038 template <typename... Content, auto V, typename... Tail>
4039 constexpr auto first(ctll::list<Content...>, ctll::list<character<V>, Tail...>) noexcept {
4040  return ctll::list<Content..., character<V>>{};
4041 }
4042 
4043 template <typename... Content, auto... Values, typename... Tail>
4044 constexpr auto first(ctll::list<Content...>, ctll::list<enumeration<Values...>, Tail...>) noexcept {
4045  return ctll::list<Content..., character<Values>...>{};
4046 }
4047 
4048 template <typename... Content, typename... SetContent, typename... Tail>
4049 constexpr auto first(ctll::list<Content...>, ctll::list<set<SetContent...>, Tail...>) noexcept {
4050  return ctll::list<Content..., SetContent...>{};
4051 }
4052 
4053 template <typename... Content, auto A, auto B, typename... Tail>
4054 constexpr auto first(ctll::list<Content...>, ctll::list<char_range<A,B>, Tail...>) noexcept {
4055  return ctll::list<Content..., char_range<A,B>>{};
4056 }
4057 
4058 template <typename... Content, typename... Tail>
4059 constexpr auto first(ctll::list<Content...>, ctll::list<any, Tail...>) noexcept {
4060  return ctll::list<can_be_anything>{};
4061 }
4062 
4063 // negative
4064 template <typename... Content, typename... SetContent, typename... Tail>
4065 constexpr auto first(ctll::list<Content...>, ctll::list<negate<SetContent...>, Tail...>) noexcept {
4066  return ctll::list<Content..., negative_set<SetContent...>>{};
4067 }
4068 
4069 template <typename... Content, typename... SetContent, typename... Tail>
4070 constexpr auto first(ctll::list<Content...>, ctll::list<negative_set<SetContent...>, Tail...>) noexcept {
4071  return ctll::list<Content..., negative_set<SetContent...>>{};
4072 }
4073 
4074 // user facing interface
4075 template <typename... Content> constexpr auto calculate_first(Content...) noexcept {
4076  return first(ctll::list<>{}, ctll::list<Content...>{});
4077 }
4078 
4079 // calculate mutual exclusivity
4080 template <typename... Content> constexpr size_t calculate_size_of_first(ctre::negative_set<Content...>) {
4081  return 1 + calculate_size_of_first(ctre::set<Content...>{});
4082 }
4083 
4084 template <auto... V> constexpr size_t calculate_size_of_first(ctre::enumeration<V...>) {
4085  return sizeof...(V);
4086 }
4087 
4088 constexpr size_t calculate_size_of_first(...) {
4089  return 1;
4090 }
4091 
4092 template <typename... Content> constexpr size_t calculate_size_of_first(ctll::list<Content...>) {
4093  return (calculate_size_of_first(Content{}) + ... + 0);
4094 }
4095 
4096 template <typename... Content> constexpr size_t calculate_size_of_first(ctre::set<Content...>) {
4097  return (calculate_size_of_first(Content{}) + ... + 0);
4098 }
4099 
4100 template <auto A, typename CB> constexpr int64_t negative_helper(ctre::character<A>, CB & cb, int64_t start) {
4101  if (A != (std::numeric_limits<int64_t>::min)()) {
4102  if (start < A) {
4103  cb(start, A-1);
4104  }
4105  }
4106  if (A != (std::numeric_limits<int64_t>::max)()) {
4107  return A+1;
4108  } else {
4109  return A;
4110  }
4111 }
4112 
4113 template <auto A, auto B, typename CB> constexpr int64_t negative_helper(ctre::char_range<A,B>, CB & cb, int64_t start) {
4114  if (A != (std::numeric_limits<int64_t>::min)()) {
4115  if (start < A) {
4116  cb(start, A-1);
4117  }
4118  }
4119  if (B != (std::numeric_limits<int64_t>::max)()) {
4120  return B+1;
4121  } else {
4122  return B;
4123  }
4124 }
4125 
4126 template <auto Head, auto... Tail, typename CB> constexpr int64_t negative_helper(ctre::enumeration<Head, Tail...>, CB & cb, int64_t start) {
4127  int64_t nstart = negative_helper(ctre::character<Head>{}, cb, start);
4128  return negative_helper(ctre::enumeration<Tail...>{}, cb, nstart);
4129 }
4130 
4131 template <typename CB> constexpr int64_t negative_helper(ctre::enumeration<>, CB &, int64_t start) {
4132  return start;
4133 }
4134 
4135 template <typename CB> constexpr int64_t negative_helper(ctre::set<>, CB &, int64_t start) {
4136  return start;
4137 }
4138 
4139 template <typename PropertyType, PropertyType Property, typename CB>
4140 constexpr auto negative_helper(ctre::binary_property<PropertyType, Property>, CB &&, int64_t start) {
4141  return start;
4142 }
4143 
4144 template <typename PropertyType, PropertyType Property, auto Value, typename CB>
4145 constexpr auto negative_helper(ctre::property<PropertyType, Property, Value>, CB &&, int64_t start) {
4146  return start;
4147 }
4148 
4149 template <typename Head, typename... Rest, typename CB> constexpr int64_t negative_helper(ctre::set<Head, Rest...>, CB & cb, int64_t start) {
4150  start = negative_helper(Head{}, cb, start);
4151  return negative_helper(ctre::set<Rest...>{}, cb, start);
4152 }
4153 
4154 template <typename Head, typename... Rest, typename CB> constexpr void negative_helper(ctre::negative_set<Head, Rest...>, CB && cb, int64_t start = (std::numeric_limits<int64_t>::min)()) {
4155  start = negative_helper(Head{}, cb, start);
4156  negative_helper(ctre::negative_set<Rest...>{}, std::forward<CB>(cb), start);
4157 }
4158 
4159 template <typename CB> constexpr void negative_helper(ctre::negative_set<>, CB && cb, int64_t start = (std::numeric_limits<int64_t>::min)()) {
4160  if (start < (std::numeric_limits<int64_t>::max)()) {
4161  cb(start, (std::numeric_limits<int64_t>::max)());
4162  }
4163 }
4164 
4165 // simple fixed set
4166 // TODO: this needs some optimizations
4167 template <size_t Capacity> class point_set {
4168  struct point {
4169  int64_t low{};
4170  int64_t high{};
4171  constexpr bool operator<(const point & rhs) const {
4172  return low < rhs.low;
4173  }
4174  constexpr point() { }
4175  constexpr point(int64_t l, int64_t h): low{l}, high{h} { }
4176  };
4177  point points[Capacity+1]{};
4178  size_t used{0};
4179  constexpr point * begin() {
4180  return points;
4181  }
4182  constexpr point * begin() const {
4183  return points;
4184  }
4185  constexpr point * end() {
4186  return points + used;
4187  }
4188  constexpr point * end() const {
4189  return points + used;
4190  }
4191  constexpr point * lower_bound(point obj) {
4192  auto first = begin();
4193  auto last = end();
4194  auto it = first;
4195  auto count = std::distance(first, last);
4196  while (count != 0) {
4197  it = first;
4198  auto step = count / 2;
4199  std::advance(it, step);
4200  if (*it < obj) {
4201  first = ++it;
4202  count -= step + 1;
4203  } else {
4204  count = step;
4205  }
4206  }
4207  return it;
4208  }
4209  constexpr point * insert_point(int64_t position, int64_t other) {
4210  point obj{position, other};
4211  auto it = lower_bound(obj);
4212  if (it == end()) {
4213  *it = obj;
4214  used++;
4215  return it;
4216  } else {
4217  auto out = it;
4218  auto e = end();
4219  while (it != e) {
4220  auto tmp = *it;
4221  *it = obj;
4222  obj = tmp;
4223  //std::swap(*it, obj);
4224  it++;
4225  }
4226  auto tmp = *it;
4227  *it = obj;
4228  obj = tmp;
4229  //std::swap(*it, obj);
4230 
4231  used++;
4232  return out;
4233  }
4234  }
4235 public:
4236  constexpr point_set() { }
4237  constexpr void insert(int64_t low, int64_t high) {
4238  insert_point(low, high);
4239  //insert_point(high, low);
4240  }
4241  constexpr bool check(int64_t low, int64_t high) {
4242  for (auto r: *this) {
4243  if (r.low <= low && low <= r.high) {
4244  return true;
4245  } else if (r.low <= high && high <= r.high) {
4246  return true;
4247  } else if (low <= r.low && r.low <= high) {
4248  return true;
4249  } else if (low <= r.high && r.high <= high) {
4250  return true;
4251  }
4252  }
4253  return false;
4254  }
4255 
4256 
4257  template <auto V> constexpr bool check(ctre::character<V>) {
4258  return check(V,V);
4259  }
4260  template <auto A, auto B> constexpr bool check(ctre::char_range<A,B>) {
4261  return check(A,B);
4262  }
4263  constexpr bool check(can_be_anything) {
4264  return used > 0;
4265  }
4266  template <typename... Content> constexpr bool check(ctre::negative_set<Content...> nset) {
4267  bool collision = false;
4268  negative_helper(nset, [&](int64_t low, int64_t high){
4269  collision |= this->check(low, high);
4270  });
4271  return collision;
4272  }
4273  template <auto... V> constexpr bool check(ctre::enumeration<V...>) {
4274 
4275  return (check(V,V) || ... || false);
4276  }
4277  template <typename... Content> constexpr bool check(ctll::list<Content...>) {
4278  return (check(Content{}) || ... || false);
4279  }
4280  template <typename... Content> constexpr bool check(ctre::set<Content...>) {
4281  return (check(Content{}) || ... || false);
4282  }
4283 
4284 
4285  template <auto V> constexpr void populate(ctre::character<V>) {
4286  insert(V,V);
4287  }
4288  template <auto A, auto B> constexpr void populate(ctre::char_range<A,B>) {
4289  insert(A,B);
4290  }
4291  constexpr void populate(...) {
4292  points[0].low = (std::numeric_limits<int64_t>::min)();
4293  points[0].high = (std::numeric_limits<int64_t>::max)();
4294  used = 1;
4295  }
4296  template <typename... Content> constexpr void populate(ctre::negative_set<Content...> nset) {
4297  negative_helper(nset, [&](int64_t low, int64_t high){
4298  this->insert(low, high);
4299  });
4300  }
4301  template <typename... Content> constexpr void populate(ctre::set<Content...>) {
4302  (populate(Content{}), ...);
4303  }
4304  template <typename... Content> constexpr void populate(ctll::list<Content...>) {
4305  (populate(Content{}), ...);
4306  }
4307 };
4308 
4309 template <typename... A, typename... B> constexpr bool collides(ctll::list<A...> rhs, ctll::list<B...> lhs) {
4310  constexpr size_t capacity = calculate_size_of_first(rhs);
4311 
4312  point_set<capacity> set;
4313  set.populate(rhs);
4314 
4315  return set.check(lhs);
4316 }
4317 
4318 }
4319 
4320 #endif
4321 
4322 #include <iterator>
4323 
4324 // remove me when MSVC fix the constexpr bug
4325 #ifdef _MSC_VER
4326 #ifndef CTRE_MSVC_GREEDY_WORKAROUND
4327 #define CTRE_MSVC_GREEDY_WORKAROUND
4328 #endif
4329 #endif
4330 
4331 namespace ctre {
4332 
4333 template <size_t Limit> constexpr CTRE_FORCE_INLINE bool less_than_or_infinite([[maybe_unused]] size_t i) noexcept {
4334  if constexpr (Limit == 0) {
4335  // infinite
4336  return true;
4337  } else {
4338  return i < Limit;
4339  }
4340 }
4341 
4342 template <size_t Limit> constexpr CTRE_FORCE_INLINE bool less_than([[maybe_unused]] size_t i) noexcept {
4343  if constexpr (Limit == 0) {
4344  // infinite
4345  return false;
4346  } else {
4347  return i < Limit;
4348  }
4349 }
4350 
4351 constexpr bool is_bidirectional(const std::bidirectional_iterator_tag &) { return true; }
4352 constexpr bool is_bidirectional(...) { return false; }
4353 
4354 // sink for making the errors shorter
4355 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator>
4356 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ...) noexcept {
4357  return not_matched;
4358 }
4359 
4360 // if we found "accept" object on stack => ACCEPT
4361 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator>
4362 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list<accept>) noexcept {
4363  return captures.matched();
4364 }
4365 
4366 // if we found "reject" object on stack => REJECT
4367 template <typename R, typename... Rest, typename BeginIterator, typename Iterator, typename EndIterator>
4368 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list<reject, Rest...>) noexcept {
4369  return not_matched;
4370 }
4371 
4372 // mark start of outer capture
4373 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4374 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<start_mark, Tail...>) noexcept {
4375  return evaluate(begin, current, last, f, captures.set_start_mark(current), ctll::list<Tail...>());
4376 }
4377 
4378 // mark end of outer capture
4379 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4380 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<end_mark, Tail...>) noexcept {
4381  return evaluate(begin, current, last, f, captures.set_end_mark(current), ctll::list<Tail...>());
4382 }
4383 
4384 // mark end of cycle
4385 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4386 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator current, const EndIterator, [[maybe_unused]] const flags & f, R captures, ctll::list<end_cycle_mark>) noexcept {
4387  if (cannot_be_empty_match(f)) {
4388  return not_matched;
4389  }
4390 
4391  return captures.set_end_mark(current).matched();
4392 }
4393 
4394 // matching everything which behave as a one character matcher
4395 
4396 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename CharacterLike, typename... Tail, typename = std::enable_if_t<(MatchesCharacter<CharacterLike>::template value<decltype(*std::declval<Iterator>())>)>>
4397 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<CharacterLike, Tail...>) noexcept {
4398  if (current == last) return not_matched;
4399  if (!CharacterLike::match_char(*current, f)) return not_matched;
4400 
4401  return evaluate(begin, ++current, last, consumed_something(f), captures, ctll::list<Tail...>());
4402 }
4403 
4404 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4405 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<any, Tail...>) noexcept {
4406  if (current == last) return not_matched;
4407 
4408  if (multiline_mode(f)) {
4409  // TODO add support for different line ending and unicode (in a future unicode mode)
4410  if (*current == '\n') return not_matched;
4411  }
4412  return evaluate(begin, ++current, last, consumed_something(f), captures, ctll::list<Tail...>());
4413 }
4414 
4415 // matching strings in patterns
4416 template <auto... String, typename Iterator, typename EndIterator> constexpr CTRE_FORCE_INLINE bool match_string([[maybe_unused]] Iterator & current, [[maybe_unused]] const EndIterator last, [[maybe_unused]] const flags & f) {
4417  return ((current != last && character<String>::match_char(*current++, f)) && ... && true);
4418 }
4419 
4420 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, auto... String, typename... Tail>
4421 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list<string<String...>, Tail...>) noexcept {
4422  if (!match_string<String...>(current, last, f)) {
4423  return not_matched;
4424  }
4425 
4426  return evaluate(begin, current, last, consumed_something(f, sizeof...(String) > 0), captures, ctll::list<Tail...>());
4427 }
4428 
4429 // matching select in patterns
4430 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename HeadOptions, typename... TailOptions, typename... Tail>
4431 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<select<HeadOptions, TailOptions...>, Tail...>) noexcept {
4432  if (auto r = evaluate(begin, current, last, f, captures, ctll::list<HeadOptions, Tail...>())) {
4433  return r;
4434  } else {
4435  return evaluate(begin, current, last, f, captures, ctll::list<select<TailOptions...>, Tail...>());
4436  }
4437 }
4438 
4439 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4440 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list<select<>, Tail...>) noexcept {
4441  // no previous option was matched => REJECT
4442  return not_matched;
4443 }
4444 
4445 // matching sequence in patterns
4446 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename HeadContent, typename... TailContent, typename... Tail>
4447 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<sequence<HeadContent, TailContent...>, Tail...>) noexcept {
4448  if constexpr (sizeof...(TailContent) > 0) {
4449  return evaluate(begin, current, last, f, captures, ctll::list<HeadContent, sequence<TailContent...>, Tail...>());
4450  } else {
4451  return evaluate(begin, current, last, f, captures, ctll::list<HeadContent, Tail...>());
4452  }
4453 }
4454 
4455 // matching empty in patterns
4456 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4457 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<empty, Tail...>) noexcept {
4458  return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
4459 }
4460 
4461 // matching asserts
4462 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4463 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<assert_subject_begin, Tail...>) noexcept {
4464  if (begin != current) {
4465  return not_matched;
4466  }
4467  return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
4468 }
4469 
4470 template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail>
4471 constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<assert_subject_end, Tail...>) noexcept {
4472  if (last != current) {
4473