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