LCOV - code coverage report
Current view: top level - borrowed/ctre - ctre.hpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 0.0 % 129 0
Test Date: 2026-11-02 18:19:43 Functions: 0.0 % 2 0
Legend: Lines:     hit not hit

            Line data    Source code
       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              : #ifndef CTLL_IN_A_MODULE
     237              : #include <utility>
     238              : #include <cstddef>
     239              : #include <string_view>
     240              : #include <array>
     241              : #include <cstdint>
     242              : #endif
     243              : 
     244              : #ifndef CTLL__UTILITIES__HPP
     245              : #define CTLL__UTILITIES__HPP
     246              : 
     247              : #ifndef CTLL_IN_A_MODULE
     248              : #include <type_traits>
     249              : #endif
     250              : 
     251              : #ifdef CTLL_IN_A_MODULE
     252              : #define CTLL_EXPORT export
     253              : #else
     254              : #define CTLL_EXPORT 
     255              : #endif
     256              : 
     257              : #if defined __cpp_nontype_template_parameter_class
     258              :     #define CTLL_CNTTP_COMPILER_CHECK 1
     259              : #elif defined __cpp_nontype_template_args
     260              : // compiler which defines correctly feature test macro (not you clang)
     261              :     #if __cpp_nontype_template_args >= 201911L
     262              :         #define CTLL_CNTTP_COMPILER_CHECK 1
     263              :     #elif __cpp_nontype_template_args >= 201411L
     264              : // appleclang 13+
     265              :       #if defined __apple_build_version__
     266              :         #if defined __clang_major__ && __clang_major__ >= 13
     267              : // but only in c++20 and more
     268              :           #if __cplusplus > 201703L
     269              :               #define CTLL_CNTTP_COMPILER_CHECK 1
     270              :           #endif
     271              :         #endif
     272              :       #else 
     273              : // clang 12+
     274              :         #if defined __clang_major__ && __clang_major__ >= 12
     275              : // but only in c++20 and more
     276              :           #if __cplusplus > 201703L
     277              :               #define CTLL_CNTTP_COMPILER_CHECK 1
     278              :           #endif
     279              :         #endif
     280              :       #endif
     281              :     #endif
     282              : #endif
     283              : 
     284              : #ifndef CTLL_CNTTP_COMPILER_CHECK
     285              :     #define CTLL_CNTTP_COMPILER_CHECK 0
     286              : #endif
     287              : 
     288              : #ifdef _MSC_VER
     289              : #define CTLL_FORCE_INLINE __forceinline
     290              : #else
     291              : #define CTLL_FORCE_INLINE __attribute__((always_inline))
     292              : #endif
     293              : 
     294              : namespace ctll {
     295              :         
     296              : template <bool> struct conditional_helper;
     297              :         
     298              : template <> struct conditional_helper<true> {
     299              :         template <typename A, typename> using type = A;
     300              : };
     301              : 
     302              : template <> struct conditional_helper<false> {
     303              :         template <typename, typename B> using type = B;
     304              : };
     305              : 
     306              : template <bool V, typename A, typename B> using conditional = typename conditional_helper<V>::template type<A,B>;
     307              :         
     308              : }
     309              : 
     310              : #endif
     311              : 
     312              : namespace ctll {
     313              : 
     314              : struct length_value_t {
     315              :         uint32_t value;
     316              :         uint8_t length;
     317              : };
     318              : 
     319              : constexpr length_value_t length_and_value_of_utf8_code_point(uint8_t first_unit) noexcept {
     320              :         if ((first_unit & 0b1000'0000) == 0b0000'0000) return {static_cast<uint32_t>(first_unit), 1};
     321              :         else if ((first_unit & 0b1110'0000) == 0b1100'0000) return {static_cast<uint32_t>(first_unit & 0b0001'1111), 2};
     322              :         else if ((first_unit & 0b1111'0000) == 0b1110'0000) return {static_cast<uint32_t>(first_unit & 0b0000'1111), 3};
     323              :         else if ((first_unit & 0b1111'1000) == 0b1111'0000) return {static_cast<uint32_t>(first_unit & 0b0000'0111), 4};
     324              :         else if ((first_unit & 0b1111'1100) == 0b1111'1000) return {static_cast<uint32_t>(first_unit & 0b0000'0011), 5};
     325              :         else if ((first_unit & 0b1111'1100) == 0b1111'1100) return {static_cast<uint32_t>(first_unit & 0b0000'0001), 6};
     326              :         else return {0, 0};
     327              : }
     328              : 
     329              : constexpr char32_t value_of_trailing_utf8_code_point(uint8_t unit, bool & correct) noexcept {
     330              :         if ((unit & 0b1100'0000) == 0b1000'0000) return unit & 0b0011'1111;
     331              :         else {
     332              :                 correct = false;
     333              :                 return 0;
     334              :         }
     335              : }
     336              : 
     337              : constexpr length_value_t length_and_value_of_utf16_code_point(uint16_t first_unit) noexcept {
     338              :         if ((first_unit & 0b1111110000000000) == 0b1101'1000'0000'0000) return {static_cast<uint32_t>(first_unit & 0b0000001111111111), 2};
     339              :         else return {first_unit, 1};
     340              : }
     341              : 
     342              : struct construct_from_pointer_t { };
     343              : 
     344              : constexpr auto construct_from_pointer = construct_from_pointer_t{};
     345              : 
     346              : CTLL_EXPORT template <size_t N> struct fixed_string {
     347              :         char32_t content[N] = {};
     348              :         size_t real_size{0};
     349              :         bool correct_flag{true};
     350              :         
     351              :         template <typename T> constexpr fixed_string(construct_from_pointer_t, const T * input) noexcept {
     352              :                 if constexpr (std::is_same_v<T, char>) {
     353              :                         #ifdef CTRE_STRING_IS_UTF8
     354              :                                 size_t out{0};
     355              :                                 for (size_t i{0}; i < N; ++i) {
     356              :                                         length_value_t info = length_and_value_of_utf8_code_point(input[i]);
     357              :                                         switch (info.length) {
     358              :                                                 case 6:
     359              :                                                         if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     360              :                                                         [[fallthrough]];
     361              :                                                 case 5:
     362              :                                                         if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     363              :                                                         [[fallthrough]];
     364              :                                                 case 4:
     365              :                                                         if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     366              :                                                         [[fallthrough]];
     367              :                                                 case 3:
     368              :                                                         if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     369              :                                                         [[fallthrough]];
     370              :                                                 case 2:
     371              :                                                         if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     372              :                                                         [[fallthrough]];
     373              :                                                 case 1:
     374              :                                                         content[out++] = static_cast<char32_t>(info.value);
     375              :                                                         real_size++;
     376              :                                                         break;
     377              :                                                 default:
     378              :                                                         correct_flag = false;
     379              :                                                         return;
     380              :                                         }
     381              :                                 }
     382              :                         #else
     383              :                                 for (size_t i{0}; i < N; ++i) {
     384              :                                         content[i] = static_cast<uint8_t>(input[i]);
     385              :                                         real_size++;
     386              :                                 }
     387              :                         #endif
     388              : #if defined(__cpp_char8_t)
     389              :                 } else if constexpr (std::is_same_v<T, char8_t>) {
     390              :                         size_t out{0};
     391              :                         for (size_t i{0}; i < N; ++i) {
     392              :                                 length_value_t info = length_and_value_of_utf8_code_point(input[i]);
     393              :                                 switch (info.length) {
     394              :                                         case 6:
     395              :                                                 if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     396              :                                                 [[fallthrough]];
     397              :                                         case 5:
     398              :                                                 if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     399              :                                                 [[fallthrough]];
     400              :                                         case 4:
     401              :                                                 if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     402              :                                                 [[fallthrough]];
     403              :                                         case 3:
     404              :                                                 if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     405              :                                                 [[fallthrough]];
     406              :                                         case 2:
     407              :                                                 if (++i < N) info.value = (info.value << 6) | value_of_trailing_utf8_code_point(input[i], correct_flag);
     408              :                                                 [[fallthrough]];
     409              :                                         case 1:
     410              :                                                 content[out++] = static_cast<char32_t>(info.value);
     411              :                                                 real_size++;
     412              :                                                 break;
     413              :                                         default:
     414              :                                                 correct_flag = false;
     415              :                                                 return;
     416              :                                 }
     417              :                         }
     418              : #endif
     419              :                 } else if constexpr (std::is_same_v<T, char16_t>) {
     420              :                         size_t out{0};
     421              :                         for (size_t i{0}; i < N; ++i) {
     422              :                                 length_value_t info = length_and_value_of_utf16_code_point(input[i]);
     423              :                                 if (info.length == 2) {
     424              :                                         if (++i < N) {
     425              :                                                 if ((input[i] & 0b1111'1100'0000'0000) == 0b1101'1100'0000'0000) {
     426              :                                                         content[out++] = ((info.value << 10) | (input[i] & 0b0000'0011'1111'1111)) + 0x10000;
     427              :                                                 } else {
     428              :                                                         correct_flag = false;
     429              :                                                         break;
     430              :                                                 }
     431              :                                         }
     432              :                                 } else {
     433              :                                         content[out++] = info.value;
     434              :                                 }
     435              :                         }
     436              :                         real_size = out;
     437              :                 } else if constexpr (std::is_same_v<T, wchar_t> || std::is_same_v<T, char32_t>) {
     438              :                         for (size_t i{0}; i < N; ++i) {
     439              :                                 content[i] = static_cast<char32_t>(input[i]);
     440              :                                 real_size++;
     441              :                         }
     442              :                 }
     443              :         }
     444              :         
     445              :         template <typename T> constexpr fixed_string(const std::array<T, N> & in) noexcept: fixed_string{construct_from_pointer, in.data()} { }
     446              :         template <typename T> constexpr fixed_string(const T (&input)[N+1]) noexcept: fixed_string{construct_from_pointer, input} { }
     447              :         
     448              :         constexpr fixed_string(const fixed_string & other) noexcept {
     449              :                 for (size_t i{0}; i < N; ++i) {
     450              :                         content[i] = other.content[i];
     451              :                 }
     452              :                 real_size = other.real_size;
     453              :                 correct_flag = other.correct_flag;
     454              :         }
     455              :         constexpr bool correct() const noexcept {
     456              :                 return correct_flag;
     457              :         }
     458              :         constexpr size_t size() const noexcept {
     459              :                 return real_size;
     460              :         }
     461              :         constexpr const char32_t * begin() const noexcept {
     462              :                 return content;
     463              :         }
     464              :         constexpr const char32_t * end() const noexcept {
     465              :                 return content + size();
     466              :         }
     467              :         constexpr char32_t operator[](size_t i) const noexcept {
     468              :                 return content[i];
     469              :         }
     470              :         template <size_t M> constexpr bool is_same_as(const fixed_string<M> & rhs) const noexcept {
     471              :                 if (real_size != rhs.size()) return false;
     472              :                 for (size_t i{0}; i != real_size; ++i) {
     473              :                         if (content[i] != rhs[i]) return false;
     474              :                 }
     475              :                 return true;
     476              :         }
     477              :         constexpr operator std::basic_string_view<char32_t>() const noexcept {
     478              :                 return std::basic_string_view<char32_t>{content, size()};
     479              :         }
     480              : };
     481              : 
     482              : template <> class fixed_string<0> {
     483              :         static constexpr char32_t empty[1] = {0};
     484              : public:
     485              :         template <typename T> constexpr fixed_string(const T *) noexcept {
     486              :                 
     487              :         }
     488              :         constexpr fixed_string(std::initializer_list<char32_t>) noexcept {
     489              :                 
     490              :         }
     491              :         constexpr fixed_string(const fixed_string &) noexcept {
     492              :                         
     493              :         }
     494              :         constexpr bool correct() const noexcept {
     495              :                 return true;
     496              :         }
     497              :         constexpr size_t size() const noexcept {
     498              :                 return 0;
     499              :         }
     500              :         constexpr const char32_t * begin() const noexcept {
     501              :                 return empty;
     502              :         }
     503              :         constexpr const char32_t * end() const noexcept {
     504              :                 return empty + size();
     505              :         }
     506              :         constexpr char32_t operator[](size_t) const noexcept {
     507              :                 return 0;
     508              :         }
     509              :         constexpr operator std::basic_string_view<char32_t>() const noexcept {
     510              :                 return std::basic_string_view<char32_t>{empty, 0};
     511              :         }
     512              : };
     513              : 
     514              : template <typename CharT, size_t N> fixed_string(const CharT (&)[N]) -> fixed_string<N-1>;
     515              : template <typename CharT, size_t N> fixed_string(const std::array<CharT,N> &) -> fixed_string<N>;
     516              : 
     517              : template <size_t N> fixed_string(fixed_string<N>) -> fixed_string<N>;
     518              : 
     519              : }
     520              : 
     521              : #endif
     522              : 
     523              : #ifndef CTLL__TYPE_STACK__HPP
     524              : #define CTLL__TYPE_STACK__HPP
     525              : 
     526              : namespace ctll {
     527              : 
     528              : template <typename... Ts> struct list { };
     529              :         
     530              : struct _nothing { };
     531              : 
     532              : using empty_list = list<>;
     533              : 
     534              : // calculate size of list content
     535              : template <typename... Ts> constexpr auto size(list<Ts...>) noexcept { return sizeof...(Ts); }
     536              : 
     537              :         
     538              : // check if the list is empty
     539              : template <typename... Ts> constexpr bool empty(list<Ts...>) noexcept { return false; }
     540              : constexpr bool empty(empty_list) { return true; }
     541              : 
     542              : // concat two lists together left to right
     543              : template <typename... As, typename... Bs> constexpr auto concat(list<As...>, list<Bs...>) noexcept -> list<As..., Bs...> { return {}; }
     544              : 
     545              : // push something to the front of a list
     546              : template <typename T, typename... As> constexpr auto push_front(T, list<As...>) noexcept -> list<T, As...> { return {}; }
     547              : 
     548              : // pop element from the front of a list
     549              : template <typename T, typename... As> constexpr auto pop_front(list<T, As...>) noexcept -> list<As...> { return {}; }
     550              : constexpr auto pop_front(empty_list) -> empty_list;
     551              : 
     552              : // pop element from the front of a list and return new typelist too
     553              : template <typename Front, typename List> struct list_pop_pair {
     554              :         Front front{};
     555              :         List list{};
     556              :         constexpr list_pop_pair() = default;
     557              : };
     558              : 
     559              : 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 {}; }
     560              : template <typename T = _nothing> constexpr auto pop_and_get_front(empty_list, T = T()) noexcept -> list_pop_pair<T, empty_list> { return {}; }
     561              : 
     562              : // return front of the list
     563              : template <typename Head, typename... As, typename T = _nothing> constexpr auto front(list<Head, As...>, T = T()) noexcept -> Head { return {}; }
     564              : template <typename T = _nothing> constexpr auto front(empty_list, T = T()) noexcept -> T { return {}; }
     565              : 
     566              : // rotate list
     567              : template <typename T> struct rotate_item {
     568              :         template <typename... Ts> friend constexpr auto operator+(list<Ts...>, rotate_item<T>) noexcept -> list<T, Ts...> { return {}; }
     569              : };
     570              : 
     571              : template <typename... Ts> constexpr auto rotate(list<Ts...>) -> decltype((list<>{} + ... + rotate_item<Ts>{})) {
     572              :         return {};
     573              : }
     574              : 
     575              : // set operations
     576              : template <typename T> struct item_matcher {
     577              :         struct not_selected {
     578              :                 template <typename... Ts> friend constexpr auto operator+(list<Ts...>, not_selected) -> list<Ts...>;
     579              :         };
     580              :         template <typename Y> struct wrapper {
     581              :                 template <typename... Ts> friend constexpr auto operator+(list<Ts...>, wrapper<Y>) -> list<Ts...,Y>;
     582              :         };
     583              : 
     584              :         static constexpr auto check(T) { return std::true_type{}; }
     585              :         static constexpr auto check(...) { return std::false_type{}; }
     586              :         static constexpr auto select(T) { return not_selected{}; }
     587              :         template <typename Y> static constexpr auto select(Y) { return wrapper<Y>{}; }
     588              : };
     589              : 
     590              : template <typename T, typename... Ts> constexpr bool exists_in(T, list<Ts...>) noexcept {
     591              :         return (item_matcher<T>::check(Ts{}) || ... || false);
     592              : }
     593              : 
     594              : template <typename T, typename... Ts> constexpr auto add_item(T item, list<Ts...> l) noexcept {
     595              :         if constexpr (exists_in(item, l)) {
     596              :                 return l;
     597              :         } else {
     598              :                 return list<Ts..., T>{};
     599              :         }
     600              : }
     601              : 
     602              : template <typename T, typename... Ts> constexpr auto remove_item(T, list<Ts...>) noexcept {
     603              :         item_matcher<T> matcher;
     604              :         return decltype((list<>{} + ... + matcher.select(Ts{}))){};
     605              : }
     606              : 
     607              : }
     608              : 
     609              : #endif
     610              : 
     611              : #ifndef CTLL__GRAMMARS__HPP
     612              : #define CTLL__GRAMMARS__HPP
     613              : 
     614              : namespace ctll {
     615              : 
     616              : // terminal type representing symbol / character of any type
     617              : template <auto v> struct term {
     618              :         static constexpr auto value = v;
     619              : };
     620              : 
     621              : // epsilon = nothing on input tape
     622              : // also used as an command for parsing means "do nothing"
     623              : struct epsilon {
     624              :         static constexpr auto value = '-';
     625              : };
     626              : 
     627              : // empty_stack_symbol = nothing on stack
     628              : struct empty_stack_symbol {};
     629              : 
     630              : // push<T...> is alias to list<T...>
     631              : template <typename... Ts> using push = list<Ts...>;
     632              : 
     633              : // accept/reject type for controlling output of LL1 machine
     634              : struct accept { constexpr explicit operator bool() noexcept { return true; } };
     635              : struct reject { constexpr explicit operator bool() noexcept { return false; } };
     636              : 
     637              : // action type, every action item in grammar must inherit from
     638              : struct action { 
     639              :         struct action_tag { };
     640              : };
     641              : 
     642              : // move one character forward and pop it from stack command
     643              : struct pop_input {
     644              :         struct pop_input_tag { };
     645              : };
     646              : 
     647              : // additional overloads for type list
     648              : template <typename... Ts> constexpr auto push_front(pop_input, list<Ts...>) -> list<Ts...> { return {}; }
     649              : 
     650              : template <typename... Ts> constexpr auto push_front(epsilon, list<Ts...>) -> list<Ts...> { return {}; }
     651              : 
     652              : template <typename... As, typename... Bs> constexpr auto push_front(list<As...>, list<Bs...>) -> list<As..., Bs...> { return {}; }
     653              : 
     654              : template <typename T, typename... As> constexpr auto pop_front_and_push_front(T item, list<As...> l) {
     655              :         return push_front(item, pop_front(l));
     656              : }
     657              : 
     658              : // SPECIAL matching types for nicer grammars
     659              : 
     660              : // match any term
     661              : struct anything {
     662              :         constexpr inline anything() noexcept { }
     663              :         template <auto V> constexpr anything(term<V>) noexcept;
     664              : };
     665              : 
     666              : // match range of term A-B
     667              : template <auto A, decltype(A) B> struct range {
     668              :         constexpr inline range() noexcept { }
     669              :         //template <auto V> constexpr range(term<V>) noexcept requires (A <= V) && (V <= B);
     670              :         template <auto V, typename = std::enable_if_t<(A <= V) && (V <= B)>> constexpr range(term<V>) noexcept;
     671              : };
     672              : 
     673              : #ifdef __EDG__
     674              : template <auto V, auto... Set> struct contains {
     675              :         static constexpr bool value = ((Set == V) || ... || false);
     676              : };
     677              : #endif
     678              : 
     679              : // match terms defined in set
     680              : template <auto... Def> struct set {
     681              :         constexpr inline set() noexcept { }
     682              :         #ifdef __EDG__
     683              :         template <auto V, typename = std::enable_if_t<contains<V, Def...>::value>> constexpr set(term<V>) noexcept;
     684              :         #else
     685              :         template <auto V, typename = std::enable_if_t<((Def == V) || ... || false)>> constexpr set(term<V>) noexcept;
     686              :         #endif
     687              : };
     688              : 
     689              : // match terms not defined in set
     690              : template <auto... Def> struct neg_set {
     691              :         constexpr inline neg_set() noexcept { }
     692              :         
     693              :         #ifdef __EDG__
     694              :         template <auto V, typename = std::enable_if_t<!contains<V, Def...>::value>> constexpr neg_set(term<V>) noexcept;
     695              :         #else
     696              :         template <auto V, typename = std::enable_if_t<!((Def == V) || ... || false)>> constexpr neg_set(term<V>) noexcept;
     697              :         #endif
     698              : };
     699              : 
     700              : // AUGMENTED grammar which completes user-defined grammar for all other cases
     701              : template <typename Grammar> struct augment_grammar: public Grammar {
     702              :         // start nonterminal is defined in parent type
     703              :         using typename Grammar::_start; 
     704              :         
     705              :         // grammar rules are inherited from Grammar parent type
     706              :         using Grammar::rule; 
     707              :         
     708              :         // term on stack and on input means pop_input;
     709              :         template <auto A> static constexpr auto rule(term<A>, term<A>) -> ctll::pop_input;
     710              :         
     711              :         // if the type on stack (range, set, neg_set, anything) is constructible from the terminal => pop_input
     712              :         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>;
     713              :         
     714              :         // empty stack and empty input means we are accepting 
     715              :         static constexpr auto rule(empty_stack_symbol, epsilon) -> ctll::accept;
     716              :         
     717              :         // not matching anything else => reject
     718              :         static constexpr auto rule(...) -> ctll::reject;
     719              :         
     720              :         // start stack is just a list<Grammar::_start>;
     721              :         using start_stack = list<typename Grammar::_start>;
     722              : };
     723              : 
     724              : }
     725              : 
     726              : #endif
     727              : 
     728              : #ifndef CTLL__ACTIONS__HPP
     729              : #define CTLL__ACTIONS__HPP
     730              : 
     731              : namespace ctll {
     732              :         struct empty_subject { };
     733              :         
     734              :         struct empty_actions {
     735              :                 // dummy operator so using Actions::operator() later will not give error
     736              :                 template <typename Action, typename InputSymbol, typename Subject> static constexpr auto apply(Action, InputSymbol, Subject subject) {
     737              :                         return subject;
     738              :                 }
     739              :         };
     740              :         
     741              :         template <typename Actions> struct identity: public Actions {
     742              :                 using Actions::apply;
     743              :                 // allow empty_subject to exists
     744              :                 template <typename Action, auto V> constexpr static auto apply(Action, term<V>, empty_subject) -> empty_subject { return {}; }
     745              :                 template <typename Action> constexpr static auto apply(Action, epsilon, empty_subject) -> empty_subject { return {}; } 
     746              :         };
     747              :         
     748              :         template <typename Actions> struct ignore_unknown: public Actions {
     749              :                 using Actions::apply;
     750              :                 // allow flow thru unknown actions
     751              :                 template <typename Action, auto V, typename Subject> constexpr static auto apply(Action, term<V>, Subject) -> Subject { return {}; }
     752              :                 template <typename Action, typename Subject> constexpr static auto apply(Action, epsilon, Subject) -> Subject { return {}; }   
     753              :         };
     754              : }
     755              : 
     756              : #endif
     757              : 
     758              : #ifndef CTLL_IN_A_MODULE
     759              : #include <limits>
     760              : #endif
     761              : 
     762              : namespace ctll {
     763              : 
     764              : enum class decision {
     765              :         reject,
     766              :         accept,
     767              :         undecided
     768              : };
     769              : 
     770              : struct placeholder { };
     771              : 
     772              : template <size_t> using index_placeholder = placeholder;
     773              : 
     774              : #if CTLL_CNTTP_COMPILER_CHECK
     775              : template <typename Grammar, ctll::fixed_string input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser { // in c++20
     776              : #else
     777              : template <typename Grammar, const auto & input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser {
     778              : #endif
     779              :         
     780              :         #ifdef __GNUC__ // workaround to GCC bug
     781              :                 #if CTLL_CNTTP_COMPILER_CHECK
     782              :                 static constexpr auto _input = input;  // c++20 mode
     783              :                 #else
     784              :                 static constexpr auto & _input = input; // c++17 mode
     785              :                 #endif
     786              :         #else
     787              :                 static constexpr auto _input = input; // everyone else
     788              :         #endif
     789              : 
     790              :         using Actions = ctll::conditional<IgnoreUnknownActions, ignore_unknown<ActionSelector>, identity<ActionSelector>>;
     791              :         using grammar = augment_grammar<Grammar>;
     792              :         
     793              :         template <size_t Pos, typename Stack, typename Subject, decision Decision> struct results {
     794              :         
     795              :                 static constexpr bool is_correct = Decision == decision::accept;
     796              :         
     797              :                 constexpr inline CTLL_FORCE_INLINE operator bool() const noexcept {
     798              :                         return is_correct;
     799              :                 }
     800              :                 
     801              :                 #ifdef __GNUC__ // workaround to GCC bug
     802              :                         #if CTLL_CNTTP_COMPILER_CHECK
     803              :                         static constexpr auto _input = input;  // c++20 mode
     804              :                         #else
     805              :                         static constexpr auto & _input = input; // c++17 mode
     806              :                         #endif
     807              :                 #else
     808              :                         static constexpr auto _input = input; // everyone else
     809              :                 #endif
     810              :         
     811              :                 using output_type = Subject;
     812              :                 static constexpr size_t position = Pos;
     813              :     
     814              :                 constexpr auto operator+(placeholder) const noexcept {
     815              :                         if constexpr (Decision == decision::undecided) {
     816              :                                 // parse for current char (RPos) with previous stack and subject :)
     817              :                                 return parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template decide<Pos, Stack, Subject>({}, {});
     818              :                         } else {
     819              :                                 // if there is decision already => just push it to the end of fold expression
     820              :                                 return *this;
     821              :                         }
     822              :                 }
     823              :         };
     824              :         
     825              :         template <size_t Pos> static constexpr auto get_current_term() noexcept {
     826              :                 if constexpr (Pos < input.size()) {
     827              :                         constexpr auto value = input[Pos];
     828              :                         if constexpr (value <= static_cast<decltype(value)>((std::numeric_limits<char>::max)())) {
     829              :                                 return term<static_cast<char>(value)>{};
     830              :                         } else {
     831              :                                 return term<value>{};
     832              :                         }
     833              :                         
     834              :                 } else {
     835              :                         // return epsilon if we are past the input
     836              :                         return epsilon{};
     837              :                 }
     838              :         }
     839              :         template <size_t Pos> static constexpr auto get_previous_term() noexcept {
     840              :                 if constexpr (Pos == 0) {
     841              :                         // there is no previous character on input if we are on start
     842              :                         return epsilon{};
     843              :                 } else if constexpr ((Pos-1) < input.size()) {
     844              :                         constexpr auto value = input[Pos-1];
     845              :                         if constexpr (value <= static_cast<decltype(value)>((std::numeric_limits<char>::max)())) {
     846              :                                 return term<static_cast<char>(value)>{};
     847              :                         } else {
     848              :                                 return term<value>{};
     849              :                         }
     850              :                 } else {
     851              :                         return epsilon{};
     852              :                 }
     853              :         }
     854              :         // if rule is accept => return true and subject
     855              :         template <size_t Pos, typename Terminal, typename Stack, typename Subject> 
     856              :         static constexpr auto move(ctll::accept, Terminal, Stack, Subject) noexcept {
     857              :                 return typename parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template results<Pos, Stack, Subject, decision::accept>();
     858              :         }
     859              :         // if rule is reject => return false and subject
     860              :         template <size_t Pos, typename Terminal, typename Stack, typename Subject>
     861              :         static constexpr auto move(ctll::reject, Terminal, Stack, Subject) noexcept {
     862              :                 return typename parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template results<Pos, Stack, Subject, decision::reject>();
     863              :         }
     864              :         // if rule is pop_input => move to next character
     865              :         template <size_t Pos, typename Terminal, typename Stack, typename Subject>
     866              :         static constexpr auto move(ctll::pop_input, Terminal, Stack, Subject) noexcept {
     867              :                 return typename parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template results<Pos+1, Stack, Subject, decision::undecided>();
     868              :         }
     869              :         // if rule is string => push it to the front of stack
     870              :         template <size_t Pos, typename... Content, typename Terminal, typename Stack, typename Subject>
     871              :         static constexpr auto move(push<Content...> string, Terminal, Stack stack, Subject subject) noexcept {
     872              :                 return decide<Pos>(push_front(string, stack), subject);
     873              :         }
     874              :         // if rule is epsilon (empty string) => continue
     875              :         template <size_t Pos, typename Terminal, typename Stack, typename Subject>
     876              :         static constexpr auto move(epsilon, Terminal, Stack stack, Subject subject) noexcept {
     877              :                 return decide<Pos>(stack, subject);
     878              :         }
     879              :         // if rule is string with current character at the beginning (term<V>) => move to next character 
     880              :         // and push string without the character (quick LL(1))
     881              :         template <size_t Pos, auto V, typename... Content, typename Stack, typename Subject>
     882              :         static constexpr auto move(push<term<V>, Content...>, term<V>, Stack stack, Subject) noexcept {
     883              :                 constexpr auto local_input = input;
     884              :                 return typename parser<Grammar, local_input, ActionSelector, IgnoreUnknownActions>::template results<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
     885              :         }
     886              :         // if rule is string with any character at the beginning (compatible with current term<T>) => move to next character 
     887              :         // and push string without the character (quick LL(1))
     888              :         template <size_t Pos, auto V, typename... Content, auto T, typename Stack, typename Subject>
     889              :         static constexpr auto move(push<anything, Content...>, term<T>, Stack stack, Subject) noexcept {
     890              :                 constexpr auto local_input = input;
     891              :                 return typename parser<Grammar, local_input, ActionSelector, IgnoreUnknownActions>::template results<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
     892              :         }
     893              :         // decide if we need to take action or move
     894              :         template <size_t Pos, typename Stack, typename Subject> static constexpr auto decide(Stack previous_stack, Subject previous_subject) noexcept {
     895              :                 // each call means we pop something from stack
     896              :                 auto top_symbol = decltype(ctll::front(previous_stack, empty_stack_symbol()))();
     897              :                 // gcc pedantic warning
     898              :                 [[maybe_unused]] auto stack = decltype(ctll::pop_front(previous_stack))();
     899              :                 
     900              :                 // in case top_symbol is action type (apply it on previous subject and get new one)
     901              :                 if constexpr (std::is_base_of_v<ctll::action, decltype(top_symbol)>) {
     902              :                         auto subject = Actions::apply(top_symbol, get_previous_term<Pos>(), previous_subject);
     903              :                         
     904              :                         // in case that semantic action is error => reject input
     905              :                         if constexpr (std::is_same_v<ctll::reject, decltype(subject)>) {
     906              :                                 return typename parser<Grammar, _input, ActionSelector, IgnoreUnknownActions>::template results<Pos, Stack, Subject, decision::reject>();
     907              :                         } else {
     908              :                                 return decide<Pos>(stack, subject);
     909              :                         }
     910              :                 } else {
     911              :                         // all other cases are ordinary for LL(1) parser
     912              :                         auto current_term = get_current_term<Pos>();
     913              :                         auto rule = decltype(grammar::rule(top_symbol,current_term))();
     914              :                         return move<Pos>(rule, current_term, stack, previous_subject);
     915              :                 }
     916              :         }
     917              :         
     918              :         // trampolines with folded expression
     919              :         template <typename Subject, size_t... Pos> static constexpr auto trampoline_decide(Subject, std::index_sequence<Pos...>) noexcept {
     920              :                 // parse everything for first char and than for next and next ...
     921              :                 // Pos+1 is needed as we want to finish calculation with epsilons on stack
     922              :                 auto v = (decide<0, typename grammar::start_stack, Subject>({}, {}) + ... + index_placeholder<Pos+1>());
     923              :                 return v;
     924              :         }
     925              :         
     926              :         template <typename Subject = empty_subject> static constexpr auto trampoline_decide(Subject subject = {}) noexcept {
     927              :                 // there will be no recursion, just sequence long as the input
     928              :                 return trampoline_decide(subject, std::make_index_sequence<input.size()>());
     929              :         }
     930              :         
     931              :         template <typename Subject = empty_subject> using output = decltype(trampoline_decide<Subject>());
     932              :         template <typename Subject = empty_subject> static inline constexpr bool correct_with = trampoline_decide<Subject>();
     933              : 
     934              : };
     935              : 
     936              : } // end of ctll namespace
     937              : 
     938              : #endif
     939              : 
     940              : #endif
     941              : 
     942              : #ifndef CTRE__PCRE_ACTIONS__HPP
     943              : #define CTRE__PCRE_ACTIONS__HPP
     944              : 
     945              : #ifndef CTRE__PCRE__HPP
     946              : #define CTRE__PCRE__HPP
     947              : 
     948              : // THIS FILE WAS GENERATED BY DESATOMAT TOOL, DO NOT MODIFY THIS FILE
     949              : 
     950              : namespace ctre {
     951              : 
     952              : struct pcre {
     953              : 
     954              : // NONTERMINALS:
     955              :         struct a {};
     956              :         struct b {};
     957              :         struct backslash {};
     958              :         struct backslash_range {};
     959              :         struct block {};
     960              :         struct block_name2 {};
     961              :         struct block_name {};
     962              :         struct c {};
     963              :         struct class_named_name {};
     964              :         struct content2 {};
     965              :         struct content_in_capture {};
     966              :         struct content_or_empty {};
     967              :         struct d {};
     968              :         struct e {};
     969              :         struct f {};
     970              :         struct g {};
     971              :         struct h {};
     972              :         struct hexdec_repeat {};
     973              :         struct i {};
     974              :         struct j {};
     975              :         struct k {};
     976              :         struct l {};
     977              :         struct m {};
     978              :         struct mod {};
     979              :         struct mode_switch2 {};
     980              :         struct n {};
     981              :         struct number2 {};
     982              :         struct number {};
     983              :         struct o {};
     984              :         struct opt_content {};
     985              :         struct p {};
     986              :         struct property_name2 {};
     987              :         struct property_name {};
     988              :         struct property_value2 {};
     989              :         struct property_value {};
     990              :         struct range {};
     991              :         struct repeat {};
     992              :         struct s {}; using _start = s;
     993              :         struct set2a {};
     994              :         struct set2b {};
     995              :         struct string2 {};
     996              : 
     997              : // 'action' types:
     998              :         struct class_digit: ctll::action {};
     999              :         struct class_horizontal_space: ctll::action {};
    1000              :         struct class_named_alnum: ctll::action {};
    1001              :         struct class_named_alpha: ctll::action {};
    1002              :         struct class_named_ascii: ctll::action {};
    1003              :         struct class_named_blank: ctll::action {};
    1004              :         struct class_named_cntrl: ctll::action {};
    1005              :         struct class_named_digit: ctll::action {};
    1006              :         struct class_named_graph: ctll::action {};
    1007              :         struct class_named_lower: ctll::action {};
    1008              :         struct class_named_print: ctll::action {};
    1009              :         struct class_named_punct: ctll::action {};
    1010              :         struct class_named_space: ctll::action {};
    1011              :         struct class_named_upper: ctll::action {};
    1012              :         struct class_named_word: ctll::action {};
    1013              :         struct class_named_xdigit: ctll::action {};
    1014              :         struct class_non_horizontal_space: ctll::action {};
    1015              :         struct class_non_vertical_space: ctll::action {};
    1016              :         struct class_nondigit: ctll::action {};
    1017              :         struct class_nonnewline: ctll::action {};
    1018              :         struct class_nonspace: ctll::action {};
    1019              :         struct class_nonword: ctll::action {};
    1020              :         struct class_space: ctll::action {};
    1021              :         struct class_vertical_space: ctll::action {};
    1022              :         struct class_word: ctll::action {};
    1023              :         struct create_hexdec: ctll::action {};
    1024              :         struct create_number: ctll::action {};
    1025              :         struct finish_hexdec: ctll::action {};
    1026              :         struct look_finish: ctll::action {};
    1027              :         struct make_alternate: ctll::action {};
    1028              :         struct make_atomic: ctll::action {};
    1029              :         struct make_back_reference: ctll::action {};
    1030              :         struct make_capture: ctll::action {};
    1031              :         struct make_capture_with_name: ctll::action {};
    1032              :         struct make_lazy: ctll::action {};
    1033              :         struct make_optional: ctll::action {};
    1034              :         struct make_possessive: ctll::action {};
    1035              :         struct make_property: ctll::action {};
    1036              :         struct make_property_negative: ctll::action {};
    1037              :         struct make_range: ctll::action {};
    1038              :         struct make_relative_back_reference: ctll::action {};
    1039              :         struct make_sequence: ctll::action {};
    1040              :         struct mode_case_insensitive: ctll::action {};
    1041              :         struct mode_case_sensitive: ctll::action {};
    1042              :         struct mode_multiline: ctll::action {};
    1043              :         struct mode_singleline: ctll::action {};
    1044              :         struct negate_class_named: ctll::action {};
    1045              :         struct prepare_capture: ctll::action {};
    1046              :         struct push_assert_begin: ctll::action {};
    1047              :         struct push_assert_end: ctll::action {};
    1048              :         struct push_assert_subject_begin: ctll::action {};
    1049              :         struct push_assert_subject_end: ctll::action {};
    1050              :         struct push_assert_subject_end_with_lineend: ctll::action {};
    1051              :         struct push_character: ctll::action {};
    1052              :         struct push_character_alarm: ctll::action {};
    1053              :         struct push_character_anything: ctll::action {};
    1054              :         struct push_character_escape: ctll::action {};
    1055              :         struct push_character_formfeed: ctll::action {};
    1056              :         struct push_character_newline: ctll::action {};
    1057              :         struct push_character_null: ctll::action {};
    1058              :         struct push_character_return_carriage: ctll::action {};
    1059              :         struct push_character_tab: ctll::action {};
    1060              :         struct push_empty: ctll::action {};
    1061              :         struct push_hexdec: ctll::action {};
    1062              :         struct push_name: ctll::action {};
    1063              :         struct push_not_word_boundary: ctll::action {};
    1064              :         struct push_number: ctll::action {};
    1065              :         struct push_property_name: ctll::action {};
    1066              :         struct push_property_value: ctll::action {};
    1067              :         struct push_word_boundary: ctll::action {};
    1068              :         struct repeat_ab: ctll::action {};
    1069              :         struct repeat_at_least: ctll::action {};
    1070              :         struct repeat_exactly: ctll::action {};
    1071              :         struct repeat_plus: ctll::action {};
    1072              :         struct repeat_star: ctll::action {};
    1073              :         struct reset_capture: ctll::action {};
    1074              :         struct set_combine: ctll::action {};
    1075              :         struct set_empty: ctll::action {};
    1076              :         struct set_make: ctll::action {};
    1077              :         struct set_make_negative: ctll::action {};
    1078              :         struct set_start: ctll::action {};
    1079              :         struct start_atomic: ctll::action {};
    1080              :         struct start_lookahead_negative: ctll::action {};
    1081              :         struct start_lookahead_positive: ctll::action {};
    1082              :         struct start_lookbehind_negative: ctll::action {};
    1083              :         struct start_lookbehind_positive: ctll::action {};
    1084              : 
    1085              : // (q)LL1 function:
    1086              :         using _others = ctll::neg_set<'!','$','\x28','\x29','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>;
    1087              :         static constexpr auto rule(s, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2>;
    1088              :         static constexpr auto rule(s, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
    1089              :         static constexpr auto rule(s, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2>;
    1090              :         static constexpr auto rule(s, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2>;
    1091              :         static constexpr auto rule(s, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2>;
    1092              :         static constexpr auto rule(s, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2>;
    1093              :         static constexpr auto rule(s, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
    1094              :         static constexpr auto rule(s, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2>;
    1095              :         static constexpr auto rule(s, ctll::term<'|'>) -> ctll::push<ctll::anything, push_empty, opt_content, make_alternate>;
    1096              :         static constexpr auto rule(s, ctll::epsilon) -> ctll::push<push_empty>;
    1097              :         static constexpr auto rule(s, ctll::set<'\x29','*','+','?','\x7B','\x7D'>) -> ctll::reject;
    1098              : 
    1099              :         static constexpr auto rule(a, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2, make_alternate>;
    1100              :         static constexpr auto rule(a, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2, make_alternate>;
    1101              :         static constexpr auto rule(a, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2, make_alternate>;
    1102              :         static constexpr auto rule(a, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2, make_alternate>;
    1103              :         static constexpr auto rule(a, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2, make_alternate>;
    1104              :         static constexpr auto rule(a, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2, make_alternate>;
    1105              :         static constexpr auto rule(a, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2, make_alternate>;
    1106              :         static constexpr auto rule(a, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2, make_alternate>;
    1107              :         static constexpr auto rule(a, ctll::term<'\x29'>) -> ctll::push<push_empty, make_alternate>;
    1108              :         static constexpr auto rule(a, ctll::epsilon) -> ctll::push<push_empty, make_alternate>;
    1109              :         static constexpr auto rule(a, ctll::set<'*','+','?','\x7B','|','\x7D'>) -> ctll::reject;
    1110              : 
    1111              :         static constexpr auto rule(b, ctll::term<','>) -> ctll::push<ctll::anything, n>;
    1112              :         static constexpr auto rule(b, ctll::term<'\x7D'>) -> ctll::push<repeat_exactly, ctll::anything>;
    1113              : 
    1114              :         static constexpr auto rule(backslash, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
    1115              :         static constexpr auto rule(backslash, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
    1116              :         static constexpr auto rule(backslash, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
    1117              :         static constexpr auto rule(backslash, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
    1118              :         static constexpr auto rule(backslash, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
    1119              :         static constexpr auto rule(backslash, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
    1120              :         static constexpr auto rule(backslash, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
    1121              :         static constexpr auto rule(backslash, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
    1122              :         static constexpr auto rule(backslash, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
    1123              :         static constexpr auto rule(backslash, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
    1124              :         static constexpr auto rule(backslash, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
    1125              :         static constexpr auto rule(backslash, ctll::set<'1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, make_back_reference>;
    1126              :         static constexpr auto rule(backslash, ctll::term<'g'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, m>;
    1127              :         static constexpr auto rule(backslash, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
    1128              :         static constexpr auto rule(backslash, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
    1129              :         static constexpr auto rule(backslash, ctll::term<'u'>) -> ctll::push<ctll::anything, k>;
    1130              :         static constexpr auto rule(backslash, ctll::term<'x'>) -> ctll::push<ctll::anything, l>;
    1131              :         static constexpr auto rule(backslash, ctll::term<'A'>) -> ctll::push<ctll::anything, push_assert_subject_begin>;
    1132              :         static constexpr auto rule(backslash, ctll::term<'z'>) -> ctll::push<ctll::anything, push_assert_subject_end>;
    1133              :         static constexpr auto rule(backslash, ctll::term<'Z'>) -> ctll::push<ctll::anything, push_assert_subject_end_with_lineend>;
    1134              :         static constexpr auto rule(backslash, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character>;
    1135              :         static constexpr auto rule(backslash, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm>;
    1136              :         static constexpr auto rule(backslash, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape>;
    1137              :         static constexpr auto rule(backslash, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed>;
    1138              :         static constexpr auto rule(backslash, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline>;
    1139              :         static constexpr auto rule(backslash, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null>;
    1140              :         static constexpr auto rule(backslash, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage>;
    1141              :         static constexpr auto rule(backslash, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab>;
    1142              :         static constexpr auto rule(backslash, ctll::term<'B'>) -> ctll::push<ctll::anything, push_not_word_boundary>;
    1143              :         static constexpr auto rule(backslash, ctll::term<'b'>) -> ctll::push<ctll::anything, push_word_boundary>;
    1144              : 
    1145              :         static constexpr auto rule(backslash_range, ctll::term<'u'>) -> ctll::push<ctll::anything, k>;
    1146              :         static constexpr auto rule(backslash_range, ctll::term<'x'>) -> ctll::push<ctll::anything, l>;
    1147              :         static constexpr auto rule(backslash_range, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character>;
    1148              :         static constexpr auto rule(backslash_range, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm>;
    1149              :         static constexpr auto rule(backslash_range, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape>;
    1150              :         static constexpr auto rule(backslash_range, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed>;
    1151              :         static constexpr auto rule(backslash_range, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline>;
    1152              :         static constexpr auto rule(backslash_range, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null>;
    1153              :         static constexpr auto rule(backslash_range, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage>;
    1154              :         static constexpr auto rule(backslash_range, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab>;
    1155              : 
    1156              :         static constexpr auto rule(block, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1157              :         static constexpr auto rule(block, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1158              :         static constexpr auto rule(block, ctll::term<'?'>) -> ctll::push<ctll::anything, d>;
    1159              :         static constexpr auto rule(block, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1160              :         static constexpr auto rule(block, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1161              :         static constexpr auto rule(block, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1162              :         static constexpr auto rule(block, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1163              :         static constexpr auto rule(block, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1164              :         static constexpr auto rule(block, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2, make_capture, ctll::term<'\x29'>>;
    1165              :         static constexpr auto rule(block, ctll::term<'|'>) -> ctll::push<ctll::anything, push_empty, content_or_empty, make_alternate, make_capture, ctll::term<'\x29'>>;
    1166              :         static constexpr auto rule(block, ctll::term<'\x29'>) -> ctll::push<push_empty, make_capture, ctll::anything>;
    1167              :         static constexpr auto rule(block, ctll::set<'*','+','\x7B','\x7D'>) -> ctll::reject;
    1168              : 
    1169              :         static constexpr auto rule(block_name2, ctll::set<'>','\x7D'>) -> ctll::epsilon;
    1170              :         static constexpr auto rule(block_name2, ctll::set<'0','1','2','3','4','5','6','7','8','9','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>;
    1171              : 
    1172              :         static constexpr auto rule(block_name, 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>;
    1173              : 
    1174              :         static constexpr auto rule(c, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_start, set2b, set_make, ctll::term<']'>>;
    1175              :         static constexpr auto rule(c, ctll::term<'\\'>) -> ctll::push<ctll::anything, e, set_start, set2b, set_make, ctll::term<']'>>;
    1176              :         static constexpr auto rule(c, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>) -> ctll::push<ctll::anything, push_character, range, set_start, set2b, set_make, ctll::term<']'>>;
    1177              :         static constexpr auto rule(c, _others) -> ctll::push<ctll::anything, push_character, range, set_start, set2b, set_make, ctll::term<']'>>;
    1178              :         static constexpr auto rule(c, ctll::term<'^'>) -> ctll::push<ctll::anything, set2a, set_make_negative, ctll::term<']'>>;
    1179              :         static constexpr auto rule(c, ctll::set<'-',']'>) -> ctll::reject;
    1180              : 
    1181              :         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>;
    1182              :         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>;
    1183              :         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>;
    1184              :         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>;
    1185              :         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>;
    1186              :         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>;
    1187              :         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>;
    1188              :         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>;
    1189              :         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>;
    1190              :         static constexpr auto rule(class_named_name, ctll::term<'a'>) -> ctll::push<ctll::anything, g>;
    1191              :         static constexpr auto rule(class_named_name, ctll::term<'p'>) -> ctll::push<ctll::anything, h>;
    1192              : 
    1193              :         static constexpr auto rule(content2, ctll::term<'\x29'>) -> ctll::epsilon;
    1194              :         static constexpr auto rule(content2, ctll::epsilon) -> ctll::epsilon;
    1195              :         static constexpr auto rule(content2, ctll::term<'|'>) -> ctll::push<ctll::anything, a>;
    1196              : 
    1197              :         static constexpr auto rule(content_in_capture, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2>;
    1198              :         static constexpr auto rule(content_in_capture, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
    1199              :         static constexpr auto rule(content_in_capture, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2>;
    1200              :         static constexpr auto rule(content_in_capture, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2>;
    1201              :         static constexpr auto rule(content_in_capture, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2>;
    1202              :         static constexpr auto rule(content_in_capture, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2>;
    1203              :         static constexpr auto rule(content_in_capture, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
    1204              :         static constexpr auto rule(content_in_capture, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2>;
    1205              :         static constexpr auto rule(content_in_capture, ctll::term<'|'>) -> ctll::push<ctll::anything, push_empty, content_or_empty, make_alternate>;
    1206              :         static constexpr auto rule(content_in_capture, ctll::term<'\x29'>) -> ctll::push<push_empty>;
    1207              :         static constexpr auto rule(content_in_capture, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject;
    1208              : 
    1209              :         static constexpr auto rule(content_or_empty, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2>;
    1210              :         static constexpr auto rule(content_or_empty, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
    1211              :         static constexpr auto rule(content_or_empty, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2>;
    1212              :         static constexpr auto rule(content_or_empty, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2>;
    1213              :         static constexpr auto rule(content_or_empty, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2>;
    1214              :         static constexpr auto rule(content_or_empty, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2>;
    1215              :         static constexpr auto rule(content_or_empty, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
    1216              :         static constexpr auto rule(content_or_empty, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2>;
    1217              :         static constexpr auto rule(content_or_empty, ctll::term<'\x29'>) -> ctll::push<push_empty>;
    1218              :         static constexpr auto rule(content_or_empty, ctll::set<'*','+','?','\x7B','|','\x7D'>) -> ctll::reject;
    1219              : 
    1220              :         static constexpr auto rule(d, ctll::term<'i'>) -> ctll::push<ctll::anything, mode_case_insensitive, mode_switch2>;
    1221              :         static constexpr auto rule(d, ctll::term<'c'>) -> ctll::push<ctll::anything, mode_case_sensitive, mode_switch2>;
    1222              :         static constexpr auto rule(d, ctll::term<'m'>) -> ctll::push<ctll::anything, mode_multiline, mode_switch2>;
    1223              :         static constexpr auto rule(d, ctll::term<'s'>) -> ctll::push<ctll::anything, mode_singleline, mode_switch2>;
    1224              :         static constexpr auto rule(d, ctll::term<'<'>) -> ctll::push<ctll::anything, o>;
    1225              :         static constexpr auto rule(d, ctll::term<':'>) -> ctll::push<ctll::anything, reset_capture, content_in_capture, ctll::term<'\x29'>>;
    1226              :         static constexpr auto rule(d, ctll::term<'>'>) -> ctll::push<ctll::anything, reset_capture, start_atomic, content_in_capture, make_atomic, ctll::term<'\x29'>>;
    1227              :         static constexpr auto rule(d, ctll::term<'!'>) -> ctll::push<ctll::anything, reset_capture, start_lookahead_negative, content_in_capture, look_finish, ctll::term<'\x29'>>;
    1228              :         static constexpr auto rule(d, ctll::term<'='>) -> ctll::push<ctll::anything, reset_capture, start_lookahead_positive, content_in_capture, look_finish, ctll::term<'\x29'>>;
    1229              : 
    1230              :         static constexpr auto rule(e, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
    1231              :         static constexpr auto rule(e, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
    1232              :         static constexpr auto rule(e, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
    1233              :         static constexpr auto rule(e, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
    1234              :         static constexpr auto rule(e, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
    1235              :         static constexpr auto rule(e, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
    1236              :         static constexpr auto rule(e, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
    1237              :         static constexpr auto rule(e, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
    1238              :         static constexpr auto rule(e, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
    1239              :         static constexpr auto rule(e, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
    1240              :         static constexpr auto rule(e, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
    1241              :         static constexpr auto rule(e, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
    1242              :         static constexpr auto rule(e, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
    1243              :         static constexpr auto rule(e, ctll::term<'u'>) -> ctll::push<ctll::anything, k, range>;
    1244              :         static constexpr auto rule(e, ctll::term<'x'>) -> ctll::push<ctll::anything, l, range>;
    1245              :         static constexpr auto rule(e, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character, range>;
    1246              :         static constexpr auto rule(e, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm, range>;
    1247              :         static constexpr auto rule(e, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape, range>;
    1248              :         static constexpr auto rule(e, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed, range>;
    1249              :         static constexpr auto rule(e, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline, range>;
    1250              :         static constexpr auto rule(e, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null, range>;
    1251              :         static constexpr auto rule(e, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage, range>;
    1252              :         static constexpr auto rule(e, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab, range>;
    1253              : 
    1254              :         static constexpr auto rule(f, ctll::term<'d'>) -> ctll::push<ctll::anything, class_digit>;
    1255              :         static constexpr auto rule(f, ctll::term<'h'>) -> ctll::push<ctll::anything, class_horizontal_space>;
    1256              :         static constexpr auto rule(f, ctll::term<'H'>) -> ctll::push<ctll::anything, class_non_horizontal_space>;
    1257              :         static constexpr auto rule(f, ctll::term<'V'>) -> ctll::push<ctll::anything, class_non_vertical_space>;
    1258              :         static constexpr auto rule(f, ctll::term<'D'>) -> ctll::push<ctll::anything, class_nondigit>;
    1259              :         static constexpr auto rule(f, ctll::term<'N'>) -> ctll::push<ctll::anything, class_nonnewline>;
    1260              :         static constexpr auto rule(f, ctll::term<'S'>) -> ctll::push<ctll::anything, class_nonspace>;
    1261              :         static constexpr auto rule(f, ctll::term<'W'>) -> ctll::push<ctll::anything, class_nonword>;
    1262              :         static constexpr auto rule(f, ctll::term<'s'>) -> ctll::push<ctll::anything, class_space>;
    1263              :         static constexpr auto rule(f, ctll::term<'v'>) -> ctll::push<ctll::anything, class_vertical_space>;
    1264              :         static constexpr auto rule(f, ctll::term<'w'>) -> ctll::push<ctll::anything, class_word>;
    1265              :         static constexpr auto rule(f, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property>;
    1266              :         static constexpr auto rule(f, ctll::term<'P'>) -> ctll::push<ctll::anything, ctll::term<'\x7B'>, property_name, ctll::term<'\x7D'>, make_property_negative>;
    1267              :         static constexpr auto rule(f, ctll::term<'u'>) -> ctll::push<ctll::anything, k, range>;
    1268              :         static constexpr auto rule(f, ctll::term<'x'>) -> ctll::push<ctll::anything, l, range>;
    1269              :         static constexpr auto rule(f, ctll::set<'$','\x28','\x29','*','+','-','.','/','<','>','?','[','\\','\"',']','^','\x7B','|','\x7D'>) -> ctll::push<ctll::anything, push_character, range>;
    1270              :         static constexpr auto rule(f, ctll::term<'a'>) -> ctll::push<ctll::anything, push_character_alarm, range>;
    1271              :         static constexpr auto rule(f, ctll::term<'e'>) -> ctll::push<ctll::anything, push_character_escape, range>;
    1272              :         static constexpr auto rule(f, ctll::term<'f'>) -> ctll::push<ctll::anything, push_character_formfeed, range>;
    1273              :         static constexpr auto rule(f, ctll::term<'n'>) -> ctll::push<ctll::anything, push_character_newline, range>;
    1274              :         static constexpr auto rule(f, ctll::term<'0'>) -> ctll::push<ctll::anything, push_character_null, range>;
    1275              :         static constexpr auto rule(f, ctll::term<'r'>) -> ctll::push<ctll::anything, push_character_return_carriage, range>;
    1276              :         static constexpr auto rule(f, ctll::term<'t'>) -> ctll::push<ctll::anything, push_character_tab, range>;
    1277              : 
    1278              :         static constexpr auto rule(g, ctll::term<'s'>) -> ctll::push<ctll::anything, ctll::term<'c'>, ctll::term<'i'>, ctll::term<'i'>, class_named_ascii>;
    1279              :         static constexpr auto rule(g, ctll::term<'l'>) -> ctll::push<ctll::anything, p>;
    1280              : 
    1281              :         static constexpr auto rule(h, ctll::term<'r'>) -> ctll::push<ctll::anything, ctll::term<'i'>, ctll::term<'n'>, ctll::term<'t'>, class_named_print>;
    1282              :         static constexpr auto rule(h, ctll::term<'u'>) -> ctll::push<ctll::anything, ctll::term<'n'>, ctll::term<'c'>, ctll::term<'t'>, class_named_punct>;
    1283              : 
    1284              :         static constexpr auto rule(hexdec_repeat, ctll::term<'\x7D'>) -> ctll::epsilon;
    1285              :         static constexpr auto rule(hexdec_repeat, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>) -> ctll::push<ctll::anything, push_hexdec, hexdec_repeat>;
    1286              : 
    1287              :         static constexpr auto rule(i, ctll::term<'^'>) -> ctll::push<ctll::anything, class_named_name, negate_class_named, ctll::term<':'>, ctll::term<']'>>;
    1288              :         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<']'>>;
    1289              :         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<']'>>;
    1290              :         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<']'>>;
    1291              :         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<']'>>;
    1292              :         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<']'>>;
    1293              :         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<']'>>;
    1294              :         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<']'>>;
    1295              :         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<']'>>;
    1296              :         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<']'>>;
    1297              :         static constexpr auto rule(i, ctll::term<'a'>) -> ctll::push<ctll::anything, g, ctll::term<':'>, ctll::term<']'>>;
    1298              :         static constexpr auto rule(i, ctll::term<'p'>) -> ctll::push<ctll::anything, h, ctll::term<':'>, ctll::term<']'>>;
    1299              : 
    1300              :         static constexpr auto rule(j, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash_range, make_range>;
    1301              :         static constexpr auto rule(j, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>) -> ctll::push<ctll::anything, push_character, make_range>;
    1302              :         static constexpr auto rule(j, _others) -> ctll::push<ctll::anything, push_character, make_range>;
    1303              :         static constexpr auto rule(j, ctll::set<'-','[',']'>) -> ctll::reject;
    1304              : 
    1305              :         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>;
    1306              :         static constexpr auto rule(k, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>) -> 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>;
    1307              : 
    1308              :         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>;
    1309              :         static constexpr auto rule(l, ctll::set<'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'>) -> 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>;
    1310              : 
    1311              :         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>;
    1312              :         static constexpr auto rule(m, ctll::term<'-'>) -> ctll::push<ctll::anything, number, ctll::term<'\x7D'>, make_relative_back_reference>;
    1313              :         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>;
    1314              : 
    1315              :         static constexpr auto rule(mod, ctll::set<'!','$','\x28','\x29',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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::epsilon;
    1316              :         static constexpr auto rule(mod, ctll::epsilon) -> ctll::epsilon;
    1317              :         static constexpr auto rule(mod, _others) -> ctll::epsilon;
    1318              :         static constexpr auto rule(mod, ctll::term<'?'>) -> ctll::push<ctll::anything, make_lazy>;
    1319              :         static constexpr auto rule(mod, ctll::term<'+'>) -> ctll::push<ctll::anything, make_possessive>;
    1320              :         static constexpr auto rule(mod, ctll::set<'*','\x7B','\x7D'>) -> ctll::reject;
    1321              : 
    1322              :         static constexpr auto rule(mode_switch2, ctll::term<'i'>) -> ctll::push<ctll::anything, mode_case_insensitive, mode_switch2>;
    1323              :         static constexpr auto rule(mode_switch2, ctll::term<'c'>) -> ctll::push<ctll::anything, mode_case_sensitive, mode_switch2>;
    1324              :         static constexpr auto rule(mode_switch2, ctll::term<'m'>) -> ctll::push<ctll::anything, mode_multiline, mode_switch2>;
    1325              :         static constexpr auto rule(mode_switch2, ctll::term<'s'>) -> ctll::push<ctll::anything, mode_singleline, mode_switch2>;
    1326              :         static constexpr auto rule(mode_switch2, ctll::term<'\x29'>) -> ctll::push<ctll::anything>;
    1327              : 
    1328              :         static constexpr auto rule(n, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<number, repeat_ab, ctll::term<'\x7D'>, mod>;
    1329              :         static constexpr auto rule(n, ctll::term<'\x7D'>) -> ctll::push<repeat_at_least, ctll::anything, mod>;
    1330              : 
    1331              :         static constexpr auto rule(number2, ctll::set<',','\x7D'>) -> ctll::epsilon;
    1332              :         static constexpr auto rule(number2, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, push_number, number2>;
    1333              : 
    1334              :         static constexpr auto rule(number, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, number2>;
    1335              : 
    1336              :         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<block_name, ctll::term<'>'>, content_in_capture, make_capture_with_name, ctll::term<'\x29'>>;
    1337              :         static constexpr auto rule(o, ctll::term<'!'>) -> ctll::push<ctll::anything, reset_capture, start_lookbehind_negative, content_in_capture, look_finish, ctll::term<'\x29'>>;
    1338              :         static constexpr auto rule(o, ctll::term<'='>) -> ctll::push<ctll::anything, reset_capture, start_lookbehind_positive, content_in_capture, look_finish, ctll::term<'\x29'>>;
    1339              : 
    1340              :         static constexpr auto rule(opt_content, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, content2>;
    1341              :         static constexpr auto rule(opt_content, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, content2>;
    1342              :         static constexpr auto rule(opt_content, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, content2>;
    1343              :         static constexpr auto rule(opt_content, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, content2>;
    1344              :         static constexpr auto rule(opt_content, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, content2>;
    1345              :         static constexpr auto rule(opt_content, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, content2>;
    1346              :         static constexpr auto rule(opt_content, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, content2>;
    1347              :         static constexpr auto rule(opt_content, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, content2>;
    1348              :         static constexpr auto rule(opt_content, ctll::epsilon) -> ctll::push<push_empty>;
    1349              :         static constexpr auto rule(opt_content, ctll::set<'\x29','*','+','?','\x7B','|','\x7D'>) -> ctll::reject;
    1350              : 
    1351              :         static constexpr auto rule(p, ctll::term<'p'>) -> ctll::push<ctll::anything, ctll::term<'h'>, ctll::term<'a'>, class_named_alpha>;
    1352              :         static constexpr auto rule(p, ctll::term<'n'>) -> ctll::push<ctll::anything, ctll::term<'u'>, ctll::term<'m'>, class_named_alnum>;
    1353              : 
    1354              :         static constexpr auto rule(property_name2, ctll::term<'\x7D'>) -> ctll::epsilon;
    1355              :         static constexpr auto rule(property_name2, ctll::term<'='>) -> ctll::push<ctll::anything, property_value>;
    1356              :         static constexpr auto rule(property_name2, ctll::set<'.','0','1','2','3','4','5','6','7','8','9','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_property_name, property_name2>;
    1357              : 
    1358              :         static constexpr auto rule(property_name, ctll::set<'.','0','1','2','3','4','5','6','7','8','9','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_property_name, property_name2>;
    1359              : 
    1360              :         static constexpr auto rule(property_value2, ctll::term<'\x7D'>) -> ctll::epsilon;
    1361              :         static constexpr auto rule(property_value2, ctll::set<'.','0','1','2','3','4','5','6','7','8','9','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_property_value, property_value2>;
    1362              : 
    1363              :         static constexpr auto rule(property_value, ctll::set<'.','0','1','2','3','4','5','6','7','8','9','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_property_value, property_value2>;
    1364              : 
    1365              :         static constexpr auto rule(range, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>) -> ctll::epsilon;
    1366              :         static constexpr auto rule(range, ctll::epsilon) -> ctll::epsilon;
    1367              :         static constexpr auto rule(range, _others) -> ctll::epsilon;
    1368              :         static constexpr auto rule(range, ctll::term<'-'>) -> ctll::push<ctll::anything, j>;
    1369              : 
    1370              :         static constexpr auto rule(repeat, ctll::set<'!','$','\x28','\x29',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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::epsilon;
    1371              :         static constexpr auto rule(repeat, ctll::epsilon) -> ctll::epsilon;
    1372              :         static constexpr auto rule(repeat, _others) -> ctll::epsilon;
    1373              :         static constexpr auto rule(repeat, ctll::term<'?'>) -> ctll::push<ctll::anything, make_optional, mod>;
    1374              :         static constexpr auto rule(repeat, ctll::term<'\x7B'>) -> ctll::push<ctll::anything, number, b>;
    1375              :         static constexpr auto rule(repeat, ctll::term<'+'>) -> ctll::push<ctll::anything, repeat_plus, mod>;
    1376              :         static constexpr auto rule(repeat, ctll::term<'*'>) -> ctll::push<ctll::anything, repeat_star, mod>;
    1377              :         static constexpr auto rule(repeat, ctll::term<'\x7D'>) -> ctll::reject;
    1378              : 
    1379              :         static constexpr auto rule(set2a, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_start, set2b>;
    1380              :         static constexpr auto rule(set2a, ctll::term<'\\'>) -> ctll::push<ctll::anything, f, set_start, set2b>;
    1381              :         static constexpr auto rule(set2a, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>) -> ctll::push<ctll::anything, push_character, range, set_start, set2b>;
    1382              :         static constexpr auto rule(set2a, _others) -> ctll::push<ctll::anything, push_character, range, set_start, set2b>;
    1383              :         static constexpr auto rule(set2a, ctll::term<']'>) -> ctll::push<set_empty>;
    1384              :         static constexpr auto rule(set2a, ctll::term<'-'>) -> ctll::reject;
    1385              : 
    1386              :         static constexpr auto rule(set2b, ctll::term<']'>) -> ctll::epsilon;
    1387              :         static constexpr auto rule(set2b, ctll::term<'['>) -> ctll::push<ctll::anything, ctll::term<':'>, i, range, set_combine, set2b>;
    1388              :         static constexpr auto rule(set2b, ctll::term<'\\'>) -> ctll::push<ctll::anything, f, set_combine, set2b>;
    1389              :         static constexpr auto rule(set2b, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','?','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'>) -> ctll::push<ctll::anything, push_character, range, set_combine, set2b>;
    1390              :         static constexpr auto rule(set2b, _others) -> ctll::push<ctll::anything, push_character, range, set_combine, set2b>;
    1391              :         static constexpr auto rule(set2b, ctll::term<'-'>) -> ctll::reject;
    1392              : 
    1393              :         static constexpr auto rule(string2, ctll::set<'\x29','|'>) -> ctll::epsilon;
    1394              :         static constexpr auto rule(string2, ctll::epsilon) -> ctll::epsilon;
    1395              :         static constexpr auto rule(string2, ctll::term<'\\'>) -> ctll::push<ctll::anything, backslash, repeat, string2, make_sequence>;
    1396              :         static constexpr auto rule(string2, ctll::term<'['>) -> ctll::push<ctll::anything, c, repeat, string2, make_sequence>;
    1397              :         static constexpr auto rule(string2, ctll::term<'\x28'>) -> ctll::push<ctll::anything, prepare_capture, block, repeat, string2, make_sequence>;
    1398              :         static constexpr auto rule(string2, ctll::term<'^'>) -> ctll::push<ctll::anything, push_assert_begin, repeat, string2, make_sequence>;
    1399              :         static constexpr auto rule(string2, ctll::term<'$'>) -> ctll::push<ctll::anything, push_assert_end, repeat, string2, make_sequence>;
    1400              :         static constexpr auto rule(string2, ctll::set<'!',',','-','/','0','1','2','3','4','5','6','7','8','9',':','<','=','>','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_character, repeat, string2, make_sequence>;
    1401              :         static constexpr auto rule(string2, _others) -> ctll::push<ctll::anything, push_character, repeat, string2, make_sequence>;
    1402              :         static constexpr auto rule(string2, ctll::term<'.'>) -> ctll::push<ctll::anything, push_character_anything, repeat, string2, make_sequence>;
    1403              :         static constexpr auto rule(string2, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject;
    1404              : 
    1405              : };
    1406              : 
    1407              : }
    1408              : 
    1409              : #endif //CTRE__PCRE__HPP
    1410              : 
    1411              : #ifndef CTRE__ROTATE__HPP
    1412              : #define CTRE__ROTATE__HPP
    1413              : 
    1414              : #ifndef CTRE__ATOMS__HPP
    1415              : #define CTRE__ATOMS__HPP
    1416              : 
    1417              : #ifndef CTRE__ATOMS_CHARACTERS__HPP
    1418              : #define CTRE__ATOMS_CHARACTERS__HPP
    1419              : 
    1420              : #ifndef CTRE__UTILITY__HPP
    1421              : #define CTRE__UTILITY__HPP
    1422              : 
    1423              : #define CTRE_CNTTP_COMPILER_CHECK CTLL_CNTTP_COMPILER_CHECK
    1424              : 
    1425              : #ifdef CTRE_IN_A_MODULE
    1426              : #define CTRE_EXPORT export
    1427              : #else
    1428              : #define CTRE_EXPORT 
    1429              : #endif
    1430              : 
    1431              : #if __GNUC__ > 9
    1432              : #if __has_cpp_attribute(likely)
    1433              : #define CTRE_LIKELY [[likely]]
    1434              : #else
    1435              : #define CTRE_LIKELY
    1436              : #endif
    1437              : 
    1438              : #if __has_cpp_attribute(unlikely)
    1439              : #define CTRE_UNLIKELY [[unlikely]]
    1440              : #else
    1441              : #define CTRE_UNLIKELY
    1442              : #endif
    1443              : #else
    1444              : #define CTRE_LIKELY
    1445              : #define CTRE_UNLIKELY
    1446              : #endif
    1447              : 
    1448              : #ifdef _MSC_VER
    1449              : #define CTRE_FORCE_INLINE __forceinline
    1450              : #if __has_cpp_attribute(msvc::flatten)
    1451              : #define CTRE_FLATTEN [[msvc::flatten]]
    1452              : #elif _MSC_VER >= 1930 && !defined(__clang__)
    1453              : #define CTRE_FLATTEN [[msvc::flatten]]
    1454              : #else
    1455              : #define CTRE_FLATTEN
    1456              : #endif
    1457              : #else
    1458              : #define CTRE_FORCE_INLINE inline __attribute__((always_inline))
    1459              : #define CTRE_FLATTEN __attribute__((flatten))
    1460              : #endif
    1461              : 
    1462              : #endif
    1463              : 
    1464              : #ifndef CTRE_V2__CTRE__FLAGS_AND_MODES__HPP
    1465              : #define CTRE_V2__CTRE__FLAGS_AND_MODES__HPP
    1466              : 
    1467              : namespace ctre {
    1468              : 
    1469              : struct singleline { };
    1470              : struct multiline { };
    1471              : 
    1472              : struct case_sensitive { };
    1473              : struct case_insensitive { };
    1474              : 
    1475              : using ci = case_insensitive;
    1476              : using cs = case_sensitive;
    1477              : 
    1478              : template <typename... Flags> struct flag_list { };
    1479              : 
    1480              : struct flags {
    1481              :         bool block_empty_match = false;
    1482              :         bool multiline = false;
    1483              :         bool case_insensitive = false;
    1484              :         
    1485              :         constexpr flags() = default;
    1486              :         constexpr flags(const flags &) = default;
    1487              :         constexpr flags(flags &&) = default;
    1488              :         
    1489              :         constexpr CTRE_FORCE_INLINE flags(ctre::singleline v) noexcept { set_flag(v); }
    1490              :         constexpr CTRE_FORCE_INLINE flags(ctre::multiline v) noexcept { set_flag(v); }
    1491              :         constexpr CTRE_FORCE_INLINE flags(ctre::case_sensitive v) noexcept { set_flag(v); }
    1492              :         constexpr CTRE_FORCE_INLINE flags(ctre::case_insensitive v) noexcept { set_flag(v); }
    1493              :         
    1494              :         
    1495            0 :         template <typename... Args> constexpr CTRE_FORCE_INLINE flags(ctll::list<Args...>) noexcept {
    1496            0 :                 (this->set_flag(Args{}), ...);
    1497            0 :         }
    1498              :         
    1499              :         constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_insensitive) noexcept {
    1500              :                 f.case_insensitive = true;
    1501              :                 return f;
    1502              :         }
    1503              :         
    1504              :         constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_sensitive) noexcept {
    1505              :                 f.case_insensitive = false;
    1506              :                 return f;
    1507              :         }
    1508              :         
    1509              :         constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_singleline) noexcept {
    1510              :                 f.multiline = false;
    1511              :                 return f;
    1512              :         }
    1513              :         
    1514              :         constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_multiline) noexcept {
    1515              :                 f.multiline = true;
    1516              :                 return f;
    1517              :         }
    1518              :         
    1519              :         constexpr CTRE_FORCE_INLINE void set_flag(ctre::singleline) noexcept {
    1520            0 :                 multiline = false;
    1521            0 :         }
    1522              :         
    1523              :         constexpr CTRE_FORCE_INLINE void set_flag(ctre::multiline) noexcept {
    1524              :                 multiline = true;
    1525              :         }
    1526              :         
    1527              :         constexpr CTRE_FORCE_INLINE void set_flag(ctre::case_insensitive) noexcept {
    1528              :                 case_insensitive = true;
    1529              :         }
    1530              :         
    1531              :         constexpr CTRE_FORCE_INLINE void set_flag(ctre::case_sensitive) noexcept {
    1532              :                 case_insensitive = false;
    1533              :         }
    1534              : };
    1535              : 
    1536              : constexpr CTRE_FORCE_INLINE auto not_empty_match(flags f) {
    1537            0 :         f.block_empty_match = true;
    1538            0 :         return f;
    1539              : }
    1540              : 
    1541              : constexpr CTRE_FORCE_INLINE auto consumed_something(flags f, bool condition = true) {
    1542            0 :         if (condition) f.block_empty_match = false;
    1543            0 :         return f;
    1544              : }
    1545              : 
    1546              : constexpr CTRE_FORCE_INLINE bool cannot_be_empty_match(flags f) {
    1547            0 :         return f.block_empty_match;
    1548              : }
    1549              : 
    1550              : constexpr CTRE_FORCE_INLINE bool multiline_mode(flags f) {
    1551            0 :         return f.multiline;
    1552              : }
    1553              : 
    1554              : constexpr CTRE_FORCE_INLINE bool is_case_insensitive(flags f) {
    1555            0 :         return f.case_insensitive;
    1556              : }
    1557              : 
    1558              : } // namespace ctre
    1559              : 
    1560              : #endif
    1561              : 
    1562              : #ifndef CTRE_IN_A_MODULE
    1563              : #include <cstdint>
    1564              : #endif
    1565              : 
    1566              : namespace ctre {
    1567              :         
    1568              : // sfinae check for types here
    1569              : 
    1570              : template <typename T> class MatchesCharacter {
    1571              :         template <typename Y, typename CharT> static auto test(CharT c) -> decltype(Y::match_char(c, std::declval<const flags &>()), std::true_type());
    1572              :         template <typename> static auto test(...) -> std::false_type;
    1573              : public:
    1574              :         template <typename CharT> static inline constexpr bool value = decltype(test<T>(std::declval<CharT>()))();
    1575              : };
    1576              : 
    1577              : template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha(T v) {
    1578              :         return ((v >= static_cast<T>('a') && v <= static_cast<T>('z')) || (v >= static_cast<T>('A') && v <= static_cast<T>('Z')));
    1579              : }
    1580              : 
    1581              : template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha_lowercase(T v) {
    1582              :         return (v >= static_cast<T>('a')) && (v <= static_cast<T>('z'));
    1583              : }
    1584              : 
    1585              : template <typename T> constexpr CTRE_FORCE_INLINE bool is_ascii_alpha_uppercase(T v) {
    1586              :         return (v >= static_cast<T>('A')) && v <= (static_cast<T>('Z'));
    1587              : }
    1588              : 
    1589              : template <auto V> struct character {
    1590              :         template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
    1591              :                 if constexpr (is_ascii_alpha(V)) {
    1592            0 :                         if (is_case_insensitive(f)) {
    1593            0 :                                 if (value == (V ^ static_cast<decltype(V)>(0x20))) {
    1594            0 :                                         return true;//
    1595              :                                 }
    1596              :                         }       
    1597              :                 }
    1598            0 :                 return static_cast<std::make_unsigned_t<CharT>>(value) == V;
    1599              :         }
    1600              : };
    1601              : 
    1602              : template <typename... Content> struct negative_set {
    1603              :         template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char([[maybe_unused]] CharT value, const flags & f) noexcept {
    1604              :                 return !(Content::match_char(value, f) || ... || false);
    1605              :         }
    1606              : };
    1607              : 
    1608              : template <typename... Content> struct set {
    1609              :         template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char([[maybe_unused]]  CharT value, const flags & f) noexcept {
    1610            0 :                 return (Content::match_char(value, f) || ... || false);
    1611              :         }
    1612              : };
    1613              : 
    1614              : template <auto... Cs> struct enumeration : set<character<Cs>...> { };
    1615              : 
    1616              : template <typename... Content> struct negate {
    1617              :         template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char([[maybe_unused]] CharT value, const flags & f) noexcept {
    1618              :                 return !(Content::match_char(value, f) || ... || false);
    1619              :         }
    1620              : };
    1621              : 
    1622              : template <auto A, auto B> struct char_range {
    1623              :         template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value, const flags & f) noexcept {
    1624              :                 if constexpr (is_ascii_alpha_lowercase(A) && is_ascii_alpha_lowercase(B)) {
    1625              :                         if (is_case_insensitive(f)) {
    1626              :                                 if (value >= (A ^ static_cast<decltype(A)>(0x20)) && value <= (B ^ static_cast<decltype(B)>(0x20))) {
    1627              :                                         return true;//
    1628              :                                 }
    1629              :                         }       
    1630              :                 } else if constexpr (is_ascii_alpha_uppercase(A) && is_ascii_alpha_uppercase(B)) {
    1631              :                         if (is_case_insensitive(f)) {
    1632              :                                 if (value >= (A ^ static_cast<decltype(A)>(0x20)) && value <= (B ^ static_cast<decltype(B)>(0x20))) {
    1633              :                                         return true;//
    1634              :                                 }
    1635              :                         }       
    1636              :                 }
    1637            0 :                 return (static_cast<std::make_unsigned_t<CharT>>(value) >= A) && (static_cast<std::make_unsigned_t<CharT>>(value) <= B);
    1638              :         }
    1639              : };
    1640              : using word_chars = set<char_range<'A','Z'>, char_range<'a','z'>, char_range<'0','9'>, character<'_'> >;
    1641              : 
    1642              : using space_chars = enumeration<' ', '\t', '\n', '\v', '\f', '\r'>;
    1643              : 
    1644              : using vertical_space_chars = enumeration<
    1645              :         char{0x000A}, // Linefeed (LF)
    1646              :         char{0x000B}, // Vertical tab (VT)
    1647              :         char{0x000C}, // Form feed (FF)
    1648              :         char{0x000D}, // Carriage return (CR)
    1649              :         char32_t{0x0085}, // Next line (NEL)
    1650              :         char32_t{0x2028}, // Line separator
    1651              :         char32_t{0x2029} // Paragraph separator
    1652              : >;
    1653              : 
    1654              : using horizontal_space_chars = enumeration<
    1655              :     char{0x0009}, // Horizontal tab (HT)
    1656              :     char{0x0020}, // Space
    1657              :     char32_t{0x00A0}, // Non-break space
    1658              :     char32_t{0x1680}, // Ogham space mark
    1659              :     char32_t{0x180E}, // Mongolian vowel separator
    1660              :     char32_t{0x2000}, // En quad
    1661              :     char32_t{0x2001}, // Em quad
    1662              :     char32_t{0x2002}, // En space
    1663              :     char32_t{0x2003}, // Em space
    1664              :     char32_t{0x2004}, // Three-per-em space
    1665              :     char32_t{0x2005}, // Four-per-em space
    1666              :     char32_t{0x2006}, // Six-per-em space
    1667              :     char32_t{0x2007}, // Figure space
    1668              :     char32_t{0x2008}, // Punctuation space
    1669              :     char32_t{0x2009}, // Thin space
    1670              :     char32_t{0x200A}, // Hair space
    1671              :     char32_t{0x202F}, // Narrow no-break space
    1672              :     char32_t{0x205F}, // Medium mathematical space
    1673              :     char32_t{0x3000} // Ideographic space
    1674              : >;
    1675              : 
    1676              : using alphanum_chars = set<char_range<'A','Z'>, char_range<'a','z'>, char_range<'0','9'> >;
    1677              : 
    1678              : using alpha_chars = set<char_range<'A','Z'>, char_range<'a','z'> >;
    1679              : 
    1680              : using xdigit_chars = set<char_range<'A','F'>, char_range<'a','f'>, char_range<'0','9'> >;
    1681              : 
    1682              : using punct_chars
    1683              :     = enumeration<'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
    1684              :                   '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']',
    1685              :                   '^', '_', '`', '{', '|', '}', '~'>;
    1686              : 
    1687              : using digit_chars = char_range<'0','9'>;
    1688              : 
    1689              : using ascii_chars = char_range<'\x00','\x7F'>;
    1690              : 
    1691              : }
    1692              : 
    1693              : #endif
    1694              : 
    1695              : #ifndef CTRE_IN_A_MODULE
    1696              : #include <cstdint>
    1697              : #endif
    1698              : 
    1699              : namespace ctre {
    1700              :         
    1701              : // special helpers for matching
    1702              : struct accept { };
    1703              : struct reject { };
    1704              : struct start_mark { };
    1705              : struct end_mark { };
    1706              : struct end_cycle_mark { };
    1707              : struct end_lookahead_mark { };
    1708              : struct end_lookbehind_mark { };
    1709              : template <size_t Id> struct numeric_mark { };
    1710              : 
    1711              : struct any { };
    1712              : 
    1713              : // actual AST of regexp
    1714              : template <auto... Str> struct string { };
    1715              : template <typename... Opts> struct select { };
    1716              : template <typename... Content> struct sequence { };
    1717              : struct empty { };
    1718              : 
    1719              : template <size_t a, size_t b, typename... Content> struct repeat { };
    1720              : template <typename... Content> using plus = repeat<1,0,Content...>;
    1721              : template <typename... Content> using star = repeat<0,0,Content...>;
    1722              : 
    1723              : template <size_t a, size_t b, typename... Content> struct lazy_repeat { };
    1724              : template <typename... Content> using lazy_plus = lazy_repeat<1,0,Content...>;
    1725              : template <typename... Content> using lazy_star = lazy_repeat<0,0,Content...>;
    1726              : 
    1727              : template <size_t a, size_t b, typename... Content> struct possessive_repeat { };
    1728              : template <typename... Content> using possessive_plus = possessive_repeat<1,0,Content...>;
    1729              : template <typename... Content> using possessive_star = possessive_repeat<0,0,Content...>;
    1730              : 
    1731              : template <typename... Content> using optional = repeat<0,1,Content...>;
    1732              : template <typename... Content> using lazy_optional = lazy_repeat<0,1,Content...>;
    1733              : template <typename... Content> using possessive_optional = possessive_repeat<0,1,Content...>;
    1734              : 
    1735              : template <size_t Index, typename... Content> struct capture { };
    1736              : 
    1737              : template <size_t Index, typename Name, typename... Content> struct capture_with_name { };
    1738              : 
    1739              : template <size_t Index> struct back_reference { };
    1740              : template <typename Name> struct back_reference_with_name { };
    1741              : 
    1742              : template <typename Type> struct look_start { };
    1743              : 
    1744              : template <typename... Content> struct lookahead_positive { };
    1745              : template <typename... Content> struct lookahead_negative { };
    1746              : 
    1747              : template <typename... Content> struct lookbehind_positive { };
    1748              : template <typename... Content> struct lookbehind_negative { };
    1749              : 
    1750              : struct atomic_start { };
    1751              : 
    1752              : template <typename... Content> struct atomic_group { };
    1753              : 
    1754              : template <typename... Content> struct boundary { };
    1755              : template <typename... Content> struct not_boundary { };
    1756              : 
    1757              : using word_boundary = boundary<word_chars>;
    1758              : using not_word_boundary = not_boundary<word_chars>;
    1759              : 
    1760              : struct assert_subject_begin { };
    1761              : struct assert_subject_end { };
    1762              : struct assert_subject_end_line{ };
    1763              : struct assert_line_begin { };
    1764              : struct assert_line_end { };
    1765              : 
    1766              : template <typename> struct mode_switch { };
    1767              : 
    1768              : }
    1769              : 
    1770              : #endif
    1771              : 
    1772              : #ifndef CTRE__ATOMS_UNICODE__HPP
    1773              : #define CTRE__ATOMS_UNICODE__HPP
    1774              : 
    1775              : // master branch is not including unicode db (for now)
    1776              : #ifndef H_COR3NTIN_UNICODE_SYNOPSYS
    1777              : #define H_COR3NTIN_UNICODE_SYNOPSYS
    1778              : 
    1779              : #ifndef UNICODE_DB_IN_A_MODULE
    1780              : #include <string_view>
    1781              : #endif
    1782              : 
    1783              : namespace uni
    1784              : {
    1785              :     enum class category;
    1786              :     enum class property;
    1787              :     enum class version : unsigned char;
    1788              :     enum class script ;
    1789              :     enum class block;
    1790              : 
    1791              :     struct script_extensions_view {
    1792              :         constexpr script_extensions_view(char32_t);
    1793              : 
    1794              :         struct sentinel {};
    1795              :         struct iterator {
    1796              : 
    1797              :             constexpr iterator(char32_t c);
    1798              :             constexpr script operator*() const;
    1799              : 
    1800              :             constexpr iterator& operator++(int);
    1801              : 
    1802              :             constexpr iterator operator++();
    1803              : 
    1804              :             constexpr bool operator==(sentinel) const;
    1805              :             constexpr bool operator!=(sentinel) const;
    1806              : 
    1807              :         private:
    1808              :             char32_t m_c;
    1809              :             script m_script;
    1810              :             int idx = 1;
    1811              :         };
    1812              : 
    1813              :         constexpr iterator begin() const;
    1814              :         constexpr sentinel end() const;
    1815              : 
    1816              :         private:
    1817              :             char32_t c;
    1818              :     };
    1819              : 
    1820              :     struct numeric_value {
    1821              : 
    1822              :         constexpr double value() const;
    1823              :         constexpr long long numerator() const;
    1824              :         constexpr int denominator() const;
    1825              :         constexpr bool is_valid() const;
    1826              : 
    1827              :     protected:
    1828              :         constexpr numeric_value() = default;
    1829              :         constexpr numeric_value(long long n, int16_t d);
    1830              : 
    1831              :         long long _n = 0;
    1832              :         int16_t _d = 0;
    1833              :         friend constexpr numeric_value cp_numeric_value(char32_t cp);
    1834              :     };
    1835              : 
    1836              :     constexpr category cp_category(char32_t cp);
    1837              :     constexpr script cp_script(char32_t cp);
    1838              :     constexpr script_extensions_view cp_script_extensions(char32_t cp);
    1839              :     constexpr version cp_age(char32_t cp);
    1840              :     constexpr block cp_block(char32_t cp);
    1841              :     constexpr bool cp_is_valid(char32_t cp);
    1842              :     constexpr bool cp_is_assigned(char32_t cp);
    1843              :     constexpr bool cp_is_ascii(char32_t cp);
    1844              :     constexpr numeric_value cp_numeric_value(char32_t cp);
    1845              : 
    1846              :     template<script>
    1847              :     constexpr bool cp_script_is(char32_t);
    1848              :     template<property>
    1849              :     constexpr bool cp_property_is(char32_t);
    1850              :     template<category>
    1851              :     constexpr bool cp_category_is(char32_t);
    1852              : 
    1853              :     namespace detail
    1854              :     {
    1855              :         enum class binary_prop;
    1856              :         constexpr int propnamecomp(std::string_view sa, std::string_view sb);
    1857              :         constexpr binary_prop binary_prop_from_string(std::string_view s);
    1858              : 
    1859              :         template<binary_prop p>
    1860              :         constexpr bool get_binary_prop(char32_t) = delete;
    1861              : 
    1862              :         constexpr script   script_from_string(std::string_view s);
    1863              :         constexpr block    block_from_string(std::string_view s);
    1864              :         constexpr version  age_from_string(std::string_view a);
    1865              :         constexpr category category_from_string(std::string_view a);
    1866              : 
    1867              :         constexpr bool is_unassigned(category cat);
    1868              :         constexpr bool is_unknown(script s);
    1869              :         constexpr bool is_unknown(block b);
    1870              :         constexpr bool is_unassigned(version v);
    1871              :         constexpr bool is_unknown(binary_prop s);
    1872              :     }
    1873              : }
    1874              : 
    1875              : #endif
    1876              : 
    1877              : namespace ctre {
    1878              : 
    1879              : // properties name & value
    1880              : 
    1881              : template <auto... Str> struct property_name { };
    1882              : template <auto... Str> struct property_value { };
    1883              : 
    1884              : template <size_t Sz> constexpr std::string_view get_string_view(const char (& arr)[Sz]) noexcept {
    1885              :         return std::string_view(arr, Sz);
    1886              : }
    1887              : 
    1888              : // basic support for binary and type-value properties
    1889              : 
    1890              : template <typename T, T Type> struct binary_property;
    1891              : template <typename T, T Type, auto Value> struct property;
    1892              : 
    1893              : template <auto Type> using make_binary_property = binary_property<std::remove_const_t<decltype(Type)>, Type>;
    1894              : template <auto Type, auto Value> using make_property = property<std::remove_const_t<decltype(Type)>, Type, Value>;
    1895              : 
    1896              : // unicode TS#18 level 1.2 general_category
    1897              : template <uni::detail::binary_prop Property> struct binary_property<uni::detail::binary_prop, Property> {
    1898              :         template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
    1899              :                 return uni::detail::get_binary_prop<Property>(static_cast<char32_t>(static_cast<std::make_unsigned_t<CharT>>(c)));
    1900              :         }
    1901              : };
    1902              : 
    1903              : // unicode TS#18 level 1.2.2
    1904              : 
    1905              : enum class property_type {
    1906              :         script, script_extension, age, block, unknown
    1907              : };
    1908              : 
    1909              : // unicode TS#18 level 1.2.2
    1910              : 
    1911              : template <uni::script Script> struct binary_property<uni::script, Script> {
    1912              :         template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
    1913              :                 return uni::cp_script(c) == Script;
    1914              :         }
    1915              : };
    1916              : 
    1917              : template <uni::script Script> struct property<property_type, property_type::script_extension, Script> {
    1918              :         template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
    1919              :                 for (uni::script sc: uni::cp_script_extensions(c)) {
    1920              :                         if (sc == Script) return true;
    1921              :                 }
    1922              :                 return false;
    1923              :         }
    1924              : };
    1925              : 
    1926              : template <uni::version Age> struct binary_property<uni::version, Age> {
    1927              :         template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
    1928              :                 return uni::cp_age(c) <= Age;
    1929              :         }
    1930              : };
    1931              : 
    1932              : template <uni::block Block> struct binary_property<uni::block, Block> {
    1933              :         template <typename CharT> inline static constexpr bool match_char(CharT c, const flags &) noexcept {
    1934              :                 return uni::cp_block(c) == Block;
    1935              :         }
    1936              : };
    1937              : 
    1938              : // nonbinary properties
    1939              : 
    1940              : template <typename = void> // Make it always a template as propnamecomp isn't defined yet
    1941              : constexpr property_type property_type_from_name(std::string_view str) noexcept {
    1942              :         using namespace std::string_view_literals;
    1943              :         if (uni::detail::propnamecomp(str, "script"sv) == 0 || uni::detail::propnamecomp(str, "sc"sv) == 0) {
    1944              :                 return property_type::script;
    1945              :         } else if (uni::detail::propnamecomp(str, "script_extension"sv) == 0 || uni::detail::propnamecomp(str, "scx"sv) == 0) {
    1946              :                 return property_type::script_extension;
    1947              :         } else if (uni::detail::propnamecomp(str, "age"sv) == 0) {
    1948              :                 return property_type::age;
    1949              :         } else if (uni::detail::propnamecomp(str, "block"sv) == 0) {
    1950              :                 return property_type::block;
    1951              :         } else {
    1952              :                 return property_type::unknown;
    1953              :         }
    1954              : }
    1955              : 
    1956              : template <property_type Property> struct property_type_builder {
    1957              :         template <auto... Value> static constexpr auto get() {
    1958              :                 return ctll::reject{};
    1959              :         }
    1960              : };
    1961              : 
    1962              : template <auto... Name> struct property_builder {
    1963              :         static constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
    1964              :         static constexpr property_type type = property_type_from_name(get_string_view(name));
    1965              : 
    1966              :         using helper = property_type_builder<type>;
    1967              : 
    1968              :         template <auto... Value> static constexpr auto get() {
    1969              :                 return helper::template get<Value...>();
    1970              :         }
    1971              : };
    1972              : 
    1973              : // unicode TS#18 level 1.2.2 script support
    1974              : 
    1975              : template <> struct property_type_builder<property_type::script> {
    1976              :         template <auto... Value> static constexpr auto get() {
    1977              :                 constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
    1978              :                 constexpr auto sc = uni::detail::script_from_string(get_string_view(value));
    1979              :                 if constexpr (uni::detail::is_unknown(sc)) {
    1980              :                         return ctll::reject{};
    1981              :                 } else {
    1982              :                         return make_binary_property<sc>();
    1983              :                 }
    1984              :         }
    1985              : };
    1986              : 
    1987              : template <> struct property_type_builder<property_type::script_extension> {
    1988              :         template <auto... Value> static constexpr auto get() {
    1989              :                 constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
    1990              :                 constexpr auto sc = uni::detail::script_from_string(get_string_view(value));
    1991              :                 if constexpr (uni::detail::is_unknown(sc)) {
    1992              :                         return ctll::reject{};
    1993              :                 } else {
    1994              :                         return make_property<property_type::script_extension, sc>();
    1995              :                 }
    1996              :         }
    1997              : };
    1998              : 
    1999              : template <> struct property_type_builder<property_type::age> {
    2000              :         template <auto... Value> static constexpr auto get() {
    2001              :                 constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
    2002              :                 constexpr auto age = uni::detail::age_from_string(get_string_view(value));
    2003              :                 if constexpr (uni::detail::is_unassigned(age)) {
    2004              :                         return ctll::reject{};
    2005              :                 } else {
    2006              :                         return make_binary_property<age>();
    2007              :                 }
    2008              :         }
    2009              : };
    2010              : 
    2011              : template <> struct property_type_builder<property_type::block> {
    2012              :         template <auto... Value> static constexpr auto get() {
    2013              :                 constexpr char value[sizeof...(Value)]{static_cast<char>(Value)...};
    2014              :                 constexpr auto block = uni::detail::block_from_string(get_string_view(value));
    2015              :                 if constexpr (uni::detail::is_unknown(block)) {
    2016              :                         return ctll::reject{};
    2017              :                 } else {
    2018              :                         return make_binary_property<block>();
    2019              :                 }
    2020              :         }
    2021              : };
    2022              : 
    2023              : }
    2024              : 
    2025              : #endif
    2026              : 
    2027              : namespace ctre {
    2028              : 
    2029              : // helper functions
    2030              : template <size_t Index, typename... Content> auto convert_to_capture(ctll::list<Content...>) -> capture<Index, Content...>;
    2031              : template <size_t Index, typename Name, typename... Content> auto convert_to_named_capture(ctll::list<Content...>) -> capture_with_name<Index, Name, Content...>;
    2032              : 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...>;
    2033              : template <template <typename...> typename ListType, typename... Content> auto convert_to_basic_list(ctll::list<Content...>) -> ListType<Content...>;
    2034              : 
    2035              : template <auto V> struct rotate_value {
    2036              :         template <auto... Vs> friend constexpr auto operator+(string<Vs...>, rotate_value<V>) noexcept -> string<V, Vs...> { return {}; }
    2037              : };
    2038              : 
    2039              : struct rotate_for_lookbehind {
    2040              : 
    2041              : // from atoms_characters.hpp
    2042              : template <auto V> static auto rotate(character<V>) -> character<V>;
    2043              : template <typename... Content> static auto rotate(negative_set<Content...>) -> negative_set<Content...>;
    2044              : template <typename... Content> static auto rotate(set<Content...>) -> set<Content...>;
    2045              : template <auto... Cs> static auto rotate(enumeration<Cs...>) -> enumeration<Cs...>;
    2046              : template <typename... Content> static auto rotate(negate<Content...>) -> negate<Content...>;
    2047              : template <auto A, auto B> static auto rotate(char_range<A,B>) -> char_range<A,B>;
    2048              : 
    2049              : // from atoms_unicode.hpp
    2050              : template <auto... Str> static auto rotate(property_name<Str...>) -> property_name<Str...>;
    2051              : template <auto... Str> static auto rotate(property_value<Str...>) -> property_value<Str...>;
    2052              : template <typename T, T Type> static auto rotate(binary_property<T, Type>) -> binary_property<T, Type>;
    2053              : template <typename T, T Type, auto Value> static auto rotate(property<T, Type, Value>) -> property<T, Type, Value>;
    2054              : 
    2055              : // from atoms.hpp
    2056              : static auto rotate(accept) -> accept;
    2057              : static auto rotate(reject) -> reject;
    2058              : static auto rotate(start_mark) -> start_mark;
    2059              : static auto rotate(end_mark) -> end_mark;
    2060              : static auto rotate(end_cycle_mark) -> end_cycle_mark;
    2061              : static auto rotate(end_lookahead_mark) -> end_lookahead_mark;
    2062              : static auto rotate(end_lookbehind_mark) -> end_lookbehind_mark;
    2063              : template <size_t Id> static auto rotate(numeric_mark<Id>) -> numeric_mark<Id>;
    2064              : static auto rotate(any) -> any;
    2065              : 
    2066              : static auto rotate(empty) -> empty;
    2067              : 
    2068              : // select rotates only insides of selection, not select itself
    2069              : template <typename... Content> static auto rotate(select<Content...>) {
    2070              :   return select<decltype(rotate(Content{}))...>{};
    2071              : }
    2072              : 
    2073              : 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{}))...>{})));
    2074              : 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{}))...>{})));
    2075              : 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{}))...>{})));
    2076              : 
    2077              : template <size_t Index, typename... Content> static auto rotate(capture<Index, Content...>) {
    2078              :         return ctre::convert_to_capture<Index>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
    2079              : }
    2080              : 
    2081              : template <size_t Index, typename Name, typename... Content> static auto rotate(capture_with_name<Index, Name, Content...>) {
    2082              :         return ctre::convert_to_named_capture<Index, Name>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
    2083              : }
    2084              : 
    2085              : template <size_t Index> static auto rotate(back_reference<Index>) -> back_reference<Index>;
    2086              : template <typename Name> static auto rotate(back_reference_with_name<Name>) -> back_reference_with_name<Name>;
    2087              : 
    2088              : template <typename... Content> static auto rotate(look_start<Content...>) -> look_start<Content...>;
    2089              : 
    2090              : template <auto... Str> static auto rotate(string<Str...>) -> decltype((string<>{} + ... + rotate_value<Str>{}));
    2091              : 
    2092              : template <typename... Content> static auto rotate(sequence<Content...>) {
    2093              :         return ctre::convert_to_basic_list<sequence>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
    2094              : }
    2095              : 
    2096              : // we don't rotate lookaheads
    2097              : template <typename... Content> static auto rotate(lookahead_positive<Content...>) -> lookahead_positive<Content...>;
    2098              : template <typename... Content> static auto rotate(lookahead_negative<Content...>) -> lookahead_negative<Content...>;
    2099              : template <typename... Content> static auto rotate(lookbehind_positive<Content...>) -> lookbehind_positive<Content...>;
    2100              : template <typename... Content> static auto rotate(lookbehind_negative<Content...>) -> lookbehind_negative<Content...>;
    2101              : 
    2102              : static auto rotate(atomic_start) -> atomic_start;
    2103              : 
    2104              : template <typename... Content> static auto rotate(atomic_group<Content...>) {
    2105              :         return ctre::convert_to_basic_list<atomic_group>(ctll::rotate(ctll::list<decltype(rotate(Content{}))...>{}));
    2106              : }
    2107              : 
    2108              : template <typename... Content> static auto rotate(boundary<Content...>) -> boundary<Content...>;
    2109              : template <typename... Content> static auto rotate(not_boundary<Content...>) -> not_boundary<Content...>;
    2110              : 
    2111              : static auto rotate(assert_subject_begin) -> assert_subject_begin;
    2112              : static auto rotate(assert_subject_end) -> assert_subject_end;
    2113              : static auto rotate(assert_subject_end_line) -> assert_subject_end_line;
    2114              : static auto rotate(assert_line_begin) -> assert_line_begin;
    2115              : static auto rotate(assert_line_end) -> assert_line_end;
    2116              : 
    2117              : };
    2118              : 
    2119              : }
    2120              : 
    2121              : #endif
    2122              : 
    2123              : #ifndef CTRE__ID__HPP
    2124              : #define CTRE__ID__HPP
    2125              : 
    2126              : #ifndef CTRE_IN_A_MODULE
    2127              : #include <type_traits>
    2128              : #endif
    2129              : 
    2130              : namespace ctre {
    2131              :         
    2132              : template <auto... Name> struct id {
    2133              :         static constexpr auto name = ctll::fixed_string<sizeof...(Name)>{{Name...}};
    2134              :         
    2135              :         friend constexpr auto operator==(id<Name...>, id<Name...>) noexcept -> std::true_type { return {}; }
    2136              : 
    2137              :         template <auto... Other> friend constexpr auto operator==(id<Name...>, id<Other...>) noexcept -> std::false_type { return {}; }
    2138              :         
    2139              :         template <typename T> friend constexpr auto operator==(id<Name...>, T) noexcept -> std::false_type { return {}; }
    2140              : 
    2141              :         template <typename T> friend constexpr auto operator==(T, id<Name...>) noexcept -> std::false_type { return {}; }
    2142              : };
    2143              : 
    2144              : }
    2145              : 
    2146              : #endif
    2147              : 
    2148              : #ifndef CTRE_IN_A_MODULE
    2149              : #include <cstdint>
    2150              : #include <limits>
    2151              : #endif
    2152              : 
    2153              : namespace ctre {
    2154              :         
    2155              : template <size_t Counter> struct pcre_parameters {
    2156              :         static constexpr size_t current_counter = Counter;
    2157              : };
    2158              :         
    2159              : template <typename Stack = ctll::list<>, typename Parameters = pcre_parameters<0>, typename Mode = ctll::list<>> struct pcre_context {
    2160              :         using stack_type = Stack;
    2161              :         using parameters_type = Parameters;
    2162              :         using mode_list = Mode;
    2163              :         static constexpr inline auto stack = stack_type();
    2164              :         static constexpr inline auto parameters = parameters_type();
    2165              :         static constexpr inline auto mode = mode_list();
    2166              :         constexpr pcre_context() noexcept { }
    2167              :         constexpr pcre_context(Stack, Parameters) noexcept { }
    2168              :         constexpr pcre_context(Stack, Parameters, Mode) noexcept { }
    2169              : };
    2170              : 
    2171              : template <typename... Content, typename Parameters> pcre_context(ctll::list<Content...>, Parameters) -> pcre_context<ctll::list<Content...>, Parameters>;
    2172              :         
    2173              : template <size_t Value> struct number { };
    2174              : 
    2175              : template <size_t Id> struct capture_id { };
    2176              :         
    2177              : struct pcre_actions {
    2178              : // i know it's ugly, but it's more readable
    2179              : #ifndef CTRE__ACTIONS__ASSERTS__HPP
    2180              : #define CTRE__ACTIONS__ASSERTS__HPP
    2181              : 
    2182              : // push_assert_begin
    2183              : 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) {
    2184              :         return pcre_context{ctll::push_front(assert_line_begin(), subject.stack), subject.parameters};
    2185              : }
    2186              : 
    2187              : // push_assert_end
    2188              : 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) {
    2189              :         return pcre_context{ctll::push_front(assert_line_end(), subject.stack), subject.parameters};
    2190              : }
    2191              : 
    2192              : // push_assert_begin
    2193              : 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) {
    2194              :         return pcre_context{ctll::push_front(assert_subject_begin(), subject.stack), subject.parameters};
    2195              : }
    2196              : 
    2197              : // push_assert_subject_end
    2198              : 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) {
    2199              :         return pcre_context{ctll::push_front(assert_subject_end(), subject.stack), subject.parameters};
    2200              : }
    2201              : 
    2202              : // push_assert_subject_end_with_lineend
    2203              : 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) {
    2204              :         return pcre_context{ctll::push_front(assert_subject_end_line(), subject.stack), subject.parameters};
    2205              : }
    2206              : 
    2207              : #endif
    2208              : 
    2209              : #ifndef CTRE__ACTIONS__ATOMIC_GROUP__HPP
    2210              : #define CTRE__ACTIONS__ATOMIC_GROUP__HPP
    2211              : 
    2212              : // atomic start
    2213              : 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>>) {
    2214              :         return pcre_context{ctll::list<atomic_start, Ts...>(), pcre_parameters<Counter>()};
    2215              : }
    2216              : 
    2217              : // atomic
    2218              : 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>>) {
    2219              :         return pcre_context{ctll::list<atomic_group<Atomic>, Ts...>(), pcre_parameters<Counter>()};
    2220              : }
    2221              : 
    2222              : // atomic sequence
    2223              : 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>>) {
    2224              :         return pcre_context{ctll::list<atomic_group<Atomic...>, Ts...>(), pcre_parameters<Counter>()};
    2225              : }
    2226              : 
    2227              : #endif
    2228              : 
    2229              : #ifndef CTRE__ACTIONS__BACKREFERENCE__HPP
    2230              : #define CTRE__ACTIONS__BACKREFERENCE__HPP
    2231              : 
    2232              : // backreference with name
    2233              : 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>>) {       
    2234              :         return pcre_context{ctll::push_front(back_reference_with_name<id<Str...>>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2235              : }
    2236              : 
    2237              : // with just a number
    2238              : 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>>) {
    2239              :         // if we are looking outside of existing list of Ids ... reject input during parsing
    2240              :         if constexpr (Counter < Id) {
    2241              :                 return ctll::reject{};
    2242              :         } else {
    2243              :                 return pcre_context{ctll::push_front(back_reference<Id>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2244              :         }
    2245              : }
    2246              : 
    2247              : // relative backreference
    2248              : 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>>) {       
    2249              :         // if we are looking outside of existing list of Ids ... reject input during parsing
    2250              :         if constexpr (Counter < Id) {
    2251              :                 return ctll::reject{};
    2252              :         } else {
    2253              :                 constexpr size_t absolute_id = (Counter + 1) - Id;
    2254              :                 return pcre_context{ctll::push_front(back_reference<absolute_id>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2255              :         }
    2256              : }
    2257              : 
    2258              : #endif
    2259              : 
    2260              : #ifndef CTRE__ACTIONS__BOUNDARIES__HPP
    2261              : #define CTRE__ACTIONS__BOUNDARIES__HPP
    2262              : 
    2263              : // push_word_boundary
    2264              : 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) {
    2265              :         return pcre_context{ctll::push_front(boundary<word_chars>(), subject.stack), subject.parameters};
    2266              : }
    2267              : 
    2268              : // push_not_word_boundary
    2269              : 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) {
    2270              :         return pcre_context{ctll::push_front(boundary<negative_set<word_chars>>(), subject.stack), subject.parameters};
    2271              : }
    2272              : 
    2273              : #endif
    2274              : 
    2275              : #ifndef CTRE__ACTIONS__CAPTURE__HPP
    2276              : #define CTRE__ACTIONS__CAPTURE__HPP
    2277              : 
    2278              : // prepare_capture
    2279              : 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>>) {
    2280              :         return pcre_context{ctll::push_front(capture_id<Counter+1>(), ctll::list<Ts...>()), pcre_parameters<Counter+1>()};
    2281              : }
    2282              : 
    2283              : // reset_capture
    2284              : 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>>) {
    2285              :         return pcre_context{ctll::list<Ts...>(), pcre_parameters<Counter-1>()};
    2286              : }
    2287              : 
    2288              : // capture
    2289              : 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>>) {
    2290              :         return pcre_context{ctll::push_front(capture<Id, A>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2291              : }
    2292              : // capture (sequence)
    2293              : 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>>) {
    2294              :         return pcre_context{ctll::push_front(capture<Id, Content...>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2295              : }
    2296              : // push_name
    2297              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_name, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2298              :         return pcre_context{ctll::push_front(id<V>(), subject.stack), subject.parameters};
    2299              : }
    2300              : // push_name (concat)
    2301              : 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) {
    2302              :         return pcre_context{ctll::push_front(id<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
    2303              : }
    2304              : // capture with name
    2305              : 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>>) {
    2306              :         return pcre_context{ctll::push_front(capture_with_name<Id, id<Str...>, A>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2307              : }
    2308              : // capture with name (sequence)
    2309              : 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>>) {
    2310              :         return pcre_context{ctll::push_front(capture_with_name<Id, id<Str...>, Content...>(), ctll::list<Ts...>()), pcre_parameters<Counter>()};
    2311              : }
    2312              : 
    2313              : #endif
    2314              : 
    2315              : #ifndef CTRE__ACTIONS__CHARACTERS__HPP
    2316              : #define CTRE__ACTIONS__CHARACTERS__HPP
    2317              : 
    2318              : // push character
    2319              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_character, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2320              :         return pcre_context{ctll::push_front(character<V>(), subject.stack), subject.parameters};
    2321              : }
    2322              : // push_any_character
    2323              : 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) {
    2324              :         return pcre_context{ctll::push_front(any(), subject.stack), subject.parameters};
    2325              : }
    2326              : // character_alarm
    2327              : 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) {
    2328              :         return pcre_context{ctll::push_front(character<'\x07'>(), subject.stack), subject.parameters};
    2329              : }
    2330              : // character_escape
    2331              : 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) {
    2332              :         return pcre_context{ctll::push_front(character<'\x14'>(), subject.stack), subject.parameters};
    2333              : }
    2334              : // character_formfeed
    2335              : 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) {
    2336              :         return pcre_context{ctll::push_front(character<'\x0C'>(), subject.stack), subject.parameters};
    2337              : }
    2338              : // push_character_newline
    2339              : 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) {
    2340              :         return pcre_context{ctll::push_front(character<'\x0A'>(), subject.stack), subject.parameters};
    2341              : }
    2342              : // push_character_null
    2343              : 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) {
    2344              :         return pcre_context{ctll::push_front(character<'\0'>(), subject.stack), subject.parameters};
    2345              : }
    2346              : // push_character_return_carriage
    2347              : 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) {
    2348              :         return pcre_context{ctll::push_front(character<'\x0D'>(), subject.stack), subject.parameters};
    2349              : }
    2350              : // push_character_tab
    2351              : 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) {
    2352              :         return pcre_context{ctll::push_front(character<'\x09'>(), subject.stack), subject.parameters};
    2353              : }
    2354              : 
    2355              : #endif
    2356              : 
    2357              : #ifndef CTRE__ACTIONS__CLASS__HPP
    2358              : #define CTRE__ACTIONS__CLASS__HPP
    2359              : 
    2360              : // class_digit
    2361              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_digit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2362              :         return pcre_context{ctll::push_front(ctre::set<ctre::digit_chars>(), subject.stack), subject.parameters};
    2363              : }
    2364              : // class_non_digit
    2365              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nondigit, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2366              :         return pcre_context{ctll::push_front(ctre::negative_set<ctre::digit_chars>(), subject.stack), subject.parameters};
    2367              : }
    2368              : // class_space
    2369              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_space, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2370              :         return pcre_context{ctll::push_front(ctre::set<ctre::space_chars>(), subject.stack), subject.parameters};
    2371              : }
    2372              : // class_nonspace
    2373              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonspace, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2374              :         return pcre_context{ctll::push_front(ctre::negative_set<ctre::space_chars>(), subject.stack), subject.parameters};
    2375              : }
    2376              : 
    2377              : // class_horizontal_space
    2378              : 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) {
    2379              :         return pcre_context{ctll::push_front(ctre::set<ctre::horizontal_space_chars>(), subject.stack), subject.parameters};
    2380              : }
    2381              : // class_horizontal_nonspace
    2382              : 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) {
    2383              :         return pcre_context{ctll::push_front(ctre::negative_set<ctre::horizontal_space_chars>(), subject.stack), subject.parameters};
    2384              : }
    2385              : // class_vertical_space
    2386              : 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) {
    2387              :         return pcre_context{ctll::push_front(ctre::set<ctre::vertical_space_chars>(), subject.stack), subject.parameters};
    2388              : }
    2389              : // class_vertical_nonspace
    2390              : 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) {
    2391              :         return pcre_context{ctll::push_front(ctre::negative_set<ctre::vertical_space_chars>(), subject.stack), subject.parameters};
    2392              : }
    2393              : 
    2394              : // class_word
    2395              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_word, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2396              :         return pcre_context{ctll::push_front(ctre::set<ctre::word_chars>(), subject.stack), subject.parameters};
    2397              : }
    2398              : // class_nonword
    2399              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonword, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2400              :         return pcre_context{ctll::push_front(ctre::negative_set<ctre::word_chars>(), subject.stack), subject.parameters};
    2401              : }
    2402              : // class_nonnewline
    2403              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::class_nonnewline, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2404              :         return pcre_context{ctll::push_front(ctre::negative_set<character<'\n'>>(), subject.stack), subject.parameters};
    2405              : }
    2406              : 
    2407              : #endif
    2408              : 
    2409              : #ifndef CTRE__ACTIONS__FUSION__HPP
    2410              : #define CTRE__ACTIONS__FUSION__HPP
    2411              : 
    2412              : static constexpr size_t combine_max_repeat_length(size_t A, size_t B) {
    2413              :         if (A && B) return A+B;
    2414              :         else return 0;
    2415              : }
    2416              : 
    2417              : 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...>) {
    2418              :         return repeat<MinA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
    2419              : }
    2420              : 
    2421              : 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...>) {
    2422              :         return lazy_repeat<MinA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
    2423              : }
    2424              : 
    2425              : 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...>) {
    2426              :         [[maybe_unused]] constexpr bool first_is_unbounded = (MaxA == 0);
    2427              :         [[maybe_unused]] constexpr bool second_is_nonempty = (MinB > 0);
    2428              :         [[maybe_unused]] constexpr bool second_can_be_empty = (MinB == 0);
    2429              : 
    2430              :         if constexpr (first_is_unbounded && second_is_nonempty) {
    2431              :                 // will always reject, but I keep the content, so I have some amount of captures
    2432              :                 return sequence<reject, Content...>();
    2433              :         } else if constexpr (first_is_unbounded) {
    2434              :                 return possessive_repeat<MinA, MaxA, Content...>();
    2435              :         } else if constexpr (second_can_be_empty) {
    2436              :                 return possessive_repeat<MinA, combine_max_repeat_length(MaxA, MaxB), Content...>();
    2437              :         } else {
    2438              :                 return possessive_repeat<MaxA + MinB, combine_max_repeat_length(MaxA, MaxB), Content...>();
    2439              :         }
    2440              : }
    2441              : 
    2442              : // concat repeat sequences
    2443              : 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) {
    2444              :         return pcre_context{ctll::push_front(combine_repeat(repeat<MinA, MaxA, Content...>(), repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
    2445              : }
    2446              : 
    2447              : // concat lazy repeat sequences
    2448              : 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) {
    2449              :         return pcre_context{ctll::push_front(combine_repeat(lazy_repeat<MinA, MaxA, Content...>(), lazy_repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
    2450              : }
    2451              : 
    2452              : // concat possessive repeat seqeunces
    2453              : 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) {
    2454              :         return pcre_context{ctll::push_front(combine_repeat(possessive_repeat<MinA, MaxA, Content...>(), possessive_repeat<MinB, MaxB, Content...>()), ctll::list<Ts...>()), subject.parameters};
    2455              : }
    2456              : 
    2457              : // concat repeat sequences into sequence
    2458              : 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) {
    2459              :         using result = decltype(combine_repeat(repeat<MinB, MaxB, Content...>(), repeat<MinA, MaxA, Content...>()));
    2460              :         
    2461              :         return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
    2462              : }
    2463              : 
    2464              : // concat lazy repeat sequences into sequence
    2465              : 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) {
    2466              :         using result = decltype(combine_repeat(lazy_repeat<MinB, MaxB, Content...>(), lazy_repeat<MinA, MaxA, Content...>()));
    2467              :         
    2468              :         return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
    2469              : }
    2470              : 
    2471              : // concat possessive repeat sequences into sequence
    2472              : 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) {
    2473              :         using result = decltype(combine_repeat(possessive_repeat<MinB, MaxB, Content...>(), possessive_repeat<MinA, MaxA, Content...>()));
    2474              :         
    2475              :         return pcre_context{ctll::push_front(sequence<result,As...>(), ctll::list<Ts...>()), subject.parameters};
    2476              : }
    2477              : 
    2478              : #endif
    2479              : 
    2480              : #ifndef CTRE__ACTIONS__HEXDEC__HPP
    2481              : #define CTRE__ACTIONS__HEXDEC__HPP
    2482              : 
    2483              : // hexdec character support (seed)
    2484              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::create_hexdec, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2485              :         return pcre_context{ctll::push_front(number<0ull>(), subject.stack), subject.parameters};
    2486              : }
    2487              : // hexdec character support (push value)
    2488              : 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) {
    2489              :         constexpr auto previous = N << 4ull;      
    2490              :         if constexpr (V >= 'a' && V <= 'f') {
    2491              :                 return pcre_context{ctll::push_front(number<(previous + (V - 'a' + 10))>(), ctll::list<Ts...>()), subject.parameters};
    2492              :         } else if constexpr (V >= 'A' && V <= 'F') {
    2493              :                 return pcre_context{ctll::push_front(number<(previous + (V - 'A' + 10))>(), ctll::list<Ts...>()), subject.parameters};
    2494              :         } else {
    2495              :                 return pcre_context{ctll::push_front(number<(previous + (V - '0'))>(), ctll::list<Ts...>()), subject.parameters};
    2496              :         }
    2497              : }
    2498              : // hexdec character support (convert to character)
    2499              : 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) {
    2500              :         constexpr size_t max_char = (std::numeric_limits<char>::max)();
    2501              :         if constexpr (N <= max_char) {
    2502              :                 return pcre_context{ctll::push_front(character<char{N}>(), ctll::list<Ts...>()), subject.parameters};
    2503              :         } else {
    2504              :                 return pcre_context{ctll::push_front(character<char32_t{N}>(), ctll::list<Ts...>()), subject.parameters};
    2505              :         } 
    2506              : }       
    2507              : 
    2508              : #endif
    2509              : 
    2510              : #ifndef CTRE__ACTIONS__LOOKAHEAD__HPP
    2511              : #define CTRE__ACTIONS__LOOKAHEAD__HPP
    2512              : 
    2513              : // lookahead positive start
    2514              : 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>>) {
    2515              :         return pcre_context{ctll::list<look_start<lookahead_positive<>>, Ts...>(), pcre_parameters<Counter>()};
    2516              : }
    2517              : 
    2518              : // lookahead positive end
    2519              : 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>>) {
    2520              :         return pcre_context{ctll::list<lookahead_positive<Look>, Ts...>(), pcre_parameters<Counter>()};
    2521              : }
    2522              : 
    2523              : // lookahead positive end (sequence)
    2524              : 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>>) {
    2525              :         return pcre_context{ctll::list<lookahead_positive<Look...>, Ts...>(), pcre_parameters<Counter>()};
    2526              : }
    2527              : 
    2528              : // lookahead negative start
    2529              : 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>>) {
    2530              :         return pcre_context{ctll::list<look_start<lookahead_negative<>>, Ts...>(), pcre_parameters<Counter>()};
    2531              : }
    2532              : 
    2533              : // lookahead negative end
    2534              : 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>>) {
    2535              :         return pcre_context{ctll::list<lookahead_negative<Look>, Ts...>(), pcre_parameters<Counter>()};
    2536              : }
    2537              : 
    2538              : // lookahead negative end (sequence)
    2539              : 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>>) {
    2540              :         return pcre_context{ctll::list<lookahead_negative<Look...>, Ts...>(), pcre_parameters<Counter>()};
    2541              : }
    2542              : 
    2543              : // LOOKBEHIND
    2544              : 
    2545              : // lookbehind positive start
    2546              : 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>>) {
    2547              :         return pcre_context{ctll::list<look_start<lookbehind_positive<>>, Ts...>(), pcre_parameters<Counter>()};
    2548              : }
    2549              : 
    2550              : // lookbehind positive end
    2551              : 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>>) {
    2552              :         return pcre_context{ctll::list<lookbehind_positive<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))>, Ts...>(), pcre_parameters<Counter>()};
    2553              : }
    2554              : 
    2555              : // lookbehind positive end (sequence)
    2556              : 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>>) {
    2557              :         using my_lookbehind = decltype(ctre::convert_to_basic_list<lookbehind_positive>(ctll::rotate(ctll::list<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))...>{})));
    2558              :         return pcre_context{ctll::list<my_lookbehind, Ts...>(), pcre_parameters<Counter>()};
    2559              : }
    2560              : 
    2561              : // lookbehind negative start
    2562              : 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>>) {
    2563              :         return pcre_context{ctll::list<look_start<lookbehind_negative<>>, Ts...>(), pcre_parameters<Counter>()};
    2564              : }
    2565              : 
    2566              : // lookbehind negative end
    2567              : 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>>) {
    2568              :         return pcre_context{ctll::list<lookbehind_negative<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))>, Ts...>(), pcre_parameters<Counter>()};
    2569              : }
    2570              : 
    2571              : // lookbehind negative end (sequence)
    2572              : 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>>) {
    2573              :         using my_lookbehind = decltype(ctre::convert_to_basic_list<lookbehind_negative>(ctll::rotate(ctll::list<decltype(ctre::rotate_for_lookbehind::rotate(Look{}))...>{})));
    2574              :         return pcre_context{ctll::list<my_lookbehind, Ts...>(), pcre_parameters<Counter>()};
    2575              : }
    2576              : 
    2577              : #endif
    2578              : 
    2579              : #ifndef CTRE__ACTIONS__NAMED_CLASS__HPP
    2580              : #define CTRE__ACTIONS__NAMED_CLASS__HPP
    2581              : 
    2582              : // class_named_alnum
    2583              : 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) {
    2584              :         return pcre_context{ctll::push_front(ctre::alphanum_chars(), subject.stack), subject.parameters};
    2585              : }
    2586              : // class_named_alpha
    2587              : 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) {
    2588              :         return pcre_context{ctll::push_front(ctre::alpha_chars(), subject.stack), subject.parameters};
    2589              : }
    2590              : // class_named_digit
    2591              : 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) {
    2592              :         return pcre_context{ctll::push_front(ctre::digit_chars(), subject.stack), subject.parameters};
    2593              : }
    2594              : // class_named_ascii
    2595              : 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) {
    2596              :         return pcre_context{ctll::push_front(ctre::ascii_chars(), subject.stack), subject.parameters};
    2597              : }
    2598              : // class_named_blank
    2599              : 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) {
    2600              :         return pcre_context{ctll::push_front(ctre::enumeration<' ','\t'>(), subject.stack), subject.parameters};
    2601              : }
    2602              : // class_named_cntrl
    2603              : 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) {
    2604              :         return pcre_context{ctll::push_front(ctre::set<ctre::char_range<'\x00','\x1F'>, ctre::character<'\x7F'>>(), subject.stack), subject.parameters};
    2605              : }
    2606              : // class_named_graph
    2607              : 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) {
    2608              :         return pcre_context{ctll::push_front(ctre::char_range<'\x21','\x7E'>(), subject.stack), subject.parameters};
    2609              : }
    2610              : // class_named_lower
    2611              : 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) {
    2612              :         return pcre_context{ctll::push_front(ctre::char_range<'a','z'>(), subject.stack), subject.parameters};
    2613              : }
    2614              : // class_named_upper
    2615              : 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) {
    2616              :         return pcre_context{ctll::push_front(ctre::char_range<'A','Z'>(), subject.stack), subject.parameters};
    2617              : }
    2618              : // class_named_print
    2619              : 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) {
    2620              :         return pcre_context{ctll::push_front(ctre::char_range<'\x20','\x7E'>(), subject.stack), subject.parameters};
    2621              : }
    2622              : // class_named_space
    2623              : 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) {
    2624              :         return pcre_context{ctll::push_front(space_chars(), subject.stack), subject.parameters};
    2625              : }
    2626              : // class_named_word
    2627              : 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) {
    2628              :         return pcre_context{ctll::push_front(word_chars(), subject.stack), subject.parameters};
    2629              : }
    2630              : // class_named_punct
    2631              : 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) {
    2632              :         return pcre_context{ctll::push_front(punct_chars(), subject.stack), subject.parameters};
    2633              : }
    2634              : // class_named_xdigit
    2635              : 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) {
    2636              :         return pcre_context{ctll::push_front(xdigit_chars(), subject.stack), subject.parameters};
    2637              : }
    2638              : 
    2639              : #endif
    2640              : 
    2641              : #ifndef CTRE__ACTIONS__OPTIONS__HPP
    2642              : #define CTRE__ACTIONS__OPTIONS__HPP
    2643              : 
    2644              : // empty option for alternate
    2645              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::push_empty, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2646              :         return pcre_context{ctll::push_front(empty(), subject.stack), subject.parameters};
    2647              : }
    2648              : 
    2649              : // empty option for empty regex
    2650              : template <typename Parameters> static constexpr auto apply(pcre::push_empty, ctll::epsilon, pcre_context<ctll::list<>, Parameters> subject) {
    2651              :         return pcre_context{ctll::push_front(empty(), subject.stack), subject.parameters};
    2652              : }
    2653              : 
    2654              : // make_alternate (A|B)
    2655              : 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) {
    2656              :         return pcre_context{ctll::push_front(select<A,B>(), ctll::list<Ts...>()), subject.parameters};
    2657              : }
    2658              : // make_alternate (As..)|B => (As..|B)
    2659              : 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) {
    2660              :         return pcre_context{ctll::push_front(select<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
    2661              : }
    2662              : 
    2663              : // make_optional
    2664              : 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) {
    2665              :         return pcre_context{ctll::push_front(optional<A>(), ctll::list<Ts...>()), subject.parameters};
    2666              : }
    2667              : 
    2668              : 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) {
    2669              :         return pcre_context{ctll::push_front(optional<Content...>(), ctll::list<Ts...>()), subject.parameters};
    2670              : }
    2671              : 
    2672              : // prevent from creating wrapped optionals
    2673              : 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) {
    2674              :         return pcre_context{ctll::push_front(optional<A>(), ctll::list<Ts...>()), subject.parameters};
    2675              : }
    2676              : 
    2677              : // in case inner optional is lazy, result should be lazy too
    2678              : 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) {
    2679              :         return pcre_context{ctll::push_front(lazy_optional<A>(), ctll::list<Ts...>()), subject.parameters};
    2680              : }
    2681              : 
    2682              : // make_lazy (optional)
    2683              : 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) {
    2684              :         return pcre_context{ctll::push_front(lazy_optional<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2685              : }
    2686              : 
    2687              : // if you already got a lazy optional, make_lazy is no-op
    2688              : 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) {
    2689              :         return pcre_context{ctll::push_front(lazy_optional<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2690              : }
    2691              : 
    2692              : #endif
    2693              : 
    2694              : #ifndef CTRE__ACTIONS__PROPERTIES__HPP
    2695              : #define CTRE__ACTIONS__PROPERTIES__HPP
    2696              : 
    2697              : // push_property_name
    2698              : 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) {
    2699              :         return pcre_context{ctll::push_front(property_name<V>(), subject.stack), subject.parameters};
    2700              : }
    2701              : // push_property_name (concat)
    2702              : 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) {
    2703              :         return pcre_context{ctll::push_front(property_name<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
    2704              : }
    2705              : 
    2706              : // push_property_value
    2707              : 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) {
    2708              :         return pcre_context{ctll::push_front(property_value<V>(), subject.stack), subject.parameters};
    2709              : }
    2710              : // push_property_value (concat)
    2711              : 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) {
    2712              :         return pcre_context{ctll::push_front(property_value<Str..., V>(), ctll::list<Ts...>()), subject.parameters};
    2713              : }
    2714              : 
    2715              : // make_property
    2716              : 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) {
    2717              :         //return ctll::reject{};
    2718              :         constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
    2719              :         constexpr auto p = uni::detail::binary_prop_from_string(get_string_view(name));
    2720              : 
    2721              :         if constexpr (uni::detail::is_unknown(p)) {
    2722              :                 return ctll::reject{};
    2723              :         } else {
    2724              :                 return pcre_context{ctll::push_front(make_binary_property<p>(), ctll::list<Ts...>()), subject.parameters};
    2725              :         }
    2726              : }
    2727              : 
    2728              : // make_property
    2729              : 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) {
    2730              :         //return ctll::reject{};
    2731              :         constexpr auto prop = property_builder<Name...>::template get<Value...>();
    2732              : 
    2733              :         if constexpr (std::is_same_v<decltype(prop), ctll::reject>) {
    2734              :                 return ctll::reject{};
    2735              :         } else {
    2736              :                 return pcre_context{ctll::push_front(prop, ctll::list<Ts...>()), subject.parameters};
    2737              :         }
    2738              : }
    2739              : 
    2740              : // make_property_negative
    2741              : 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) {
    2742              :         //return ctll::reject{};
    2743              :         constexpr char name[sizeof...(Name)]{static_cast<char>(Name)...};
    2744              :         constexpr auto p = uni::detail::binary_prop_from_string(get_string_view(name));
    2745              : 
    2746              :         if constexpr (uni::detail::is_unknown(p)) {
    2747              :                 return ctll::reject{};
    2748              :         } else {
    2749              :                 return pcre_context{ctll::push_front(negate<make_binary_property<p>>(), ctll::list<Ts...>()), subject.parameters};
    2750              :         }
    2751              : }
    2752              : 
    2753              : // make_property_negative
    2754              : 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) {
    2755              :         //return ctll::reject{};
    2756              :         constexpr auto prop = property_builder<Name...>::template get<Value...>();
    2757              : 
    2758              :         if constexpr (std::is_same_v<decltype(prop), ctll::reject>) {
    2759              :                 return ctll::reject{};
    2760              :         } else {
    2761              :                 return pcre_context{ctll::push_front(negate<decltype(prop)>(), ctll::list<Ts...>()), subject.parameters};
    2762              :         }
    2763              : }
    2764              : 
    2765              : #endif
    2766              : 
    2767              : #ifndef CTRE__ACTIONS__REPEAT__HPP
    2768              : #define CTRE__ACTIONS__REPEAT__HPP
    2769              : 
    2770              : // repeat 1..N
    2771              : 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) {
    2772              :         return pcre_context{ctll::push_front(plus<A>(), ctll::list<Ts...>()), subject.parameters};
    2773              : }
    2774              : // repeat 1..N (sequence)
    2775              : 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) {
    2776              :         return pcre_context{ctll::push_front(plus<Content...>(), ctll::list<Ts...>()), subject.parameters};
    2777              : }
    2778              : 
    2779              : // repeat 0..N
    2780              : 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) {
    2781              :         return pcre_context{ctll::push_front(star<A>(), ctll::list<Ts...>()), subject.parameters};
    2782              : }
    2783              : // repeat 0..N (sequence)
    2784              : 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) {
    2785              :         return pcre_context{ctll::push_front(star<Content...>(), ctll::list<Ts...>()), subject.parameters};
    2786              : }
    2787              : 
    2788              : // create_number (seed)
    2789              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::create_number, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2790              :         return pcre_context{ctll::push_front(number<static_cast<size_t>(V - '0')>(), subject.stack), subject.parameters};
    2791              : }
    2792              : // push_number
    2793              : 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) {
    2794              :         constexpr size_t previous = N * 10ull;  
    2795              :         return pcre_context{ctll::push_front(number<(previous + (V - '0'))>(), ctll::list<Ts...>()), subject.parameters};
    2796              : }
    2797              : 
    2798              : // repeat A..B
    2799              : 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) {
    2800              :         return pcre_context{ctll::push_front(repeat<A,B,Subject>(), ctll::list<Ts...>()), subject.parameters};
    2801              : }
    2802              : // repeat A..B (sequence)
    2803              : 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) {
    2804              :         return pcre_context{ctll::push_front(repeat<A,B,Content...>(), ctll::list<Ts...>()), subject.parameters};
    2805              : }
    2806              : 
    2807              : // repeat_exactly 
    2808              : 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) {
    2809              :         return pcre_context{ctll::push_front(repeat<A,A,Subject>(), ctll::list<Ts...>()), subject.parameters};
    2810              : }
    2811              : // repeat_exactly A..B (sequence)
    2812              : 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) {
    2813              :         return pcre_context{ctll::push_front(repeat<A,A,Content...>(), ctll::list<Ts...>()), subject.parameters};
    2814              : }
    2815              : 
    2816              : // repeat_at_least (A+) 
    2817              : 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) {
    2818              :         return pcre_context{ctll::push_front(repeat<A,0,Subject>(), ctll::list<Ts...>()), subject.parameters};
    2819              : }
    2820              : // repeat_at_least (A+) (sequence)
    2821              : 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) {
    2822              :         return pcre_context{ctll::push_front(repeat<A,0,Content...>(), ctll::list<Ts...>()), subject.parameters};
    2823              : }
    2824              : 
    2825              : // make_lazy (plus)
    2826              : 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) {
    2827              :         return pcre_context{ctll::push_front(lazy_plus<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2828              : }
    2829              : 
    2830              : // make_lazy (star)
    2831              : 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) {
    2832              :         return pcre_context{ctll::push_front(lazy_star<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2833              : }
    2834              : 
    2835              : // make_lazy (repeat<A,B>)
    2836              : 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) {
    2837              :         return pcre_context{ctll::push_front(lazy_repeat<A,B,Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2838              : }
    2839              : 
    2840              : // make_possessive (plus)
    2841              : 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) {
    2842              :         return pcre_context{ctll::push_front(possessive_plus<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2843              : }
    2844              : 
    2845              : // make_possessive (star)
    2846              : 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) {
    2847              :         return pcre_context{ctll::push_front(possessive_star<Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2848              : }
    2849              : 
    2850              : // make_possessive (repeat<A,B>)
    2851              : 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) {
    2852              :         return pcre_context{ctll::push_front(possessive_repeat<A,B,Subject...>(), ctll::list<Ts...>()), subject.parameters};
    2853              : }
    2854              : 
    2855              : #endif
    2856              : 
    2857              : #ifndef CTRE__ACTIONS__SEQUENCE__HPP
    2858              : #define CTRE__ACTIONS__SEQUENCE__HPP
    2859              : 
    2860              : // make_sequence
    2861              : 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) {
    2862              :         return pcre_context{ctll::push_front(sequence<A,B>(), ctll::list<Ts...>()), subject.parameters};
    2863              : }
    2864              : // make_sequence (concat)
    2865              : 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) {
    2866              :         return pcre_context{ctll::push_front(sequence<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
    2867              : }
    2868              : 
    2869              : // make_sequence (make string)
    2870              : 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) {
    2871              :         return pcre_context{ctll::push_front(string<A,B>(), ctll::list<Ts...>()), subject.parameters};
    2872              : }
    2873              : // make_sequence (concat string)
    2874              : 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) {
    2875              :         return pcre_context{ctll::push_front(string<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
    2876              : }
    2877              : 
    2878              : // make_sequence (make string in front of different items)
    2879              : 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) {
    2880              :         return pcre_context{ctll::push_front(sequence<string<A,B>,Sq...>(), ctll::list<Ts...>()), subject.parameters};
    2881              : }
    2882              : // make_sequence (concat string in front of different items)
    2883              : 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) {
    2884              :         return pcre_context{ctll::push_front(sequence<string<A,Bs...>,Sq...>(), ctll::list<Ts...>()), subject.parameters};
    2885              : }
    2886              : 
    2887              : #endif
    2888              : 
    2889              : #ifndef CTRE__ACTIONS__SET__HPP
    2890              : #define CTRE__ACTIONS__SET__HPP
    2891              : 
    2892              : // UTILITY
    2893              : // add into set if not exists
    2894              : 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 {}; }
    2895              : 
    2896              : //template <template <typename...> typename SetType, typename A, typename BHead, typename... Bs> struct set_merge_helper {
    2897              : //      using step = decltype(push_back_into_set<SetType>(BHead(), A()));
    2898              : //      using type = ctll::conditional<(sizeof...(Bs) > 0), set_merge_helper<SetType, step, Bs...>, step>;
    2899              : //};
    2900              : //
    2901              : //// add set into set if not exists
    2902              : //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}}
    2903              : //
    2904              : //template <template <typename...> typename SetType, typename... As> static constexpr auto push_back_into_set(SetType<As...>, SetType<>) -> SetType<As...> { return pcre_context{{};), subject.parameters}}
    2905              : 
    2906              : // END OF UTILITY
    2907              : 
    2908              : // set_start
    2909              : 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) {
    2910              :         return pcre_context{ctll::push_front(set<A>(), ctll::list<Ts...>()), subject.parameters};
    2911              : }
    2912              : 
    2913              : // set_empty
    2914              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::set_empty, ctll::term<V>, pcre_context<ctll::list<Ts...>, Parameters> subject) {
    2915              :         return pcre_context{ctll::push_front(set<>(), ctll::list<Ts...>()), subject.parameters};
    2916              : }
    2917              : 
    2918              : // set_make
    2919              : 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) {
    2920              :         return pcre_context{ctll::push_front(set<Content...>(), ctll::list<Ts...>()), subject.parameters};
    2921              : }
    2922              : // set_make_negative
    2923              : 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) {
    2924              :         return pcre_context{ctll::push_front(negative_set<Content...>(), ctll::list<Ts...>()), subject.parameters};
    2925              : }
    2926              : // set{A...} + B = set{A,B}
    2927              : 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) {
    2928              :         auto new_set = push_back_into_set<set>(A(), set<Content...>());
    2929              :         return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
    2930              : }
    2931              : // TODO checkme
    2932              : //// set{A...} + set{B...} = set{A...,B...}
    2933              : //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) {
    2934              : //      auto new_set = push_back_into_set<set>(set<As...>(), set<Bs...>());
    2935              : //      return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
    2936              : //}
    2937              : 
    2938              : // negative_set{A...} + B = negative_set{A,B}
    2939              : 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) {
    2940              :         auto new_set = push_back_into_set<set>(A(), set<Content...>());
    2941              :         return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
    2942              : }
    2943              : // TODO checkme
    2944              : //// negative_set{A...} + negative_set{B...} = negative_set{A...,B...}
    2945              : //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) {
    2946              : //      auto new_set = push_back_into_set<negative_set>(negative_set<As...>(), negative_set<Bs...>());
    2947              : //      return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
    2948              : //}
    2949              : // negate_class_named: [[^:digit:]] = [^[:digit:]]
    2950              : 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) {
    2951              :         return pcre_context{ctll::push_front(negate<A>(), ctll::list<Ts...>()), subject.parameters};
    2952              : }
    2953              : 
    2954              : // add range to set
    2955              : 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) {
    2956              :         return pcre_context{ctll::push_front(char_range<A,B>(), ctll::list<Ts...>()), subject.parameters};
    2957              : }
    2958              : 
    2959              : #endif
    2960              : 
    2961              : #ifndef CTRE__ACTIONS__MODE__HPP
    2962              : #define CTRE__ACTIONS__MODE__HPP
    2963              : 
    2964              : // we need to reset counter and wrap Mode into mode_switch
    2965              : template <typename Mode, typename... Ts, typename Parameters> static constexpr auto apply_mode(Mode, ctll::list<Ts...>, Parameters) {
    2966              :         return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, Parameters>{};
    2967              : }
    2968              : 
    2969              : 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>) {
    2970              :         return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, pcre_parameters<Counter-1>>{};
    2971              : }
    2972              : 
    2973              : // catch a semantic action into mode
    2974              : 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>) {
    2975              :         return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
    2976              : }
    2977              : 
    2978              : 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>) {
    2979              :         return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
    2980              : }
    2981              : 
    2982              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_singleline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
    2983              :         return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
    2984              : }
    2985              : 
    2986              : template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_multiline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
    2987              :         return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
    2988              : }
    2989              : 
    2990              : // to properly reset capture
    2991              : 
    2992              : #endif
    2993              : 
    2994              : };
    2995              : 
    2996              : }
    2997              : 
    2998              : #endif
    2999              : 
    3000              : #ifndef CTRE__EVALUATION__HPP
    3001              : #define CTRE__EVALUATION__HPP
    3002              : 
    3003              : #ifndef CTRE__STARTS_WITH_ANCHOR__HPP
    3004              : #define CTRE__STARTS_WITH_ANCHOR__HPP
    3005              : 
    3006              : namespace ctre {
    3007              : 
    3008              : template <typename... Content> 
    3009              : constexpr bool starts_with_anchor(const flags &, ctll::list<Content...>) noexcept {
    3010              :         return false;
    3011              : }
    3012              : 
    3013              : template <typename... Content> 
    3014              : constexpr bool starts_with_anchor(const flags &, ctll::list<assert_subject_begin, Content...>) noexcept {
    3015              :         // yes! start subject anchor is here
    3016              :         return true;
    3017              : }
    3018              : 
    3019              : template <typename... Content> 
    3020              : constexpr bool starts_with_anchor(const flags & f, ctll::list<assert_line_begin, Content...>) noexcept {
    3021              :         // yes! start line anchor is here
    3022              :         return !ctre::multiline_mode(f) || starts_with_anchor(f, ctll::list<Content...>{});
    3023              : }
    3024              : 
    3025              : template <typename CharLike, typename... Content> 
    3026              : constexpr bool starts_with_anchor(const flags & f, ctll::list<boundary<CharLike>, Content...>) noexcept {
    3027              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3028              :         return starts_with_anchor(f, ctll::list<Content...>{});
    3029              : }
    3030              : 
    3031              : template <typename... Options, typename... Content> 
    3032              : constexpr bool starts_with_anchor(const flags & f, ctll::list<select<Options...>, Content...>) noexcept {
    3033              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3034              :         return (starts_with_anchor(f, ctll::list<Options, Content...>{}) && ... && true);
    3035              : }
    3036              : 
    3037              : template <typename... Optional, typename... Content> 
    3038              : constexpr bool starts_with_anchor(const flags & f, ctll::list<optional<Optional...>, Content...>) noexcept {
    3039              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3040              :         return starts_with_anchor(f, ctll::list<Optional..., Content...>{}) && starts_with_anchor(f, ctll::list<Content...>{});
    3041              : }
    3042              : 
    3043              : template <typename... Optional, typename... Content> 
    3044              : constexpr bool starts_with_anchor(const flags & f, ctll::list<lazy_optional<Optional...>, Content...>) noexcept {
    3045              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3046              :         return starts_with_anchor(f, ctll::list<Optional..., Content...>{}) && starts_with_anchor(f, ctll::list<Content...>{});
    3047              : }
    3048              : 
    3049              : template <typename... Seq, typename... Content> 
    3050              : constexpr bool starts_with_anchor(const flags & f, ctll::list<sequence<Seq...>, Content...>) noexcept {
    3051              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3052              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3053              : }
    3054              : 
    3055              : template <size_t A, size_t B, typename... Seq, typename... Content> 
    3056              : constexpr bool starts_with_anchor(const flags & f, ctll::list<repeat<A, B, Seq...>, Content...>) noexcept {
    3057              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3058              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3059              : }
    3060              : 
    3061              : template <size_t A, size_t B, typename... Seq, typename... Content> 
    3062              : constexpr bool starts_with_anchor(const flags & f, ctll::list<lazy_repeat<A, B, Seq...>, Content...>) noexcept {
    3063              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3064              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3065              : }
    3066              : 
    3067              : template <size_t A, size_t B, typename... Seq, typename... Content> 
    3068              : constexpr bool starts_with_anchor(const flags & f, ctll::list<possessive_repeat<A, B, Seq...>, Content...>) noexcept {
    3069              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3070              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3071              : }
    3072              : 
    3073              : template <size_t Index, typename... Seq, typename... Content> 
    3074              : constexpr bool starts_with_anchor(const flags & f, ctll::list<capture<Index, Seq...>, Content...>) noexcept {
    3075              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3076              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3077              : }
    3078              : 
    3079              : template <size_t Index, typename... Seq, typename... Content> 
    3080              : constexpr bool starts_with_anchor(const flags & f, ctll::list<capture_with_name<Index, Seq...>, Content...>) noexcept {
    3081              :         // check if all options starts with anchor or if they are empty, there is an anchor behind them
    3082              :         return starts_with_anchor(f, ctll::list<Seq..., Content...>{});
    3083              : }
    3084              : 
    3085              : }
    3086              : 
    3087              : #endif
    3088              : 
    3089              : #ifndef CTRE__RETURN_TYPE__HPP
    3090              : #define CTRE__RETURN_TYPE__HPP
    3091              : 
    3092              : #ifndef CTRE__UTF8__HPP
    3093              : #define CTRE__UTF8__HPP
    3094              : 
    3095              : #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
    3096              : 
    3097              : #ifndef CTRE_IN_A_MODULE
    3098              : #include <string_view>
    3099              : #include <iterator>
    3100              : #endif
    3101              : 
    3102              : #if defined(__cpp_char8_t) &&__cpp_lib_char8_t >= 201811L
    3103              : #define CTRE_ENABLE_UTF8_RANGE
    3104              : #endif
    3105              : 
    3106              : #if defined(__cpp_impl_three_way_comparison) && (__cpp_impl_three_way_comparison >= 201907L)
    3107              : #define CTRE_NO_NEED_FOR_ADDITIONAL_COMPARISONS
    3108              : #endif
    3109              : 
    3110              : namespace ctre {
    3111              : 
    3112              : struct utf8_iterator {
    3113              :         using self_type = utf8_iterator;
    3114              :         using value_type = char8_t;
    3115              :         using reference = char8_t;
    3116              :         using pointer = const char8_t *;
    3117              :         using iterator_category = std::bidirectional_iterator_tag;
    3118              :         using difference_type = int;
    3119              :         
    3120              :         struct sentinel {
    3121              :                 // this is here only because I want to support std::make_reverse_iterator
    3122              :                 using self_type = sentinel;
    3123              :                 using value_type = char8_t;
    3124              :                 using reference = char8_t &;
    3125              :                 using pointer = const char8_t *;
    3126              :                 using iterator_category = std::bidirectional_iterator_tag;
    3127              :                 using difference_type = int;
    3128              :                 
    3129              :                 // it's just sentinel it won't be ever called
    3130              :                 auto operator++() noexcept -> self_type &;
    3131              :                 auto operator++(int) noexcept -> self_type;
    3132              :                 auto operator--() noexcept -> self_type &;
    3133              :                 auto operator--(int) noexcept -> self_type;
    3134              :                 friend auto operator==(self_type, self_type) noexcept -> bool;
    3135              :                 auto operator*() noexcept -> reference;
    3136              :                 
    3137              :                 friend constexpr auto operator==(self_type, const char8_t * other_ptr) noexcept {
    3138              :                         return *other_ptr == char8_t{0};
    3139              :                 }
    3140              : #ifndef CTRE_NO_NEED_FOR_ADDITIONAL_COMPARISONS         
    3141              :                 friend constexpr auto operator!=(self_type, const char8_t * other_ptr) noexcept {
    3142              :                         return *other_ptr != char8_t{0};
    3143              :                 }
    3144              :                 
    3145              :                 friend constexpr auto operator==(const char8_t * other_ptr, self_type) noexcept {
    3146              :                         return *other_ptr == char8_t{0};
    3147              :                 }
    3148              : 
    3149              :                 friend constexpr auto operator!=(const char8_t * other_ptr, self_type) noexcept {
    3150              :                         return *other_ptr != char8_t{0};
    3151              :                 }
    3152              : #endif
    3153              :         };
    3154              :         
    3155              :         const char8_t * ptr{nullptr};
    3156              :         const char8_t * end{nullptr};
    3157              : #ifndef CTRE_NO_NEED_FOR_ADDITIONAL_COMPARISONS
    3158              :         constexpr friend bool operator!=(const utf8_iterator & lhs, sentinel) {
    3159              :                 return lhs.ptr < lhs.end;
    3160              :         }
    3161              :         
    3162              :         constexpr friend bool operator!=(const utf8_iterator & lhs, const char8_t * rhs) {
    3163              :                 return lhs.ptr != rhs;
    3164              :         }
    3165              :         
    3166              :         constexpr friend bool operator!=(const utf8_iterator & lhs, const utf8_iterator & rhs) {
    3167              :                 return lhs.ptr != rhs.ptr;
    3168              :         }
    3169              : #endif  
    3170              :         constexpr friend bool operator==(const utf8_iterator & lhs, sentinel) {
    3171              :                 return lhs.ptr >= lhs.end;
    3172              :         }
    3173              :         
    3174              :         constexpr friend bool operator==(const utf8_iterator & lhs, const char8_t * rhs) {
    3175              :                 return lhs.ptr == rhs;
    3176              :         }
    3177              :         
    3178              :         constexpr friend bool operator==(const utf8_iterator & lhs, const utf8_iterator & rhs) {
    3179              :                 return lhs.ptr == rhs.ptr;
    3180              :         }
    3181              :         
    3182              : #ifndef CTRE_NO_NEED_FOR_ADDITIONAL_COMPARISONS
    3183              :         constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) {
    3184              :                 return rhs.ptr < rhs.end;
    3185              :         }
    3186              :         
    3187              :         constexpr friend bool operator!=(const char8_t * lhs, const utf8_iterator & rhs) {
    3188              :                 return lhs == rhs.ptr;
    3189              :         }
    3190              :         
    3191              :         constexpr friend bool operator==(sentinel, const utf8_iterator & rhs) {
    3192              :                 return rhs.ptr >= rhs.end;
    3193              :         }
    3194              :         
    3195              :         constexpr friend bool operator==(const char8_t * lhs, const utf8_iterator & rhs) {
    3196              :                 return lhs == rhs.ptr;
    3197              :         }
    3198              : #endif
    3199              :         
    3200              :         
    3201              :         constexpr utf8_iterator & operator=(const char8_t * rhs) {
    3202              :                 ptr = rhs;
    3203              :                 return *this;
    3204              :         }
    3205              :         
    3206              :         constexpr operator const char8_t *() const noexcept {
    3207              :                 return ptr;
    3208              :         }
    3209              :         
    3210              :         constexpr utf8_iterator & operator++() noexcept {
    3211              :                 // the contant is mapping from first 5 bits of first code unit to length of UTF8 code point -1
    3212              :                 // xxxxx -> yy (5 bits to 2 bits)
    3213              :                 // 5 bits are 32 combination, and for each I need 2 bits, hence 64 bit constant
    3214              :                 // (*ptr >> 2) & 0b111110 look at the left 5 bits ignoring the least significant
    3215              :                 // & 0b11u  selects only needed two bits
    3216              :                 // +1  because each iteration is at least one code unit forward
    3217              :                 
    3218              :                 ptr += ((0x3A55000000000000ull >> ((*ptr >> 2) & 0b111110u)) & 0b11u) + 1;
    3219              :                 return *this;
    3220              :         }
    3221              :         
    3222              :         constexpr utf8_iterator & operator--() noexcept {
    3223              :                 if (ptr > end) {
    3224              :                         ptr = end-1;
    3225              :                 } else {
    3226              :                         --ptr;
    3227              :                 }
    3228              :                 
    3229              :                 while ((*ptr & 0b11000000u) == 0b10'000000) {
    3230              :                         --ptr;
    3231              :                 }
    3232              :                 
    3233              :                 return *this;
    3234              :         }
    3235              :         
    3236              :         constexpr utf8_iterator operator--(int) noexcept {
    3237              :                 auto self = *this;
    3238              :                 this->operator--();
    3239              :                 return self;
    3240              :         }
    3241              :         
    3242              :         constexpr utf8_iterator operator++(int) noexcept {
    3243              :                 auto self = *this;
    3244              :                 this->operator++();
    3245              :                 return self;
    3246              :         }
    3247              :         
    3248              :         constexpr utf8_iterator operator+(unsigned step) const noexcept {
    3249              :                 utf8_iterator result = *this;
    3250              :                 while (step > 0) {
    3251              :                         ++result;
    3252              :                         step--;
    3253              :                 }
    3254              :                 return result;
    3255              :         }
    3256              :         
    3257              :         constexpr utf8_iterator operator-(unsigned step) const noexcept {
    3258              :                 utf8_iterator result = *this;
    3259              :                 while (step > 0) {
    3260              :                         --result;
    3261              :                         step--;
    3262              :                 }
    3263              :                 return result;
    3264              :         }
    3265              :         
    3266              :         constexpr char32_t operator*() const noexcept {
    3267              :                 constexpr char32_t mojibake = 0xFFFDull;
    3268              :                 
    3269              :                 // quickpath
    3270              :                 if (!(*ptr & 0b1000'0000u)) CTRE_LIKELY {
    3271              :                         return static_cast<char32_t>(*ptr);
    3272              :                 }
    3273              :  
    3274              :                 // calculate length based on first 5 bits
    3275              :                 const unsigned length = ((0x3A55000000000000ull >> ((*ptr >> 2) & 0b111110u)) & 0b11u);
    3276              : 
    3277              :                 // actual length is number + 1 bytes
    3278              :                 
    3279              :                 // length 0 here means it's a bad front unit
    3280              :                 if (!length) CTRE_UNLIKELY {
    3281              :                         return mojibake;
    3282              :                 }
    3283              : 
    3284              :                 // if part of the utf-8 sequence is past the end
    3285              :                 if (((ptr + length) >= end)) CTRE_UNLIKELY {
    3286              :                         return mojibake;
    3287              :                 }
    3288              :                 
    3289              :                 if ((ptr[1] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
    3290              :                         return mojibake;
    3291              :                 }
    3292              : 
    3293              :                 const char8_t mask = static_cast<char8_t>(0b0011'1111u >> length);
    3294              :                 
    3295              :                 // length = 1 (2 bytes) mask = 0b0001'1111u
    3296              :                 // length = 2 (3 bytes) mask = 0b0000'1111u
    3297              :                 // length = 3 (4 bytes) mask = 0b0000'0111u
    3298              : 
    3299              :                 // remove utf8 front bits, get only significant part
    3300              :                 // and add first trailing unit
    3301              : 
    3302              :                 char32_t result = static_cast<char32_t>((ptr[0] & mask) << 6u) | (ptr[1] & 0b0011'1111u);
    3303              : 
    3304              :                 // add rest of trailing units
    3305              :                 if (length == 1) CTRE_LIKELY {
    3306              :                         return result;
    3307              :                 }
    3308              : 
    3309              :                 if ((ptr[2] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
    3310              :                         return mojibake;
    3311              :                 }
    3312              : 
    3313              :                 result = (result << 6) | (ptr[2] & 0b0011'1111u);
    3314              : 
    3315              :                 if (length == 2) CTRE_LIKELY {
    3316              :                         return result;
    3317              :                 }
    3318              : 
    3319              :                 if ((ptr[3] & 0b1100'0000u) != 0b1000'0000) CTRE_UNLIKELY {
    3320              :                         return mojibake;
    3321              :                 }
    3322              : 
    3323              :                 return (result << 6) | (ptr[3] & 0b0011'1111u);
    3324              :         }
    3325              : };
    3326              : 
    3327              : #ifdef CTRE_ENABLE_UTF8_RANGE
    3328              : struct utf8_range {
    3329              :         std::u8string_view range;
    3330              :         constexpr utf8_range(std::u8string_view r) noexcept: range{r} { }
    3331              :         
    3332              :         constexpr auto begin() const noexcept {
    3333              :                 return utf8_iterator{range.data(), range.data() + range.size()};
    3334              :         }
    3335              :         constexpr auto end() const noexcept {
    3336              :                 return utf8_iterator::sentinel{};
    3337              :         }
    3338              : };
    3339              : #endif
    3340              : 
    3341              : }
    3342              : 
    3343              : #endif
    3344              : 
    3345              : #endif
    3346              : 
    3347              : #ifndef CTRE_IN_A_MODULE
    3348              : #include <type_traits>
    3349              : #include <tuple>
    3350              : #include <string_view>
    3351              : #include <string>
    3352              : #include <iterator>
    3353              : #include <optional>
    3354              : #ifdef _MSC_VER
    3355              : #include <memory>
    3356              : #endif
    3357              : #include <iosfwd>
    3358              : #if __has_include(<charconv>)
    3359              : #include <charconv>
    3360              : #endif
    3361              : #if defined(__cpp_concepts) && __cpp_concepts >= 202002L
    3362              : #include <concepts>
    3363              : #endif
    3364              : #endif
    3365              : 
    3366              : namespace ctre {
    3367              : 
    3368              : constexpr auto is_random_accessible_f(const std::random_access_iterator_tag &) { return std::true_type{}; }
    3369              : constexpr auto is_random_accessible_f(...) { return std::false_type{}; }
    3370              : 
    3371              : template <typename T> constexpr auto is_reverse_iterator_f(const std::reverse_iterator<T> &) { return std::true_type{}; }
    3372              : constexpr auto is_reverse_iterator_f(...) { return std::false_type{}; }
    3373              : 
    3374              : template <typename T> constexpr bool is_random_accessible = decltype(is_random_accessible_f(std::declval<const T &>())){};
    3375              : template <typename T> constexpr bool is_reverse_iterator = decltype(is_reverse_iterator_f(std::declval<const T &>())){};
    3376              : 
    3377              : struct not_matched_tag_t { };
    3378              : 
    3379              : constexpr inline auto not_matched = not_matched_tag_t{};
    3380              :         
    3381              : template <size_t Id, typename Name = void> struct captured_content {
    3382              :         template <typename Iterator> class storage {
    3383              :                 Iterator _begin{};
    3384              :                 Iterator _end{};
    3385              :                 
    3386              :                 bool _matched{false};
    3387              :         public:
    3388              :                 using char_type = typename std::iterator_traits<Iterator>::value_type;
    3389              :                 
    3390              :                 using name = Name;
    3391              :         
    3392            0 :                 constexpr CTRE_FORCE_INLINE storage() noexcept {}
    3393              :         
    3394              :                 constexpr CTRE_FORCE_INLINE void matched() noexcept {
    3395            0 :                         _matched = true;
    3396            0 :                 }
    3397              :                 constexpr CTRE_FORCE_INLINE void unmatch() noexcept {
    3398            0 :                         _matched = false;
    3399            0 :                 }
    3400              :                 constexpr CTRE_FORCE_INLINE void set_start(Iterator pos) noexcept {
    3401            0 :                         _begin = pos;
    3402            0 :                 }
    3403              :                 constexpr CTRE_FORCE_INLINE storage & set_end(Iterator pos) noexcept {
    3404            0 :                         _end = pos;
    3405            0 :                         return *this;
    3406              :                 }
    3407              :                 constexpr CTRE_FORCE_INLINE Iterator get_end() const noexcept {
    3408            0 :                         return _end;
    3409              :                 }
    3410              :                 
    3411              :         
    3412              :                 constexpr auto begin() const noexcept {
    3413              :                         return _begin;
    3414              :                 }
    3415              :                 constexpr auto end() const noexcept {
    3416              :                         return _end;
    3417              :                 }
    3418              :         
    3419              :                 constexpr explicit CTRE_FORCE_INLINE operator bool() const noexcept {
    3420            0 :                         return _matched;
    3421              :                 }
    3422              :                 
    3423              :                 template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data_unsafe() const noexcept {
    3424              :                         static_assert(!is_reverse_iterator<It>, "Iterator in your capture must not be reverse!");
    3425              :                         
    3426              : #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
    3427              :                         if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
    3428              :                                 return _begin.ptr;
    3429              :                         } else { // I'm doing this to avoid warning about dead code
    3430              : #endif
    3431              :                         
    3432              : #ifdef _MSC_VER
    3433              :                         return std::to_address(_begin); // I'm enabling this only for MSVC for now, as some clang old versions with various libraries (random combinations) has different problems
    3434              : #else
    3435              :                         return &*_begin; 
    3436              : #endif
    3437              :                         
    3438              : #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
    3439              :                         }
    3440              : #endif
    3441              :                 }
    3442              :                 
    3443              :                 template <typename It = Iterator> constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
    3444              :                         constexpr bool must_be_contiguous_nonreverse_iterator = is_random_accessible<typename std::iterator_traits<It>::iterator_category> && !is_reverse_iterator<It>;
    3445              :                         
    3446              :                         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).");
    3447              :                         
    3448              :                         return data_unsafe();
    3449              :                 }
    3450              : 
    3451              :                 constexpr CTRE_FORCE_INLINE auto size() const noexcept {
    3452              :                         return static_cast<size_t>(std::distance(begin(), end()));
    3453              :                 }
    3454              :                 
    3455              :                 constexpr CTRE_FORCE_INLINE size_t unit_size() const noexcept {
    3456              : #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
    3457              :                         if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
    3458              :                                 return static_cast<size_t>(std::distance(_begin.ptr, _end.ptr));
    3459              :                         } else {
    3460              :                                 return static_cast<size_t>(std::distance(begin(), end()));
    3461              :                         }
    3462              : #else
    3463              :                         return static_cast<size_t>(std::distance(begin(), end()));
    3464              : #endif
    3465              :                 }
    3466              :                 
    3467              : #if __has_include(<charconv>)
    3468              :                 template <typename R = int, typename... Ts> constexpr CTRE_FORCE_INLINE auto to_number(Ts && ... args) const noexcept -> R {
    3469              :                         R result{0};
    3470              :                         const auto view = to_view();
    3471              :                         std::from_chars(view.data(), view.data() + view.size(), result, std::forward<Ts>(args)...);
    3472              :                         return result;
    3473              :                 }
    3474              :                 
    3475              :                 template <typename R = int, typename... Ts> constexpr CTRE_FORCE_INLINE auto to_optional_number(Ts && ... args) const noexcept -> std::optional<R> {
    3476              :                         if (!static_cast<bool>(*this)) {
    3477              :                                 return std::nullopt;
    3478              :                         }
    3479              :                 
    3480              :                         return to_number<R>(std::forward<Ts>(args)...);
    3481              :                 }
    3482              : #endif
    3483              :                 
    3484              :                 template <typename It = Iterator> constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
    3485              :                         // random access, because C++ (waving hands around)
    3486              :                         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>;
    3487              :                         
    3488              :                         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.");
    3489              :         
    3490              :                         return std::basic_string_view<char_type>(data_unsafe(), static_cast<size_t>(unit_size()));
    3491              :                 }
    3492              :                 
    3493              :                 constexpr CTRE_FORCE_INLINE auto view() const noexcept {
    3494              :                         return to_view();
    3495              :                 }
    3496              :                 
    3497              :                 template <typename It = Iterator> constexpr CTRE_FORCE_INLINE auto to_optional_view() const noexcept -> std::optional<std::basic_string_view<char_type>> {
    3498              :                         if (!static_cast<bool>(*this)) {
    3499              :                                 return std::nullopt;
    3500              :                         }
    3501              :                         return to_view();
    3502              :                 }
    3503              :                 
    3504              :                 constexpr CTRE_FORCE_INLINE std::basic_string<char_type> to_string() const noexcept {
    3505              : #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
    3506              :                         if constexpr (std::is_same_v<Iterator, utf8_iterator>) {
    3507              :                                 return std::basic_string<char_type>(data_unsafe(), static_cast<size_t>(unit_size()));
    3508              :                         } else {
    3509              :                                 return std::basic_string<char_type>(begin(), end());
    3510              :                         }
    3511              : #else
    3512              :                         return std::basic_string<char_type>(begin(), end());
    3513              : #endif
    3514              :                 }
    3515              :                 
    3516              :                 constexpr CTRE_FORCE_INLINE auto str() const noexcept {
    3517              :                         return to_string();
    3518              :                 }
    3519              :                 
    3520              :                 template <typename It = Iterator> constexpr CTRE_FORCE_INLINE auto to_optional_string() const noexcept -> std::optional<std::basic_string<char_type>> {
    3521              :                         if (!static_cast<bool>(*this)) {
    3522              :                                 return std::nullopt;
    3523              :                         }
    3524              :                         return to_string();
    3525              :                 }
    3526              :                 
    3527              :                 constexpr CTRE_FORCE_INLINE operator std::basic_string_view<char_type>() const noexcept {
    3528              :                         return to_view();
    3529              :                 }
    3530              :                 
    3531              :                 constexpr CTRE_FORCE_INLINE explicit operator std::basic_string<char_type>() const noexcept {
    3532              :                         return to_string();
    3533              :                 }
    3534              :                 
    3535              :                 constexpr CTRE_FORCE_INLINE operator std::optional<std::basic_string_view<char_type>>() const noexcept {
    3536              :                         return to_optional_view();
    3537              :                 }
    3538              :                 
    3539              :                 constexpr CTRE_FORCE_INLINE explicit operator std::optional<std::basic_string<char_type>>() const noexcept {
    3540              :                         return to_optional_string();
    3541              :                 }
    3542              :                 
    3543              :                 constexpr CTRE_FORCE_INLINE static size_t get_id() noexcept {
    3544              :                         return Id;
    3545              :                 }
    3546              :                 
    3547              :                 friend CTRE_FORCE_INLINE constexpr bool operator==(const storage & lhs, std::basic_string_view<char_type> rhs) noexcept {
    3548              :                         return bool(lhs) ? lhs.view() == rhs : false;
    3549              :                 }
    3550              :                 friend CTRE_FORCE_INLINE constexpr bool operator!=(const storage & lhs, std::basic_string_view<char_type> rhs) noexcept {
    3551              :                         return bool(lhs) ? lhs.view() != rhs : false;
    3552              :                 }
    3553              :                 friend CTRE_FORCE_INLINE constexpr bool operator==(std::basic_string_view<char_type> lhs, const storage & rhs) noexcept {
    3554              :                         return bool(rhs) ? lhs == rhs.view() : false;
    3555              :                 }
    3556              :                 friend CTRE_FORCE_INLINE constexpr bool operator!=(std::basic_string_view<char_type> lhs, const storage & rhs) noexcept {
    3557              :                         return bool(rhs) ? lhs != rhs.view() : false;
    3558              :                 }
    3559              :                 friend CTRE_FORCE_INLINE std::ostream & operator<<(std::ostream & str, const storage & rhs) {
    3560              :                         return str << rhs.view();
    3561              :                 }
    3562              :         };
    3563              : };
    3564              : 
    3565              : #if defined(__cpp_concepts) && __cpp_concepts >= 202002L
    3566              : template <typename T> concept capture_group = requires(const T & cap) {
    3567              :         { T::get_id() } -> std::same_as<size_t>;
    3568              :         { cap.view() };
    3569              :         { cap.str() };
    3570              :         { cap.to_string() };
    3571              :         { cap.to_view() };
    3572              :         { cap.unit_size() } -> std::same_as<size_t>;
    3573              :         { cap.size() } -> std::same_as<size_t>;
    3574              :         { static_cast<bool>(cap) };
    3575              :         { cap.data() };
    3576              :         { cap.data_unsafe() };
    3577              :         { cap.begin() };
    3578              :         { cap.end() };
    3579              : };
    3580              : #endif
    3581              : 
    3582              : struct capture_not_exists_tag { };
    3583              : 
    3584              : constexpr auto capture_not_exists = capture_not_exists_tag{};
    3585              : 
    3586              : template <typename... Captures> struct captures;
    3587              : 
    3588              : template <typename Head, typename... Tail> struct captures<Head, Tail...>: captures<Tail...> {
    3589              :         Head head{};
    3590            0 :         constexpr CTRE_FORCE_INLINE captures() noexcept { }
    3591              :         template <size_t id> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3592              :                 if constexpr (id == Head::get_id()) {
    3593              :                         return true;
    3594              :                 } else {
    3595              :                         return captures<Tail...>::template exists<id>();
    3596              :                 }
    3597              :         }
    3598              :         template <typename Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3599              :                 if constexpr (std::is_same_v<Name, typename Head::name>) {
    3600              :                         return true;
    3601              :                 } else {
    3602              :                         return captures<Tail...>::template exists<Name>();
    3603              :                 }
    3604              :         }
    3605              : #if CTRE_CNTTP_COMPILER_CHECK
    3606              :         template <ctll::fixed_string Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3607              : #else
    3608              :         template <const auto & Name> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3609              : #endif
    3610              :                 if constexpr (std::is_same_v<typename Head::name, void>) {
    3611              :                         return captures<Tail...>::template exists<Name>();
    3612              :                 } else {
    3613              :                         if constexpr (Head::name::name.is_same_as(Name)) {
    3614              :                                 return true;
    3615              :                         } else {
    3616              :                                 return captures<Tail...>::template exists<Name>();
    3617              :                         }
    3618              :                 }
    3619              :         }
    3620              :         template <size_t id> CTRE_FORCE_INLINE constexpr auto & select() noexcept {
    3621              :                 if constexpr (id == Head::get_id()) {
    3622            0 :                         return head;
    3623              :                 } else {
    3624              :                         return captures<Tail...>::template select<id>();
    3625              :                 }
    3626              :         }
    3627              :         template <typename Name> CTRE_FORCE_INLINE constexpr auto & select() noexcept {
    3628              :                 if constexpr (std::is_same_v<Name, typename Head::name>) {
    3629              :                         return head;
    3630              :                 } else {
    3631              :                         return captures<Tail...>::template select<Name>();
    3632              :                 }
    3633              :         }
    3634              :         template <size_t id> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3635              :                 if constexpr (id == Head::get_id()) {
    3636            0 :                         return head;
    3637              :                 } else {
    3638              :                         return captures<Tail...>::template select<id>();
    3639              :                 }
    3640              :         }
    3641              :         template <typename Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3642              :                 if constexpr (std::is_same_v<Name, typename Head::name>) {
    3643              :                         return head;
    3644              :                 } else {
    3645              :                         return captures<Tail...>::template select<Name>();
    3646              :                 }
    3647              :         }
    3648              : #if CTRE_CNTTP_COMPILER_CHECK
    3649              :         template <ctll::fixed_string Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3650              : #else
    3651              :         template <const auto & Name> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3652              : #endif
    3653              :                 if constexpr (std::is_same_v<typename Head::name, void>) {
    3654              :                         return captures<Tail...>::template select<Name>();
    3655              :                 } else {
    3656              :                         if constexpr (Head::name::name.is_same_as(Name)) {
    3657              :                                 return head;
    3658              :                         } else {
    3659              :                                 return captures<Tail...>::template select<Name>();
    3660              :                         }
    3661              :                 }
    3662              :         }
    3663              : };
    3664              : 
    3665              : template <> struct captures<> {
    3666            0 :         constexpr CTRE_FORCE_INLINE captures() noexcept { }
    3667              :         template <size_t> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3668              :                 return false;
    3669              :         }
    3670              :         template <typename> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3671              :                 return false;
    3672              :         }
    3673              : #if CTRE_CNTTP_COMPILER_CHECK
    3674              :         template <ctll::fixed_string> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3675              : #else
    3676              :         template <const auto &> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
    3677              : #endif
    3678              :                 return false;
    3679              :         }
    3680              :         template <size_t> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3681              :                 return capture_not_exists;
    3682              :         }
    3683              :         template <typename> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3684              :                 return capture_not_exists;
    3685              :         }
    3686              : #if CTRE_CNTTP_COMPILER_CHECK
    3687              :         template <ctll::fixed_string> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3688              : #else
    3689              :         template <const auto &> CTRE_FORCE_INLINE constexpr auto & select() const noexcept {
    3690              : #endif
    3691              :                 return capture_not_exists;
    3692              :         }
    3693              : };
    3694              : 
    3695              : template <typename Iterator, typename... Captures> class regex_results {
    3696              :         captures<captured_content<0>::template storage<Iterator>, typename Captures::template storage<Iterator>...> _captures{};
    3697              : public:
    3698              :         using char_type = typename std::iterator_traits<Iterator>::value_type;
    3699              :         
    3700            0 :         constexpr CTRE_FORCE_INLINE regex_results() noexcept { }
    3701            0 :         constexpr CTRE_FORCE_INLINE regex_results(not_matched_tag_t) noexcept { }
    3702              :         
    3703              :         // special constructor for deducting
    3704              :         constexpr CTRE_FORCE_INLINE regex_results(Iterator, ctll::list<Captures...>) noexcept { }
    3705              :         
    3706              :         template <size_t Id> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
    3707              :                 constexpr bool capture_of_provided_id_must_exists = decltype(_captures)::template exists<Id>();
    3708              :                 static_assert(capture_of_provided_id_must_exists);
    3709              :                 
    3710              :                 if constexpr (capture_of_provided_id_must_exists) {
    3711              :                         return _captures.template select<Id>();
    3712              :                 } else {
    3713              :                         return false;
    3714              :                 }
    3715              :         }
    3716              :         template <typename Name> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
    3717              :                 constexpr bool capture_of_provided_name_must_exists = decltype(_captures)::template exists<Name>();
    3718              :                 static_assert(capture_of_provided_name_must_exists);
    3719              :         
    3720              :                 if constexpr (capture_of_provided_name_must_exists) {
    3721              :                         return _captures.template select<Name>();
    3722              :                 } else {
    3723              :                         return false;
    3724              :                 }
    3725              :         }
    3726              : #if CTRE_CNTTP_COMPILER_CHECK
    3727              :         template <ctll::fixed_string Name> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
    3728              : #else
    3729              :         template <const auto & Name> CTRE_FORCE_INLINE constexpr auto get() const noexcept {
    3730              : #endif
    3731              :                 constexpr bool capture_of_provided_name_must_exists = decltype(_captures)::template exists<Name>();
    3732              :                 static_assert(capture_of_provided_name_must_exists);
    3733              :         
    3734              :                 if constexpr (capture_of_provided_name_must_exists) {
    3735              :                         return _captures.template select<Name>();
    3736              :                 } else {
    3737              :                         return false;
    3738              :                 }
    3739              :         }
    3740              :         static constexpr size_t count() noexcept {
    3741              :                 return sizeof...(Captures) + 1;
    3742              :         }
    3743              :         constexpr CTRE_FORCE_INLINE regex_results & matched() noexcept {
    3744            0 :                 _captures.template select<0>().matched();
    3745            0 :                 return *this;
    3746              :         }
    3747              :         constexpr CTRE_FORCE_INLINE regex_results & unmatch() noexcept {
    3748            0 :                 _captures.template select<0>().unmatch();
    3749            0 :                 return *this;
    3750              :         }
    3751              :         constexpr CTRE_FORCE_INLINE operator bool() const noexcept {
    3752            0 :                 return bool(_captures.template select<0>());
    3753              :         }
    3754              :         
    3755              :         // implicit conversions
    3756              :         constexpr CTRE_FORCE_INLINE operator std::basic_string_view<char_type>() const noexcept {
    3757              :                 return to_view();
    3758              :         }
    3759              :         
    3760              :         constexpr CTRE_FORCE_INLINE explicit operator std::basic_string<char_type>() const noexcept {
    3761              :                 return to_string();
    3762              :         }
    3763              :         
    3764              :         constexpr CTRE_FORCE_INLINE operator std::optional<std::basic_string_view<char_type>>() const noexcept {
    3765              :                 return to_optional_view();
    3766              :         }
    3767              :         
    3768              :         constexpr CTRE_FORCE_INLINE explicit operator std::optional<std::basic_string<char_type>>() const noexcept {
    3769              :                 return to_optional_string();
    3770              :         }
    3771              :         
    3772              :         // conversion to numbers
    3773              : #if __has_include(<charconv>)
    3774              :         template <typename R = int, typename... Ts> constexpr CTRE_FORCE_INLINE auto to_number(Ts && ... args) const noexcept -> R {
    3775              :                 return _captures.template select<0>().template to_number<R>(std::forward<Ts>(args)...);
    3776              :         }
    3777              :         
    3778              :         template <typename R = int, typename... Ts> constexpr CTRE_FORCE_INLINE auto to_optional_number(Ts && ... args) const noexcept -> std::optional<R> {
    3779              :                 return _captures.template select<0>().template to_optional_number<R>(std::forward<Ts>(args)...);
    3780              :         }
    3781              : #endif
    3782              :         
    3783              :         // conversion to basic_string_view
    3784              :         constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
    3785              :                 return _captures.template select<0>().to_view();
    3786              :         }
    3787              :         
    3788              :         constexpr CTRE_FORCE_INLINE auto view() const noexcept {
    3789              :                 return _captures.template select<0>().view(); // this should be deprecated (??)
    3790              :         }
    3791              :         
    3792              :         constexpr CTRE_FORCE_INLINE auto to_optional_view() const noexcept {
    3793              :                 return _captures.template select<0>().to_optional_view();
    3794              :         }
    3795              :         
    3796              :         // conversion to basic_string
    3797              :         constexpr CTRE_FORCE_INLINE auto to_string() const noexcept {
    3798              :                 return _captures.template select<0>().to_string();
    3799              :         }
    3800              :         
    3801              :         constexpr CTRE_FORCE_INLINE auto str() const noexcept {
    3802              :                 return _captures.template select<0>().to_string();  // this should be deprecated (??)
    3803              :         }
    3804              :         
    3805              :         constexpr CTRE_FORCE_INLINE auto to_optional_string() const noexcept {
    3806              :                 return _captures.template select<0>().to_optional_string();
    3807              :         }
    3808              :         
    3809              :         
    3810              :         
    3811              :         
    3812              :         
    3813              :         constexpr CTRE_FORCE_INLINE size_t size() const noexcept {
    3814              :                 return _captures.template select<0>().size();
    3815              :         }
    3816              :         
    3817              :         constexpr CTRE_FORCE_INLINE const auto * data() const noexcept {
    3818              :                 return _captures.template select<0>().data();
    3819              :         }
    3820              :         
    3821              :         constexpr CTRE_FORCE_INLINE regex_results & set_start_mark(Iterator pos) noexcept {
    3822            0 :                 _captures.template select<0>().set_start(pos);
    3823            0 :                 return *this;
    3824              :         }
    3825              :         constexpr CTRE_FORCE_INLINE regex_results & set_end_mark(Iterator pos) noexcept {
    3826            0 :                 _captures.template select<0>().set_end(pos);
    3827            0 :                 return *this;
    3828              :         }
    3829              :         constexpr CTRE_FORCE_INLINE Iterator get_end_position() const noexcept {
    3830            0 :                 return _captures.template select<0>().get_end();
    3831              :         }
    3832              :         template <size_t Id> CTRE_FORCE_INLINE constexpr regex_results & start_capture(Iterator pos) noexcept {
    3833              :                 _captures.template select<Id>().set_start(pos);
    3834              :                 return *this;
    3835              :         }
    3836              :         template <size_t Id> CTRE_FORCE_INLINE constexpr regex_results & end_capture(Iterator pos) noexcept {
    3837              :                 _captures.template select<Id>().set_end(pos).matched();
    3838              :                 return *this;
    3839              :         }
    3840              :         constexpr auto begin() const noexcept {
    3841              :                 return _captures.template select<0>().begin();
    3842              :         }
    3843              :         constexpr auto end() const noexcept {
    3844              :                 return _captures.template select<0>().end();
    3845              :         }
    3846              :         friend CTRE_FORCE_INLINE constexpr bool operator==(const regex_results & lhs, std::basic_string_view<char_type> rhs) noexcept {
    3847              :                 return bool(lhs) ? lhs.view() == rhs : false;
    3848              :         }
    3849              :         friend CTRE_FORCE_INLINE constexpr bool operator!=(const regex_results & lhs, std::basic_string_view<char_type> rhs) noexcept {
    3850              :                 return bool(lhs) ? lhs.view() != rhs : true;
    3851              :         }
    3852              :         friend CTRE_FORCE_INLINE constexpr bool operator==(std::basic_string_view<char_type> lhs, const regex_results & rhs) noexcept {
    3853              :                 return bool(rhs) ? lhs == rhs.view() : false;
    3854              :         }
    3855              :         friend CTRE_FORCE_INLINE constexpr bool operator!=(std::basic_string_view<char_type> lhs, const regex_results & rhs) noexcept {
    3856              :                 return bool(rhs) ? lhs != rhs.view() : true;
    3857              :         }
    3858              :         friend CTRE_FORCE_INLINE std::ostream & operator<<(std::ostream & str, const regex_results & rhs) {
    3859              : #ifdef CTRE_IN_A_MODULE
    3860              :                 auto view = rhs.view();
    3861              :                 str.write(view.data(), view.size());
    3862              :                 return str;
    3863              : #else
    3864              :                 return str << rhs.view();
    3865              : #endif
    3866              :         }
    3867              : };
    3868              : 
    3869              : template <size_t Id, typename Iterator, typename... Captures> constexpr auto get(const regex_results<Iterator, Captures...> & results) noexcept {
    3870              :         return results.template get<Id>();
    3871              : }
    3872              : 
    3873              : template <typename Iterator, typename... Captures> regex_results(Iterator, ctll::list<Captures...>) -> regex_results<Iterator, Captures...>;
    3874              : 
    3875              : template <typename> struct is_regex_results_t: std::false_type { };
    3876              : 
    3877              : template <typename Iterator, typename... Captures> struct is_regex_results_t<regex_results<Iterator, Captures...>>: std::true_type { };
    3878              : 
    3879              : template <typename T> constexpr bool is_regex_results_v = is_regex_results_t<T>();
    3880              : 
    3881              : #if defined(__cpp_concepts) && __cpp_concepts >= 201907L
    3882              : template <typename T> concept capture_groups = is_regex_results_v<T>;
    3883              : #endif
    3884              : 
    3885              : template <typename ResultIterator, typename Pattern> using return_type = decltype(regex_results(std::declval<ResultIterator>(), find_captures(Pattern{})));
    3886              : 
    3887              : }
    3888              : 
    3889              : // support for structured bindings
    3890              : 
    3891              : #ifndef __EDG__
    3892              : #ifdef __clang__
    3893              : #pragma clang diagnostic push
    3894              : #pragma clang diagnostic ignored "-Wmismatched-tags"
    3895              : #endif
    3896              : 
    3897              : namespace std {
    3898              :         template <typename... Captures> struct tuple_size<ctre::regex_results<Captures...>> : public std::integral_constant<size_t, ctre::regex_results<Captures...>::count()> { };
    3899              :         
    3900              :         template <size_t N, typename... Captures> struct tuple_element<N, ctre::regex_results<Captures...>> {
    3901              :         public:
    3902              :                 using type = decltype(
    3903              :                         std::declval<const ctre::regex_results<Captures...> &>().template get<N>()
    3904              :                 );
    3905              :         };
    3906              : }
    3907              : 
    3908              : #ifdef __clang__
    3909              : #pragma clang diagnostic pop
    3910              : #endif
    3911              : #endif
    3912              : 
    3913              : #endif
    3914              : 
    3915              : #ifndef CTRE__FIND_CAPTURES__HPP
    3916              : #define CTRE__FIND_CAPTURES__HPP
    3917              : 
    3918              : namespace ctre {
    3919              : 
    3920              : CTRE_EXPORT template <typename Pattern> constexpr auto find_captures(Pattern) noexcept {
    3921              :         return find_captures(ctll::list<Pattern>(), ctll::list<>());
    3922              : }
    3923              : 
    3924              : CTRE_EXPORT template <typename... Output> constexpr auto find_captures(ctll::list<>, ctll::list<Output...> output) noexcept {
    3925              :         return output;
    3926              : }
    3927              : 
    3928              : CTRE_EXPORT template <auto... String, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<string<String...>, Tail...>, Output output) noexcept {
    3929              :         return find_captures(ctll::list<Tail...>(), output);
    3930              : }
    3931              : 
    3932              : CTRE_EXPORT template <typename... Options, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<select<Options...>, Tail...>, Output output) noexcept {
    3933              :         return find_captures(ctll::list<Options..., Tail...>(), output);
    3934              : }
    3935              : 
    3936              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<optional<Content...>, Tail...>, Output output) noexcept {
    3937              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3938              : }
    3939              : 
    3940              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_optional<Content...>, Tail...>, Output output) noexcept {
    3941              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3942              : }
    3943              : 
    3944              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<sequence<Content...>, Tail...>, Output output) noexcept {
    3945              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3946              : }
    3947              : 
    3948              : CTRE_EXPORT template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<empty, Tail...>, Output output) noexcept {
    3949              :         return find_captures(ctll::list<Tail...>(), output);
    3950              : }
    3951              : 
    3952              : CTRE_EXPORT template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<assert_subject_begin, Tail...>, Output output) noexcept {
    3953              :         return find_captures(ctll::list<Tail...>(), output);
    3954              : }
    3955              : 
    3956              : CTRE_EXPORT template <typename... Tail, typename Output> constexpr auto find_captures(ctll::list<assert_subject_end, Tail...>, Output output) noexcept {
    3957              :         return find_captures(ctll::list<Tail...>(), output);
    3958              : }
    3959              : 
    3960              : // , typename = std::enable_if_t<(MatchesCharacter<CharacterLike>::template value<char>)
    3961              : CTRE_EXPORT template <typename CharacterLike, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<CharacterLike, Tail...>, Output output) noexcept {
    3962              :         return find_captures(ctll::list<Tail...>(), output);
    3963              : }
    3964              : 
    3965              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<plus<Content...>, Tail...>, Output output) noexcept {
    3966              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3967              : }
    3968              : 
    3969              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<star<Content...>, Tail...>, Output output) noexcept {
    3970              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3971              : }
    3972              : 
    3973              : CTRE_EXPORT 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 {
    3974              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3975              : }
    3976              : 
    3977              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_plus<Content...>, Tail...>, Output output) noexcept {
    3978              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3979              : }
    3980              : 
    3981              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lazy_star<Content...>, Tail...>, Output output) noexcept {
    3982              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3983              : }
    3984              : 
    3985              : CTRE_EXPORT 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 {
    3986              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3987              : }
    3988              : 
    3989              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<possessive_plus<Content...>, Tail...>, Output output) noexcept {
    3990              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3991              : }
    3992              : 
    3993              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<possessive_star<Content...>, Tail...>, Output output) noexcept {
    3994              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3995              : }
    3996              : 
    3997              : CTRE_EXPORT 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 {
    3998              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    3999              : }
    4000              : 
    4001              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lookahead_positive<Content...>, Tail...>, Output output) noexcept {
    4002              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    4003              : }
    4004              : 
    4005              : CTRE_EXPORT template <typename... Content, typename... Tail, typename Output> constexpr auto find_captures(ctll::list<lookahead_negative<Content...>, Tail...>, Output output) noexcept {
    4006              :         return find_captures(ctll::list<Content..., Tail...>(), output);
    4007              : }
    4008              : 
    4009              : CTRE_EXPORT template <size_t Id, typename... Content, typename... Tail, typename... Output> constexpr auto find_captures(ctll::list<capture<Id,Content...>, Tail...>, ctll::list<Output...>) noexcept {
    4010              :         return find_captures(ctll::list<Content..., Tail...>(), ctll::list<Output..., captured_content<Id>>());
    4011              : }
    4012              : 
    4013              : CTRE_EXPORT 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 {
    4014              :         return find_captures(ctll::list<Content..., Tail...>(), ctll::list<Output..., captured_content<Id, Name>>());
    4015              : }
    4016              : 
    4017              : }
    4018              : 
    4019              : #endif
    4020              : 
    4021              : #ifndef CTRE__FIRST__HPP
    4022              : #define CTRE__FIRST__HPP
    4023              : 
    4024              : namespace ctre {
    4025              :         
    4026              : struct can_be_anything {};
    4027              :         
    4028              : 
    4029              : template <typename... Content> 
    4030              : constexpr auto first(ctll::list<Content...> l, ctll::list<>) noexcept {
    4031              :         return l;
    4032              : }
    4033              : 
    4034              : template <typename... Content, typename... Tail> 
    4035              : constexpr auto first(ctll::list<Content...> l, ctll::list<accept, Tail...>) noexcept {
    4036              :         return l;
    4037              : }
    4038              : 
    4039              : template <typename... Content, typename... Tail> 
    4040              : constexpr auto first(ctll::list<Content...> l, ctll::list<end_mark, Tail...>) noexcept {
    4041              :         return l;
    4042              : }
    4043              : 
    4044              : template <typename... Content, typename... Tail> 
    4045              : constexpr auto first(ctll::list<Content...> l, ctll::list<end_cycle_mark, Tail...>) noexcept {
    4046              :         return l;
    4047              : }
    4048              : 
    4049              : template <typename... Content, typename... Tail> 
    4050              : constexpr auto first(ctll::list<Content...> l, ctll::list<end_lookahead_mark, Tail...>) noexcept {
    4051              :         return l;
    4052              : }
    4053              : 
    4054              : template <typename... Content, size_t Id, typename... Tail> 
    4055              : constexpr auto first(ctll::list<Content...> l, ctll::list<numeric_mark<Id>, Tail...>) noexcept {
    4056              :         return first(l, ctll::list<Tail...>{});
    4057              : }
    4058              : 
    4059              : // empty
    4060              : template <typename... Content, typename... Tail> 
    4061              : constexpr auto first(ctll::list<Content...> l, ctll::list<empty, Tail...>) noexcept {
    4062              :         return first(l, ctll::list<Tail...>{});
    4063              : }
    4064              : 
    4065              : // boundary
    4066              : template <typename... Content, typename CharLike, typename... Tail> 
    4067              : constexpr auto first(ctll::list<Content...> l, ctll::list<boundary<CharLike>, Tail...>) noexcept {
    4068              :         return first(l, ctll::list<Tail...>{});
    4069              : }
    4070              : 
    4071              : // asserts
    4072              : template <typename... Content, typename... Tail> 
    4073              : constexpr auto first(ctll::list<Content...> l, ctll::list<assert_subject_begin, Tail...>) noexcept {
    4074              :         return first(l, ctll::list<Tail...>{});
    4075              : }
    4076              : 
    4077              : template <typename... Content, typename... Tail> 
    4078              : constexpr auto first(ctll::list<Content...> l, ctll::list<assert_subject_end, Tail...>) noexcept {
    4079              :         return l;
    4080              : }
    4081              : 
    4082              : template <typename... Content, typename... Tail> 
    4083              : constexpr auto first(ctll::list<Content...> l, ctll::list<assert_subject_end_line, Tail...>) noexcept {
    4084              :         // FIXME allow endline here
    4085              :         return l;
    4086              : }
    4087              : 
    4088              : template <typename... Content, typename... Tail> 
    4089              : constexpr auto first(ctll::list<Content...> l, ctll::list<assert_line_begin, Tail...>) noexcept {
    4090              :         // FIXME line begin is a bit different than subject begin
    4091              :         return first(l, ctll::list<Tail...>{});
    4092              : }
    4093              : 
    4094              : template <typename... Content, typename... Tail> 
    4095              : constexpr auto first(ctll::list<Content...> l, ctll::list<assert_line_end, Tail...>) noexcept {
    4096              :         // FIXME line end is a bit different than subject begin
    4097              :         return l;
    4098              : }
    4099              : 
    4100              : // sequence
    4101              : template <typename... Content, typename... Seq, typename... Tail> 
    4102              : constexpr auto first(ctll::list<Content...> l, ctll::list<sequence<Seq...>, Tail...>) noexcept {
    4103              :         return first(l, ctll::list<Seq..., Tail...>{});
    4104              : }
    4105              : 
    4106              : // atomic group
    4107              : template <typename... Content, typename... Seq, typename... Tail> 
    4108              : constexpr auto first(ctll::list<Content...> l, ctll::list<atomic_group<Seq...>, Tail...>) noexcept {
    4109              :         return first(l, ctll::list<possessive_repeat<1, 1, Seq...>, Tail...>{});
    4110              : }
    4111              : 
    4112              : // plus
    4113              : template <typename... Content, typename... Seq, typename... Tail> 
    4114              : constexpr auto first(ctll::list<Content...> l, ctll::list<plus<Seq...>, Tail...>) noexcept {
    4115              :         return first(l, ctll::list<Seq..., Tail...>{});
    4116              : }
    4117              : 
    4118              : // lazy_plus
    4119              : template <typename... Content, typename... Seq, typename... Tail> 
    4120              : constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_plus<Seq...>, Tail...>) noexcept {
    4121              :         return first(l, ctll::list<Seq..., Tail...>{});
    4122              : }
    4123              : 
    4124              : // possessive_plus
    4125              : template <typename... Content, typename... Seq, typename... Tail> 
    4126              : constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_plus<Seq...>, Tail...>) noexcept {
    4127              :         return first(l, ctll::list<Seq..., Tail...>{});
    4128              : }
    4129              : 
    4130              : // star
    4131              : template <typename... Content, typename... Seq, typename... Tail> 
    4132              : constexpr auto first(ctll::list<Content...> l, ctll::list<star<Seq...>, Tail...>) noexcept {
    4133              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4134              : }
    4135              : 
    4136              : // lazy_star
    4137              : template <typename... Content, typename... Seq, typename... Tail> 
    4138              : constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_star<Seq...>, Tail...>) noexcept {
    4139              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4140              : }
    4141              : 
    4142              : // possessive_star
    4143              : template <typename... Content, typename... Seq, typename... Tail> 
    4144              : constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_star<Seq...>, Tail...>) noexcept {
    4145              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4146              : }
    4147              : 
    4148              : // lazy_repeat
    4149              : template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail> 
    4150              : constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_repeat<A, B, Seq...>, Tail...>) noexcept {
    4151              :         return first(l, ctll::list<Seq..., Tail...>{});
    4152              : }
    4153              : 
    4154              : template <typename... Content, size_t B, typename... Seq, typename... Tail> 
    4155              : constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_repeat<0, B, Seq...>, Tail...>) noexcept {
    4156              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4157              : }
    4158              : 
    4159              : // possessive_repeat
    4160              : template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail> 
    4161              : constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_repeat<A, B, Seq...>, Tail...>) noexcept {
    4162              :         return first(l, ctll::list<Seq..., Tail...>{});
    4163              : }
    4164              : 
    4165              : template <typename... Content, size_t B, typename... Seq, typename... Tail> 
    4166              : constexpr auto first(ctll::list<Content...> l, ctll::list<possessive_repeat<0, B, Seq...>, Tail...>) noexcept {
    4167              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4168              : }
    4169              : 
    4170              : // repeat
    4171              : template <typename... Content, size_t A, size_t B, typename... Seq, typename... Tail> 
    4172              : constexpr auto first(ctll::list<Content...> l, ctll::list<repeat<A, B, Seq...>, Tail...>) noexcept {
    4173              :         return first(l, ctll::list<Seq..., Tail...>{});
    4174              : }
    4175              : 
    4176              : template <typename... Content, size_t B, typename... Seq, typename... Tail> 
    4177              : constexpr auto first(ctll::list<Content...> l, ctll::list<repeat<0, B, Seq...>, Tail...>) noexcept {
    4178              :         return first(first(l, ctll::list<Tail...>{}), ctll::list<Seq..., Tail...>{});
    4179              : }
    4180              : 
    4181              : // lookahead_positive
    4182              : template <typename... Content, typename... Seq, typename... Tail> 
    4183              : constexpr auto first(ctll::list<Content...>, ctll::list<lookahead_positive<Seq...>, Tail...>) noexcept {
    4184              :         return ctll::list<can_be_anything>{};
    4185              : }
    4186              : 
    4187              : // lookbehind_negative TODO fixme
    4188              : template <typename... Content, typename... Seq, typename... Tail> 
    4189              : constexpr auto first(ctll::list<Content...>, ctll::list<lookbehind_negative<Seq...>, Tail...>) noexcept {
    4190              :         return ctll::list<can_be_anything>{};
    4191              : }
    4192              : 
    4193              : // lookbehind_positive
    4194              : template <typename... Content, typename... Seq, typename... Tail> 
    4195              : constexpr auto first(ctll::list<Content...>, ctll::list<lookbehind_positive<Seq...>, Tail...>) noexcept {
    4196              :         return ctll::list<can_be_anything>{};
    4197              : }
    4198              : 
    4199              : // lookahead_negative TODO fixme
    4200              : template <typename... Content, typename... Seq, typename... Tail> 
    4201              : constexpr auto first(ctll::list<Content...>, ctll::list<lookahead_negative<Seq...>, Tail...>) noexcept {
    4202              :         return ctll::list<can_be_anything>{};
    4203              : }
    4204              : 
    4205              : // capture
    4206              : template <typename... Content, size_t Id, typename... Seq, typename... Tail> 
    4207              : constexpr auto first(ctll::list<Content...> l, ctll::list<capture<Id, Seq...>, Tail...>) noexcept {
    4208              :         return first(l, ctll::list<Seq..., Tail...>{});
    4209              : }
    4210              : 
    4211              : template <typename... Content, size_t Id, typename Name, typename... Seq, typename... Tail> 
    4212              : constexpr auto first(ctll::list<Content...> l, ctll::list<capture_with_name<Id, Name, Seq...>, Tail...>) noexcept {
    4213              :         return first(l, ctll::list<Seq..., Tail...>{});
    4214              : }
    4215              : 
    4216              : // backreference
    4217              : template <typename... Content, size_t Id, typename... Tail> 
    4218              : constexpr auto first(ctll::list<Content...>, ctll::list<back_reference<Id>, Tail...>) noexcept {
    4219              :         return ctll::list<can_be_anything>{};
    4220              : }
    4221              : 
    4222              : template <typename... Content, typename Name, typename... Tail> 
    4223              : constexpr auto first(ctll::list<Content...>, ctll::list<back_reference_with_name<Name>, Tail...>) noexcept {
    4224              :         return ctll::list<can_be_anything>{};
    4225              : }
    4226              : 
    4227              : // string First extraction
    4228              : template <typename... Content, auto First, auto... String, typename... Tail> 
    4229              : constexpr auto first(ctll::list<Content...>, ctll::list<string<First, String...>, Tail...>) noexcept {
    4230              :         return ctll::list<Content..., character<First>>{};
    4231              : }
    4232              : 
    4233              : template <typename... Content, typename... Tail> 
    4234              : constexpr auto first(ctll::list<Content...> l, ctll::list<string<>, Tail...>) noexcept {
    4235              :         return first(l, ctll::list<Tail...>{});
    4236              : }
    4237              : 
    4238              : // optional
    4239              : template <typename... Content, typename... Opt, typename... Tail> 
    4240              : constexpr auto first(ctll::list<Content...> l, ctll::list<optional<Opt...>, Tail...>) noexcept {
    4241              :         return first(first(l, ctll::list<Opt..., Tail...>{}), ctll::list<Tail...>{});
    4242              : }
    4243              : 
    4244              : template <typename... Content, typename... Opt, typename... Tail> 
    4245              : constexpr auto first(ctll::list<Content...> l, ctll::list<lazy_optional<Opt...>, Tail...>) noexcept {
    4246              :         return first(first(l, ctll::list<Opt..., Tail...>{}), ctll::list<Tail...>{});
    4247              : }
    4248              : 
    4249              : // select (alternation)
    4250              : template <typename... Content, typename SHead, typename... STail, typename... Tail> 
    4251              : constexpr auto first(ctll::list<Content...> l, ctll::list<select<SHead, STail...>, Tail...>) noexcept {
    4252              :         return first(first(l, ctll::list<SHead, Tail...>{}), ctll::list<select<STail...>, Tail...>{});
    4253              : }
    4254              : 
    4255              : template <typename... Content, typename... Tail> 
    4256              : constexpr auto first(ctll::list<Content...> l, ctll::list<select<>, Tail...>) noexcept {
    4257              :         return l;
    4258              : }
    4259              : 
    4260              : // unicode property => anything
    4261              : template <typename... Content, typename PropertyType, PropertyType Property, typename... Tail> 
    4262              : constexpr auto first(ctll::list<Content...>, ctll::list<ctre::binary_property<PropertyType, Property>, Tail...>) noexcept {
    4263              :         return ctll::list<can_be_anything>{};
    4264              : }
    4265              : 
    4266              : template <typename... Content, typename PropertyType, PropertyType Property, auto Value, typename... Tail> 
    4267              : constexpr auto first(ctll::list<Content...>, ctll::list<ctre::property<PropertyType, Property, Value>, Tail...>) noexcept {
    4268              :         return ctll::list<can_be_anything>{};
    4269              : }
    4270              : 
    4271              : // characters / sets
    4272              : 
    4273              : template <typename... Content, auto V, typename... Tail> 
    4274              : constexpr auto first(ctll::list<Content...>, ctll::list<character<V>, Tail...>) noexcept {
    4275              :         return ctll::list<Content..., character<V>>{};
    4276              : }
    4277              : 
    4278              : template <typename... Content, auto... Values, typename... Tail> 
    4279              : constexpr auto first(ctll::list<Content...>, ctll::list<enumeration<Values...>, Tail...>) noexcept {
    4280              :         return ctll::list<Content..., character<Values>...>{};
    4281              : }
    4282              : 
    4283              : template <typename... Content, typename... SetContent, typename... Tail> 
    4284              : constexpr auto first(ctll::list<Content...>, ctll::list<set<SetContent...>, Tail...>) noexcept {
    4285              :         return ctll::list<Content..., SetContent...>{};
    4286              : }
    4287              : 
    4288              : template <typename... Content, auto A, auto B, typename... Tail> 
    4289              : constexpr auto first(ctll::list<Content...>, ctll::list<char_range<A,B>, Tail...>) noexcept {
    4290              :         return ctll::list<Content..., char_range<A,B>>{};
    4291              : }
    4292              : 
    4293              : template <typename... Content, typename... Tail> 
    4294              : constexpr auto first(ctll::list<Content...>, ctll::list<any, Tail...>) noexcept {
    4295              :         return ctll::list<can_be_anything>{};
    4296              : }
    4297              : 
    4298              : // negative
    4299              : template <typename... Content, typename... SetContent, typename... Tail> 
    4300              : constexpr auto first(ctll::list<Content...>, ctll::list<negate<SetContent...>, Tail...>) noexcept {
    4301              :         return ctll::list<Content..., negative_set<SetContent...>>{};
    4302              : }
    4303              : 
    4304              : template <typename... Content, typename... SetContent, typename... Tail> 
    4305              : constexpr auto first(ctll::list<Content...>, ctll::list<negative_set<SetContent...>, Tail...>) noexcept {
    4306              :         return ctll::list<Content..., negative_set<SetContent...>>{};
    4307              : }
    4308              : 
    4309              : // user facing interface
    4310              : template <typename... Content> constexpr auto calculate_first(Content...) noexcept {
    4311              :         return first(ctll::list<>{}, ctll::list<Content...>{});
    4312              : }
    4313              : 
    4314              : // calculate mutual exclusivity
    4315              : template <typename... Content> constexpr size_t calculate_size_of_first(ctre::negative_set<Content...>) {
    4316              :         return 1 + calculate_size_of_first(ctre::set<Content...>{});
    4317              : }
    4318              : 
    4319              : template <auto... V> constexpr size_t calculate_size_of_first(ctre::enumeration<V...>) {
    4320              :         return sizeof...(V);
    4321              : }
    4322              : 
    4323              : constexpr size_t calculate_size_of_first(...) {
    4324              :         return 1;
    4325              : }
    4326              : 
    4327              : template <typename... Content> constexpr size_t calculate_size_of_first(ctll::list<Content...>) {
    4328              :         return (calculate_size_of_first(Content{}) + ... + 0);
    4329              : }
    4330              : 
    4331              : template <typename... Content> constexpr size_t calculate_size_of_first(ctre::set<Content...>) {
    4332              :         return (calculate_size_of_first(Content{}) + ... + 0);
    4333              : }
    4334              : 
    4335              : template <auto A, typename CB> constexpr int64_t negative_helper(ctre::character<A>, CB & cb, int64_t start) {
    4336              :         if (A != (std::numeric_limits<int64_t>::min)()) {
    4337              :                 if (start < A) {
    4338              :                         cb(start, A-1);
    4339              :                 }
    4340              :         }
    4341              :         if (A != (std::numeric_limits<int64_t>::max)()) {
    4342              :                 return A+1;
    4343              :         } else {
    4344              :                 return A;
    4345              :         }
    4346              : }       
    4347              : 
    4348              : template <auto A, auto B, typename CB> constexpr int64_t negative_helper(ctre::char_range<A,B>, CB & cb, int64_t start) {
    4349              :         if (A != (std::numeric_limits<int64_t>::min)()) {
    4350              :                 if (start < A) {
    4351              :                         cb(start, A-1);
    4352              :                 }
    4353              :         }
    4354              :         if (B != (std::numeric_limits<int64_t>::max)()) {
    4355              :                 return B+1;
    4356              :         } else {
    4357              :                 return B;
    4358              :         }
    4359              : }       
    4360              : 
    4361              : template <auto Head, auto... Tail, typename CB> constexpr int64_t negative_helper(ctre::enumeration<Head, Tail...>, CB & cb, int64_t start) {
    4362              :         int64_t nstart = negative_helper(ctre::character<Head>{}, cb, start);
    4363              :         return negative_helper(ctre::enumeration<Tail...>{}, cb, nstart);
    4364              : }
    4365              : 
    4366              : template <typename CB> constexpr int64_t negative_helper(ctre::enumeration<>, CB &, int64_t start) {
    4367              :         return start;
    4368              : }
    4369              : 
    4370              : template <typename CB> constexpr int64_t negative_helper(ctre::set<>, CB &, int64_t start) {
    4371              :         return start;
    4372              : }
    4373              : 
    4374              : template <typename PropertyType, PropertyType Property, typename CB> 
    4375              : constexpr auto negative_helper(ctre::binary_property<PropertyType, Property>, CB &&, int64_t start) {
    4376              :         return start;
    4377              : }
    4378              : 
    4379              : template <typename PropertyType, PropertyType Property, auto Value, typename CB> 
    4380              : constexpr auto negative_helper(ctre::property<PropertyType, Property, Value>, CB &&, int64_t start) {
    4381              :         return start;
    4382              : }
    4383              : 
    4384              : template <typename Head, typename... Rest, typename CB> constexpr int64_t negative_helper(ctre::set<Head, Rest...>, CB & cb, int64_t start) {
    4385              :         start = negative_helper(Head{}, cb, start);
    4386              :         return negative_helper(ctre::set<Rest...>{}, cb, start);
    4387              : }
    4388              : 
    4389              : 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)()) {
    4390              :         start = negative_helper(Head{}, cb, start);
    4391              :         negative_helper(ctre::negative_set<Rest...>{}, std::forward<CB>(cb), start);
    4392              : }
    4393              : 
    4394              : template <typename CB> constexpr void negative_helper(ctre::negative_set<>, CB && cb, int64_t start = (std::numeric_limits<int64_t>::min)()) {
    4395              :         if (start < (std::numeric_limits<int64_t>::max)()) {
    4396              :                 cb(start, (std::numeric_limits<int64_t>::max)());
    4397              :         }
    4398              : }
    4399              : 
    4400              : // simple fixed set
    4401              : // TODO: this needs some optimizations
    4402              : template <size_t Capacity> class point_set {
    4403              :         struct point {
    4404              :                 int64_t low{};
    4405              :                 int64_t high{};
    4406              :                 constexpr bool operator<(const point & rhs) const {
    4407              :                         return low < rhs.low;
    4408              :                 }
    4409              :                 constexpr point() { }
    4410              :                 constexpr point(int64_t l, int64_t h): low{l}, high{h} { }
    4411              :         };
    4412              :         point points[Capacity+1]{};
    4413              :         size_t used{0};
    4414              :         constexpr point * begin() {
    4415              :                 return points;
    4416              :         }
    4417              :         constexpr point * begin() const {
    4418              :                 return points;
    4419              :         }
    4420              :         constexpr point * end() {
    4421              :                 return points + used;
    4422              :         }
    4423              :         constexpr point * end() const {
    4424              :                 return points + used;
    4425              :         }
    4426              :         constexpr point * lower_bound(point obj) {
    4427              :                 auto first = begin();
    4428              :                 auto last = end();
    4429              :                 auto it = first;
    4430              :                 auto count = std::distance(first, last);
    4431              :                 while (count != 0) {
    4432              :                         it = first;
    4433              :                         auto step = count / 2;
    4434              :                         std::advance(it, step);
    4435              :                         if (*it < obj) {
    4436              :                                 first = ++it;
    4437              :                                 count -= step + 1;
    4438              :                         } else {
    4439              :                                 count = step;
    4440              :                         }
    4441              :                 }
    4442              :                 return it;
    4443              :         }
    4444              :         constexpr point * insert_point(int64_t position, int64_t other) {
    4445              :                 point obj{position, other};
    4446              :                 auto it = lower_bound(obj);
    4447              :                 if (it == end()) {
    4448              :                         *it = obj;
    4449              :                         used++;
    4450              :                         return it;
    4451              :                 } else {
    4452              :                         auto out = it;
    4453              :                         auto e = end();
    4454              :                         while (it != e) {
    4455              :                                 auto tmp = *it;
    4456              :                                 *it = obj;
    4457              :                                 obj = tmp;
    4458              :                                 //std::swap(*it, obj);
    4459              :                                 it++;
    4460              :                         }
    4461              :                         auto tmp = *it;
    4462              :                         *it = obj;
    4463              :                         obj = tmp;
    4464              :                         //std::swap(*it, obj);
    4465              :                         
    4466              :                         used++;
    4467              :                         return out;
    4468              :                 }
    4469              :         }
    4470              : public:
    4471              :         constexpr point_set() { }
    4472              :         constexpr void insert(int64_t low, int64_t high) {
    4473              :                 insert_point(low, high);
    4474              :                 //insert_point(high, low);
    4475              :         }
    4476              :         constexpr bool check(int64_t low, int64_t high) {
    4477              :                 for (const auto & r: *this) {
    4478              :                         if (r.low <= low && low <= r.high) {
    4479              :                                 return true;
    4480              :                         } else if (r.low <= high && high <= r.high) {
    4481              :                                 return true;
    4482              :                         } else if (low <= r.low && r.low <= high) {
    4483              :                                 return true;
    4484              :                         } else if (low <= r.high && r.high <= high) {
    4485              :                                 return true;
    4486              :                         }
    4487              :                 }
    4488              :                 return false;
    4489              :         }
    4490              :         
    4491              :         
    4492              :         template <auto V> constexpr bool check(ctre::character<V>) {
    4493              :                 return check(V,V);
    4494              :         }
    4495              :         template <auto A, auto B> constexpr bool check(ctre::char_range<A,B>) {
    4496              :                 return check(A,B);
    4497              :         }
    4498              :         constexpr bool check(can_be_anything) {
    4499              :                 return used > 0;
    4500              :         }
    4501              :         template <typename PropertyType, PropertyType Property> 
    4502              :         constexpr bool check(ctre::binary_property<PropertyType, Property>) {
    4503              :                 return check(can_be_anything{});
    4504              :         }
    4505              : 
    4506              :         template <typename PropertyType, PropertyType Property, auto Value> 
    4507              :         constexpr bool check(ctre::property<PropertyType, Property, Value>) {
    4508              :                 return check(can_be_anything{});
    4509              :         }
    4510              :         template <typename... Content> constexpr bool check(ctre::negative_set<Content...> nset) {
    4511              :                 bool collision = false;
    4512              :                 negative_helper(nset, [&](int64_t low, int64_t high){
    4513              :                         collision |= this->check(low, high);
    4514              :                 });
    4515              :                 return collision;
    4516              :         }
    4517              :         template <auto... V> constexpr bool check(ctre::enumeration<V...>) {
    4518              :                 
    4519              :                 return (check(V,V) || ... || false);
    4520              :         }
    4521              :         template <typename... Content> constexpr bool check(ctll::list<Content...>) {
    4522              :                 return (check(Content{}) || ... || false);
    4523              :         }
    4524              :         template <typename... Content> constexpr bool check(ctre::set<Content...>) {
    4525              :                 return (check(Content{}) || ... || false);
    4526              :         }
    4527              :         
    4528              :         
    4529              :         template <auto V> constexpr void populate(ctre::character<V>) {
    4530              :                 insert(V,V);
    4531              :         }
    4532              :         template <auto A, auto B> constexpr void populate(ctre::char_range<A,B>) {
    4533              :                 insert(A,B);
    4534              :         }
    4535              :         constexpr void populate(...) {
    4536              :                 points[0].low = (std::numeric_limits<int64_t>::min)();
    4537              :                 points[0].high = (std::numeric_limits<int64_t>::max)();
    4538              :                 used = 1;
    4539              :         }
    4540              :         template <typename... Content> constexpr void populate(ctre::negative_set<Content...> nset) {
    4541              :                 negative_helper(nset, [&](int64_t low, int64_t high){
    4542              :                         this->insert(low, high);
    4543              :                 });
    4544              :         }
    4545              :         template <typename... Content> constexpr void populate(ctre::set<Content...>) {
    4546              :                 (populate(Content{}), ...);
    4547              :         }
    4548              :         template <typename... Content> constexpr void populate(ctll::list<Content...>) {
    4549              :                 (populate(Content{}), ...);
    4550              :         }
    4551              : };
    4552              : 
    4553              : template <typename... A, typename... B> constexpr bool collides(ctll::list<A...> rhs, ctll::list<B...> lhs) {
    4554              :         constexpr size_t capacity = calculate_size_of_first(rhs);
    4555              :         
    4556              :         point_set<capacity> set;
    4557              :         set.populate(rhs);
    4558              :         
    4559              :         return set.check(lhs);
    4560              : }
    4561              : 
    4562              : }
    4563              : 
    4564              : #endif
    4565              : 
    4566              : #ifndef CTRE_IN_A_MODULE
    4567              : #include <iterator>
    4568              : #endif
    4569              : 
    4570              : // remove me when MSVC fix the constexpr bug
    4571              : #ifdef _MSC_VER
    4572              : #ifndef CTRE_MSVC_GREEDY_WORKAROUND
    4573              : #define CTRE_MSVC_GREEDY_WORKAROUND
    4574              : #endif
    4575              : #endif
    4576              : 
    4577              : namespace ctre {
    4578              : 
    4579              : template <size_t Limit> constexpr CTRE_FORCE_INLINE bool less_than_or_infinite([[maybe_unused]] size_t i) noexcept {
    4580              :         if constexpr (Limit == 0) {
    4581              :                 // infinite
    4582            0 :                 return true;
    4583              :         } else {
    4584            0 :                 return i < Limit;
    4585              :         }
    4586              : }
    4587              : 
    4588              : template <size_t Limit> constexpr CTRE_FORCE_INLINE bool less_than([[maybe_unused]] size_t i) noexcept {
    4589              :         if constexpr (Limit == 0) {
    4590              :                 // infinite
    4591            0 :                 return false;
    4592              :         } else {
    4593            0 :                 return i < Limit;
    4594              :         }
    4595              : }
    4596              : 
    4597              : constexpr bool is_bidirectional(const std::bidirectional_iterator_tag &) { return true; }
    4598              : constexpr bool is_bidirectional(...) { return false; }
    4599              : 
    4600              : // sink for making the errors shorter
    4601              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator> 
    4602              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ...) noexcept {
    4603              :         return not_matched;
    4604              : }
    4605              : 
    4606              : // if we found "accept" object on stack => ACCEPT
    4607              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator> 
    4608              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list<accept>) noexcept {
    4609            0 :         return captures.matched();
    4610              : }
    4611              : 
    4612              : // if we found "reject" object on stack => REJECT
    4613              : template <typename R, typename... Rest, typename BeginIterator, typename Iterator, typename EndIterator> 
    4614              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list<reject, Rest...>) noexcept {
    4615              :         return not_matched;
    4616              : }
    4617              : 
    4618              : // mark start of outer capture
    4619              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4620              : 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 {
    4621            0 :         return evaluate(begin, current, last, f, captures.set_start_mark(current), ctll::list<Tail...>());
    4622              : }
    4623              : 
    4624              : // mark end of outer capture
    4625              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4626              : 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 {
    4627            0 :         return evaluate(begin, current, last, f, captures.set_end_mark(current), ctll::list<Tail...>());
    4628              : }
    4629              : 
    4630              : // mark end of cycle
    4631              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4632              : 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 {
    4633            0 :         if (cannot_be_empty_match(f)) {
    4634            0 :                 return not_matched;
    4635              :         }
    4636              :         
    4637            0 :         return captures.set_end_mark(current).matched();
    4638              : }
    4639              : 
    4640              : // matching everything which behave as a one character matcher
    4641              : 
    4642              : 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>())>)>> 
    4643              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<CharacterLike, Tail...>) noexcept {
    4644            0 :         if (current == last) return not_matched;
    4645            0 :         if (!CharacterLike::match_char(*current, f)) return not_matched;
    4646              :         
    4647            0 :         return evaluate(begin, ++current, last, consumed_something(f), captures, ctll::list<Tail...>());
    4648              : }
    4649              : 
    4650              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4651              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<any, Tail...>) noexcept {
    4652            0 :         if (current == last) return not_matched;
    4653              :         
    4654            0 :         if (multiline_mode(f)) {
    4655              :                 // TODO add support for different line ending and unicode (in a future unicode mode)
    4656            0 :                 if (*current == '\n') return not_matched;
    4657              :         }
    4658            0 :         return evaluate(begin, ++current, last, consumed_something(f), captures, ctll::list<Tail...>());
    4659              : }
    4660              : 
    4661              : // matching strings in patterns
    4662              : 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) {
    4663            0 :         return ((current != last && character<String>::match_char(*current++, f)) && ... && true);
    4664              : }
    4665              : 
    4666              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, auto... String, typename... Tail> 
    4667              : 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 {
    4668            0 :         if (!match_string<String...>(current, last, f)) {
    4669            0 :                 return not_matched;
    4670              :         }
    4671              : 
    4672            0 :         return evaluate(begin, current, last, consumed_something(f, sizeof...(String) > 0), captures, ctll::list<Tail...>());
    4673              : }
    4674              : 
    4675              : // matching select in patterns
    4676              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename HeadOptions, typename... TailOptions, typename... Tail> 
    4677              : 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 {
    4678            0 :         if (auto r = evaluate(begin, current, last, f, captures, ctll::list<HeadOptions, Tail...>())) {
    4679            0 :                 return r;
    4680              :         } else {
    4681            0 :                 return evaluate(begin, current, last, f, captures, ctll::list<select<TailOptions...>, Tail...>());
    4682              :         }
    4683              : }
    4684              : 
    4685              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4686              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list<select<>, Tail...>) noexcept {
    4687              :         // no previous option was matched => REJECT
    4688            0 :         return not_matched;
    4689              : }
    4690              : 
    4691              : // matching sequence in patterns
    4692              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename HeadContent, typename... TailContent, typename... Tail> 
    4693              : 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 {
    4694              :         if constexpr (sizeof...(TailContent) > 0) {
    4695            0 :                 return evaluate(begin, current, last, f, captures, ctll::list<HeadContent, sequence<TailContent...>, Tail...>());
    4696              :         } else {
    4697            0 :                 return evaluate(begin, current, last, f, captures, ctll::list<HeadContent, Tail...>());
    4698              :         }
    4699              : }
    4700              : 
    4701              : // matching empty in patterns
    4702              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4703              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<empty, Tail...>) noexcept {
    4704              :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4705              : }
    4706              : 
    4707              : // matching asserts
    4708              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4709              : 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 {
    4710              :         if (begin != current) {
    4711              :                 return not_matched;
    4712              :         }
    4713              :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4714              : }
    4715              : 
    4716              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4717              : 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 {
    4718            0 :         if (last != current) {
    4719            0 :                 return not_matched;
    4720              :         }
    4721            0 :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4722              : }
    4723              : 
    4724              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4725              : 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 {
    4726              :         if (multiline_mode(f)) {
    4727              :                 if (last == current) {
    4728              :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4729              :                 } else if (*current == '\n' && std::next(current) == last) {
    4730              :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4731              :                 } else {
    4732              :                         return not_matched;
    4733              :                 }
    4734              :         } else {
    4735              :                 if (last != current) {
    4736              :                         return not_matched;
    4737              :                 }
    4738              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4739              :         }
    4740              : }
    4741              : 
    4742              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4743              : 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 {
    4744              :         if (multiline_mode(f)) {
    4745              :                 if (begin == current) {
    4746              :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4747              :                 } else if (*std::prev(current) == '\n') {
    4748              :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4749              :                 } else {
    4750              :                         return not_matched;
    4751              :                 }
    4752              :         } else {
    4753              :                 if (begin != current) {
    4754              :                         return not_matched;
    4755              :                 }
    4756              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4757              :         }
    4758              : }
    4759              : 
    4760              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    4761              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<assert_line_end, Tail...>) noexcept {
    4762            0 :         if (multiline_mode(f)) {
    4763            0 :                 if (last == current) {
    4764            0 :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4765            0 :                 } else if (*current == '\n') {
    4766            0 :                         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4767              :                 } else {
    4768            0 :                         return not_matched;
    4769              :                 }
    4770              :         }
    4771              :         
    4772              :         // TODO properly match line end
    4773            0 :         if (last != current) {
    4774            0 :                 return not_matched;
    4775              :         }
    4776            0 :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4777              : }
    4778              : 
    4779              : // matching boundary
    4780              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename CharacterLike, typename... Tail> 
    4781              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<boundary<CharacterLike>, Tail...>) noexcept {
    4782              :         
    4783              :         // reason why I need bidirectional iterators or some clever hack
    4784              :         bool before = false;
    4785              :         bool after = false;
    4786              :         
    4787              :         static_assert(is_bidirectional(typename std::iterator_traits<Iterator>::iterator_category{}), "To use boundary in regex you need to provide bidirectional iterator or range.");
    4788              :         
    4789              :         if (last != current) {
    4790              :                 after = CharacterLike::match_char(*current, f);
    4791              :         }
    4792              :         if (begin != current) {
    4793              :                 before = CharacterLike::match_char(*std::prev(current), f);
    4794              :         }
    4795              :         
    4796              :         if (before == after) return not_matched;
    4797              :         
    4798              :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4799              : }
    4800              : 
    4801              : // matching not_boundary
    4802              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename CharacterLike, typename... Tail> 
    4803              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<not_boundary<CharacterLike>, Tail...>) noexcept {
    4804              :         
    4805              :         // reason why I need bidirectional iterators or some clever hack
    4806              :         bool before = false;
    4807              :         bool after = false;
    4808              :         
    4809              :         static_assert(is_bidirectional(typename std::iterator_traits<Iterator>::iterator_category{}), "To use boundary in regex you need to provide bidirectional iterator or range.");
    4810              :         
    4811              :         if (last != current) {
    4812              :                 after = CharacterLike::match_char(*current, f);
    4813              :         }
    4814              :         if (begin != current) {
    4815              :                 before = CharacterLike::match_char(*std::prev(current), f);
    4816              :         }
    4817              :         
    4818              :         if (before != after) return not_matched;
    4819              :         
    4820              :         return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    4821              : }
    4822              : 
    4823              : // lazy repeat
    4824              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> 
    4825              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list<lazy_repeat<A,B,Content...>, Tail...>) noexcept {
    4826              : 
    4827              :         if constexpr (B != 0 && A > B) {
    4828              :                 return not_matched;
    4829              :         } else {
    4830              :                 const Iterator backup_current = current;
    4831              :         
    4832              :                 size_t i{0};
    4833              :         
    4834              :                 while (less_than<A>(i)) {
    4835              :                         auto outer_result = evaluate(begin, current, last, not_empty_match(f), captures, ctll::list<Content..., end_cycle_mark>());
    4836              :                 
    4837              :                         if (!outer_result) return not_matched;
    4838              :                 
    4839              :                         captures = outer_result.unmatch();
    4840              :                         current = outer_result.get_end_position();
    4841              :                 
    4842              :                         ++i;
    4843              :                 }
    4844              :         
    4845              :                 if (auto outer_result = evaluate(begin, current, last, consumed_something(f, backup_current != current), captures, ctll::list<Tail...>())) {
    4846              :                         return outer_result;
    4847              :                 }
    4848              :         
    4849              :                 while (less_than_or_infinite<B>(i)) {
    4850              :                         auto inner_result = evaluate(begin, current, last, not_empty_match(f), captures, ctll::list<Content..., end_cycle_mark>());
    4851              :                 
    4852              :                         if (!inner_result) return not_matched;
    4853              :                 
    4854              :                         auto outer_result = evaluate(begin, inner_result.get_end_position(), last, consumed_something(f), inner_result.unmatch(), ctll::list<Tail...>());
    4855              :                 
    4856              :                         if (outer_result) {
    4857              :                                 return outer_result;
    4858              :                         }
    4859              :                 
    4860              :                         captures = inner_result.unmatch();
    4861              :                         current = inner_result.get_end_position();
    4862              :                 
    4863              :                         ++i;
    4864              :                 }
    4865              :         
    4866              :                 // rest of regex
    4867              :                 return evaluate(begin, current, last, consumed_something(f), captures, ctll::list<Tail...>());
    4868              :         }
    4869              : }
    4870              : 
    4871              : // possessive repeat
    4872              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> 
    4873              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list<possessive_repeat<A,B,Content...>, Tail...>) noexcept {
    4874              : 
    4875              :         if constexpr ((B != 0) && (A > B)) {
    4876              :                 return not_matched;
    4877              :         } else {
    4878            0 :                 const auto backup_current = current;
    4879              : 
    4880            0 :                 for (size_t i{0}; less_than_or_infinite<B>(i); ++i) {
    4881              :                         // try as many of inner as possible and then try outer once
    4882            0 :                         auto inner_result = evaluate(begin, current, last, not_empty_match(f), captures, ctll::list<Content..., end_cycle_mark>());
    4883              :                 
    4884            0 :                         if (!inner_result) {
    4885            0 :                                 if (!less_than<A>(i)) break;
    4886            0 :                                 return not_matched;
    4887              :                         }
    4888              :                 
    4889            0 :                         captures = inner_result.unmatch();
    4890            0 :                         current = inner_result.get_end_position();
    4891              :                 }
    4892              :         
    4893            0 :                 return evaluate(begin, current, last, consumed_something(f, backup_current != current), captures, ctll::list<Tail...>());
    4894              :         }
    4895              : }
    4896              : 
    4897              : // (gready) repeat
    4898              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> 
    4899              : #ifdef CTRE_MSVC_GREEDY_WORKAROUND
    4900              : constexpr inline void evaluate_recursive(R & result, size_t i, const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) noexcept {
    4901              : #else
    4902            0 : constexpr inline R evaluate_recursive(size_t i, const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) noexcept {
    4903              : #endif
    4904            0 :         if (less_than_or_infinite<B>(i)) {
    4905              :                  
    4906              :                 // a*ab
    4907              :                 // aab
    4908              :                 
    4909            0 :                 if (auto inner_result = evaluate(begin, current, last, not_empty_match(f), captures, ctll::list<Content..., end_cycle_mark>())) {
    4910              :                         // TODO MSVC issue:
    4911              :                         // if I uncomment this return it will not fail in constexpr (but the matching result will not be correct)
    4912              :                         //  return inner_result
    4913              :                         // I tried to add all constructors to R but without any success
    4914            0 :                         auto tmp_current = current;
    4915            0 :                         tmp_current = inner_result.get_end_position();
    4916              :                         #ifdef CTRE_MSVC_GREEDY_WORKAROUND
    4917              :                         evaluate_recursive(result, i+1, begin, tmp_current, last, f, inner_result.unmatch(), stack);
    4918              :                         if (result) {
    4919              :                                 return;
    4920              :                         }
    4921              :                         #else
    4922            0 :                         if (auto rec_result = evaluate_recursive(i+1, begin, tmp_current, last, f, inner_result.unmatch(), stack)) {
    4923            0 :                                 return rec_result;
    4924              :                         }
    4925              :                         #endif
    4926              :                 }
    4927              :         }
    4928              :         #ifdef CTRE_MSVC_GREEDY_WORKAROUND
    4929              :         result = evaluate(begin, current, last, consumed_something(f), captures, ctll::list<Tail...>());
    4930              :         #else
    4931            0 :         return evaluate(begin, current, last, consumed_something(f), captures, ctll::list<Tail...>());
    4932              :         #endif
    4933              : }       
    4934              : 
    4935              : // (greedy) repeat 
    4936              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> 
    4937              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, [[maybe_unused]] ctll::list<repeat<A,B,Content...>, Tail...> stack) {
    4938              : 
    4939              :         if constexpr ((B != 0) && (A > B)) {
    4940              :                 return not_matched;
    4941              :         }
    4942              : 
    4943              : #ifndef CTRE_DISABLE_GREEDY_OPT
    4944              :         else if constexpr (!collides(calculate_first(Content{}...), calculate_first(Tail{}...))) {
    4945            0 :                 return evaluate(begin, current, last, f, captures, ctll::list<possessive_repeat<A,B,Content...>, Tail...>());
    4946              :         }
    4947              : #endif
    4948              :         else {
    4949              :                 // A..B
    4950            0 :                 size_t i{0};
    4951            0 :                 while (less_than<A>(i)) {
    4952            0 :                         auto inner_result = evaluate(begin, current, last, not_empty_match(f), captures, ctll::list<Content..., end_cycle_mark>());
    4953              :                 
    4954            0 :                         if (!inner_result) return not_matched;
    4955              :                 
    4956            0 :                         captures = inner_result.unmatch();
    4957            0 :                         current = inner_result.get_end_position();
    4958              :                 
    4959            0 :                         ++i;
    4960              :                 }
    4961              :         
    4962              : #ifdef CTRE_MSVC_GREEDY_WORKAROUND
    4963              :                 R result;
    4964              :                 evaluate_recursive(result, i, begin, current, last, f, captures, stack);
    4965              :                 return result;
    4966              : #else
    4967            0 :                 return evaluate_recursive(i, begin, current, last, f, captures, stack);
    4968              : #endif
    4969              :         }
    4970              : 
    4971              : }
    4972              : 
    4973              : // capture (numeric ID)
    4974              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t Id, typename... Content, typename... Tail> 
    4975              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<capture<Id, Content...>, Tail...>) noexcept {
    4976              :         return evaluate(begin, current, last, f, captures.template start_capture<Id>(current), ctll::list<sequence<Content...>, numeric_mark<Id>, Tail...>());
    4977              : }
    4978              : 
    4979              : // capture end mark (numeric and string ID)
    4980              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t Id, typename... Tail> 
    4981              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<numeric_mark<Id>, Tail...>) noexcept {
    4982              :         return evaluate(begin, current, last, f, captures.template end_capture<Id>(current), ctll::list<Tail...>());
    4983              : }
    4984              : 
    4985              : // capture (string ID)
    4986              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, size_t Id, typename Name, typename... Content, typename... Tail> 
    4987              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<capture_with_name<Id, Name, Content...>, Tail...>) noexcept {
    4988              :         return evaluate(begin, current, last, f, captures.template start_capture<Id>(current), ctll::list<sequence<Content...>, numeric_mark<Id>, Tail...>());
    4989              : }
    4990              : 
    4991              : // backreference support (match agains content of iterators)
    4992              : template <typename Iterator> struct string_match {
    4993              :         Iterator position;
    4994              :         bool match;
    4995              : };
    4996              : 
    4997              : template <typename Iterator, typename EndIterator> constexpr CTRE_FORCE_INLINE string_match<Iterator> match_against_range(Iterator current, const EndIterator last, Iterator range_current, const Iterator range_end, flags) noexcept {
    4998              :         while (last != current && range_end != range_current) {
    4999              :                 if (*current == *range_current) {
    5000              :                         current++;
    5001              :                         range_current++;
    5002              :                 } else {
    5003              :                         return {current, false};
    5004              :                 }
    5005              :         }
    5006              :         return {current, range_current == range_end};
    5007              : }
    5008              : 
    5009              : // backreference with name
    5010              : template <typename R, typename Id, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    5011              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<back_reference_with_name<Id>, Tail...>) noexcept {
    5012              :         
    5013              :         if (const auto ref = captures.template get<Id>()) {
    5014              :                 if (auto result = match_against_range(current, last, ref.begin(), ref.end(), f); result.match) {
    5015              :                         return evaluate(begin, result.position, last, consumed_something(f, ref.begin() != ref.end()), captures, ctll::list<Tail...>());
    5016              :                 }
    5017              :         }
    5018              :         return not_matched;
    5019              : }
    5020              : 
    5021              : // backreference
    5022              : template <typename R, size_t Id, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    5023              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<back_reference<Id>, Tail...>) noexcept {
    5024              :         
    5025              :         if (const auto ref = captures.template get<Id>()) {
    5026              :                 if (auto result = match_against_range(current, last, ref.begin(), ref.end(), f); result.match) {
    5027              :                         return evaluate(begin, result.position, last, consumed_something(f, ref.begin() != ref.end()), captures, ctll::list<Tail...>());
    5028              :                 }
    5029              :         }
    5030              :         return not_matched;
    5031              : }
    5032              : 
    5033              : // end of lookahead
    5034              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    5035              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list<end_lookahead_mark>) noexcept {
    5036              :         // TODO check interaction with non-empty flag
    5037              :         return captures.matched();
    5038              : }
    5039              : 
    5040              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Tail> 
    5041              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list<end_lookbehind_mark>) noexcept {
    5042              :         // TODO check interaction with non-empty flag
    5043              :         return captures.matched();
    5044              : }
    5045              : 
    5046              : // lookahead positive
    5047              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail> 
    5048              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<lookahead_positive<Content...>, Tail...>) noexcept {
    5049              :         
    5050              :         if (auto lookahead_result = evaluate(begin, current, last, f, captures, ctll::list<sequence<Content...>, end_lookahead_mark>())) {
    5051              :                 captures = lookahead_result.unmatch();
    5052              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    5053              :         } else {
    5054              :                 return not_matched;
    5055              :         }
    5056              : }
    5057              : 
    5058              : // lookahead negative
    5059              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail> 
    5060              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<lookahead_negative<Content...>, Tail...>) noexcept {
    5061              :         
    5062              :         if (auto lookahead_result = evaluate(begin, current, last, f, captures, ctll::list<sequence<Content...>, end_lookahead_mark>())) {
    5063              :                 return not_matched;
    5064              :         } else {
    5065              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    5066              :         }
    5067              : }
    5068              : 
    5069              : // lookbehind positive
    5070              : constexpr bool is_at_least_bidirectional(std::input_iterator_tag) {
    5071              :         return false;
    5072              : }
    5073              : 
    5074              : constexpr bool is_at_least_bidirectional(std::bidirectional_iterator_tag) {
    5075              :         return true;
    5076              : }
    5077              : 
    5078              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail> 
    5079              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<lookbehind_positive<Content...>, Tail...>) noexcept {
    5080              :         static_assert(is_at_least_bidirectional(typename std::iterator_traits<Iterator>::iterator_category{}), "to use lookbehind you must provide bi-directional iterator");
    5081              :         
    5082              :         if (auto lookbehind_result = evaluate(std::make_reverse_iterator(last), std::make_reverse_iterator(current), std::make_reverse_iterator(begin), f, captures, ctll::list<sequence<Content...>, end_lookbehind_mark>())) {
    5083              :                 captures = lookbehind_result.unmatch();
    5084              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    5085              :         } else {
    5086              :                 return not_matched;
    5087              :         }
    5088              : }
    5089              : 
    5090              : // lookbehind negative
    5091              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail> 
    5092              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<lookbehind_negative<Content...>, Tail...>) noexcept {
    5093              :         static_assert(is_at_least_bidirectional(typename std::iterator_traits<Iterator>::iterator_category{}), "to use negative lookbehind you must provide bi-directional iterator");
    5094              :         
    5095              :         if (auto lookbehind_result = evaluate(std::make_reverse_iterator(last), std::make_reverse_iterator(current), std::make_reverse_iterator(begin), f, captures, ctll::list<sequence<Content...>, end_lookbehind_mark>())) {
    5096              :                 return not_matched;
    5097              :         } else {
    5098              :                 return evaluate(begin, current, last, f, captures, ctll::list<Tail...>());
    5099              :         }
    5100              : }
    5101              : 
    5102              : template <typename...> constexpr auto dependent_false = false;
    5103              : 
    5104              : // atomic_group<...> is just transformation to possessive_repeat<1,1,...>
    5105              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail> 
    5106              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<atomic_group<Content...>, Tail...>) noexcept {
    5107              :         return evaluate(begin, current, last, f, captures, ctll::list<possessive_repeat<1,1,Content...>, Tail...>{});
    5108              : }
    5109              : 
    5110              : // switching modes
    5111              : template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename Mode, typename... Tail> 
    5112              : constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<mode_switch<Mode>, Tail...>) noexcept {
    5113              :         return evaluate(begin, current, last, f + Mode{}, captures, ctll::list<Tail...>());
    5114              : }
    5115              : 
    5116              : }
    5117              : 
    5118              : #endif
    5119              : 
    5120              : #ifndef CTRE__WRAPPER__HPP
    5121              : #define CTRE__WRAPPER__HPP
    5122              : 
    5123              : #ifndef CTRE_V2__CTRE__RANGE__HPP
    5124              : #define CTRE_V2__CTRE__RANGE__HPP
    5125              : 
    5126              : #ifndef CTRE_V2__CTRE__ITERATOR__HPP
    5127              : #define CTRE_V2__CTRE__ITERATOR__HPP
    5128              : 
    5129              : #ifndef CTRE_IN_A_MODULE
    5130              : #include <cstddef>
    5131              : #endif
    5132              : 
    5133              : namespace ctre {
    5134              : 
    5135              : // TODO make proper iterator traits here
    5136              : 
    5137              : struct regex_end_iterator {
    5138              :         constexpr regex_end_iterator() noexcept { }
    5139              : };
    5140              : 
    5141              : template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_iterator {
    5142              :         using value_type = decltype(RE::template exec_with_result_iterator<ResultIterator>(std::declval<BeginIterator>(), std::declval<EndIterator>()));
    5143              :         using iterator_category = std::forward_iterator_tag;
    5144              :         using pointer = void;
    5145              :         using reference = const value_type &;
    5146              :         using difference_type = int;
    5147              :         
    5148              :         BeginIterator orig_begin{};
    5149              :         BeginIterator current{};
    5150              :         EndIterator end{};
    5151              :         value_type current_match{};
    5152              :         
    5153              :         constexpr CTRE_FORCE_INLINE regex_iterator() noexcept = default;
    5154              :         constexpr CTRE_FORCE_INLINE regex_iterator(const regex_iterator &) noexcept = default;
    5155              :         constexpr CTRE_FORCE_INLINE regex_iterator(regex_iterator &&) noexcept = default;
    5156              : 
    5157              :         constexpr CTRE_FORCE_INLINE regex_iterator(BeginIterator begin, EndIterator last) noexcept: orig_begin{begin}, current{begin}, end{last}, current_match{RE::template exec_with_result_iterator<ResultIterator>(current, last)} {
    5158              :                 if (current_match) {
    5159              :                         current = current_match.template get<0>().end();
    5160              :                 }
    5161              :         }
    5162              :         
    5163              :         constexpr CTRE_FORCE_INLINE regex_iterator & operator=(const regex_iterator &) noexcept = default;
    5164              :         constexpr CTRE_FORCE_INLINE regex_iterator & operator=(regex_iterator &&) noexcept = default;
    5165              :         
    5166              :         constexpr CTRE_FORCE_INLINE const value_type & operator*() const noexcept {
    5167              :                 return current_match;
    5168              :         }
    5169              :         constexpr CTRE_FORCE_INLINE regex_iterator & operator++() noexcept {
    5170              :                 if (current == end) {
    5171              :                         current_match = decltype(current_match){};
    5172              :                         return *this;
    5173              :                 }
    5174              :                 
    5175              :                 current_match = RE::template exec_with_result_iterator<ResultIterator>(orig_begin, current, end);
    5176              :                 
    5177              :                 if (current_match) {
    5178              :                         current = current_match.template get<0>().end();
    5179              :                 }
    5180              :                 return *this;
    5181              :         }
    5182              :         constexpr CTRE_FORCE_INLINE regex_iterator operator++(int) noexcept {
    5183              :                 auto previous = *this;
    5184              :                 this->operator++();
    5185              :                 return previous;
    5186              :         }
    5187              :         friend constexpr CTRE_FORCE_INLINE bool operator==(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5188              :                 return left.current == right.current;
    5189              :         }
    5190              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5191              :                 return !(left.current == right.current);
    5192              :         }
    5193              :         friend constexpr CTRE_FORCE_INLINE bool operator<(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5194              :                 return left.current < right.current;
    5195              :         }
    5196              :         friend constexpr CTRE_FORCE_INLINE bool operator>(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5197              :                 return left.current > right.current;
    5198              :         }
    5199              :         friend constexpr CTRE_FORCE_INLINE bool operator<=(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5200              :                 return left.current <= right.current;
    5201              :         }
    5202              :         friend constexpr CTRE_FORCE_INLINE bool operator>=(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5203              :                 return left.current >= right.current;
    5204              :         }
    5205              :         friend constexpr CTRE_FORCE_INLINE bool operator==(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, regex_end_iterator) noexcept {
    5206              :                 return !bool(left.current_match);
    5207              :         }
    5208              :         friend constexpr CTRE_FORCE_INLINE bool operator==(regex_end_iterator, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5209              :                 return !bool(right.current_match);
    5210              :         }
    5211              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, regex_end_iterator) noexcept {
    5212              :                 return bool(left.current_match);
    5213              :         }
    5214              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(regex_end_iterator, const regex_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5215              :                 return bool(right.current_match);
    5216              :         }
    5217              : };
    5218              : 
    5219              : template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_split_iterator {
    5220              :         using value_type = decltype(RE::template exec_with_result_iterator<ResultIterator>(std::declval<BeginIterator>(), std::declval<EndIterator>()));
    5221              :         using iterator_category = std::forward_iterator_tag;
    5222              :         using pointer = void;
    5223              :         using reference = const value_type &;
    5224              :         using difference_type = int;
    5225              : 
    5226              :         BeginIterator orig_begin{};
    5227              :         BeginIterator current{};
    5228              :         EndIterator end{};
    5229              :         value_type current_match{};
    5230              :         bool last_match{false};
    5231              : 
    5232              :         constexpr CTRE_FORCE_INLINE void modify_match() {
    5233              :                 auto tmp = current_match.template get<0>().end();
    5234              :                 current_match.set_end_mark(current_match.template get<0>().begin());
    5235              :                 current_match.set_start_mark(current);
    5236              :                 current = tmp;
    5237              :         }
    5238              :         
    5239              :         constexpr CTRE_FORCE_INLINE void match_rest() {
    5240              :                 // the end is there set by search_method
    5241              :                 current_match.set_start_mark(current);
    5242              :                 current_match.matched();
    5243              :                 current = current_match.template get<0>().end();
    5244              :                 last_match = true;
    5245              :         }
    5246              : 
    5247              :         constexpr CTRE_FORCE_INLINE regex_split_iterator() noexcept = default;
    5248              :         constexpr CTRE_FORCE_INLINE regex_split_iterator(const regex_split_iterator &) noexcept = default;
    5249              :         constexpr CTRE_FORCE_INLINE regex_split_iterator(regex_split_iterator &&) noexcept = default;
    5250              : 
    5251              :         constexpr CTRE_FORCE_INLINE regex_split_iterator(BeginIterator begin, EndIterator last) noexcept: orig_begin{begin}, current{begin}, end{last}, current_match{RE::template exec_with_result_iterator<ResultIterator>(current, last)} {
    5252              :                 if (current_match) {
    5253              :                         modify_match();
    5254              :                 } else {
    5255              :                         match_rest();
    5256              :                 }
    5257              :         }
    5258              :         
    5259              :         constexpr CTRE_FORCE_INLINE regex_split_iterator & operator=(const regex_split_iterator &) noexcept = default;
    5260              :         constexpr CTRE_FORCE_INLINE regex_split_iterator & operator=(regex_split_iterator &&) noexcept = default;
    5261              :         
    5262              :         constexpr CTRE_FORCE_INLINE const value_type & operator*() const noexcept {
    5263              :                 return current_match;
    5264              :         }
    5265              :         constexpr CTRE_FORCE_INLINE regex_split_iterator & operator++() noexcept {
    5266              :                 if (current == end && last_match) {
    5267              :                         current_match = decltype(current_match){};
    5268              :                         return *this;
    5269              :                 }
    5270              :         
    5271              :                 current_match = RE::template exec_with_result_iterator<ResultIterator>(orig_begin, current, end);
    5272              :         
    5273              :                 if (current_match) {
    5274              :                         modify_match();
    5275              :                 } else {
    5276              :                         match_rest();
    5277              :                 }
    5278              :                 return *this;
    5279              :         }
    5280              :         constexpr CTRE_FORCE_INLINE regex_split_iterator operator++(int) noexcept {
    5281              :                 auto previous = *this;
    5282              :                 this->operator++();
    5283              :                 return previous;
    5284              :         }
    5285              :         friend constexpr CTRE_FORCE_INLINE bool operator==(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5286              :                 return left.current == right.current;
    5287              :         }
    5288              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5289              :                 return !(left.current == right.current);
    5290              :         }
    5291              :         friend constexpr CTRE_FORCE_INLINE bool operator<(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5292              :                 return left.current < right.current;
    5293              :         }
    5294              :         friend constexpr CTRE_FORCE_INLINE bool operator>(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5295              :                 return left.current > right.current;
    5296              :         }
    5297              :         friend constexpr CTRE_FORCE_INLINE bool operator<=(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5298              :                 return left.current <= right.current;
    5299              :         }
    5300              :         friend constexpr CTRE_FORCE_INLINE bool operator>=(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5301              :                 return left.current >= right.current;
    5302              :         }
    5303              :         friend constexpr CTRE_FORCE_INLINE bool operator==(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, regex_end_iterator) noexcept {
    5304              :                 return !bool(left.current_match);
    5305              :         }
    5306              :         friend constexpr CTRE_FORCE_INLINE bool operator==(regex_end_iterator, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5307              :                 return !bool(right.current_match);
    5308              :         }
    5309              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & left, regex_end_iterator) noexcept {
    5310              :                 return bool(left.current_match);
    5311              :         }
    5312              :         friend constexpr CTRE_FORCE_INLINE bool operator!=(regex_end_iterator, const regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator> & right) noexcept {
    5313              :                 return bool(right.current_match);
    5314              :         }
    5315              : };
    5316              : 
    5317              : } // ctre
    5318              : 
    5319              : #endif
    5320              : 
    5321              : namespace ctre {
    5322              : 
    5323              : template <typename> constexpr bool is_range = false;
    5324              : 
    5325              : template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_range {
    5326              :         BeginIterator _begin;
    5327              :         EndIterator _end;
    5328              :         
    5329              :         constexpr CTRE_FORCE_INLINE regex_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
    5330              :         
    5331              :         constexpr CTRE_FORCE_INLINE auto begin() const noexcept {
    5332              :                 return regex_iterator<BeginIterator, EndIterator, RE, ResultIterator>(_begin, _end);
    5333              :         }
    5334              :         constexpr CTRE_FORCE_INLINE auto end() const noexcept {
    5335              :                 return regex_end_iterator{};
    5336              :         }
    5337              : };
    5338              : 
    5339              : template <typename... Ts> constexpr bool is_range<regex_range<Ts...>> = true;
    5340              : 
    5341              : template <typename BeginIterator, typename EndIterator, typename RE, typename ResultIterator = BeginIterator> struct regex_split_range {
    5342              :         BeginIterator _begin;
    5343              :         EndIterator _end;
    5344              :         
    5345              :         constexpr CTRE_FORCE_INLINE regex_split_range(BeginIterator begin, EndIterator end) noexcept: _begin{begin}, _end{end} { }
    5346              :         
    5347              :         constexpr CTRE_FORCE_INLINE auto begin() const noexcept {
    5348              :                 return regex_split_iterator<BeginIterator, EndIterator, RE, ResultIterator>(_begin, _end);
    5349              :         }
    5350              :         constexpr CTRE_FORCE_INLINE auto end() const noexcept {
    5351              :                 return regex_end_iterator{};
    5352              :         }
    5353              : };
    5354              : 
    5355              : template <typename... Ts> constexpr bool is_range<regex_split_range<Ts...>> = true;
    5356              : 
    5357              : template <typename Range, typename RE> struct multi_subject_range {
    5358              :         struct end_iterator { };
    5359              :         
    5360              :         using first_type = decltype(std::declval<Range>().begin());
    5361              :         using last_type = decltype(std::declval<Range>().end());
    5362              :         
    5363              :         struct iterator {
    5364              :                 using value_type = decltype(RE::exec(std::declval<typename std::iterator_traits<first_type>::value_type>()));
    5365              :                 using iterator_category = std::forward_iterator_tag;
    5366              :                 using reference = const value_type &;
    5367              :                 using pointer = const value_type *;
    5368              :                 using difference_type = int;
    5369              :                 
    5370              :                 first_type first{};
    5371              :                 last_type last{};
    5372              :                 value_type current_result{};
    5373              :                 
    5374              :                 constexpr CTRE_FORCE_INLINE iterator() noexcept = default;
    5375              :                 constexpr CTRE_FORCE_INLINE iterator(first_type f, last_type l) noexcept: first{f}, last{l}, current_result{find_first()} { }
    5376              :                 
    5377              :                 constexpr CTRE_FORCE_INLINE value_type find_first() noexcept {
    5378              :                         while (first != last) {
    5379              :                                 if (auto res = RE::exec(*first)) return res;
    5380              :                                 else ++first;
    5381              :                         }
    5382              :                         return {};
    5383              :                 }
    5384              :                 
    5385              :                 constexpr CTRE_FORCE_INLINE reference operator*() const noexcept {
    5386              :                         return current_result;
    5387              :                 }
    5388              :                 
    5389              :                 constexpr CTRE_FORCE_INLINE pointer operator->() const noexcept {
    5390              :                         return &current_result;
    5391              :                 }
    5392              :                 
    5393              :                 constexpr CTRE_FORCE_INLINE iterator & operator++() noexcept {
    5394              :                         ++first;
    5395              :                         current_result = find_first();
    5396              :                         return *this;
    5397              :                 }
    5398              :                 constexpr CTRE_FORCE_INLINE iterator operator++(int) noexcept {
    5399              :                         auto previous = *this;
    5400              :                         this->operator++();
    5401              :                         return previous;
    5402              :                 }
    5403              :                 
    5404              :                 friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, const iterator & right) noexcept {
    5405              :                         return left.first == right.first;
    5406              :                 }
    5407              :                 friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, const iterator & right) noexcept {
    5408              :                         return !(left.first == right.first);
    5409              :                 }
    5410              :                 friend constexpr CTRE_FORCE_INLINE bool operator<(const iterator & left, const iterator & right) noexcept {
    5411              :                         return left.first < right.first;
    5412              :                 }
    5413              :                 friend constexpr CTRE_FORCE_INLINE bool operator>(const iterator & left, const iterator & right) noexcept {
    5414              :                         return left.first > right.first;
    5415              :                 }
    5416              :                 friend constexpr CTRE_FORCE_INLINE bool operator<=(const iterator & left, const iterator & right) noexcept {
    5417              :                         return left.first <= right.first;
    5418              :                 }
    5419              :                 friend constexpr CTRE_FORCE_INLINE bool operator>=(const iterator & left, const iterator & right) noexcept {
    5420              :                         return left.first >= right.first;
    5421              :                 }
    5422              :                 friend constexpr CTRE_FORCE_INLINE bool operator==(const iterator & left, end_iterator) noexcept {
    5423              :                         return left.first == left.last;
    5424              :                 }
    5425              :                 friend constexpr CTRE_FORCE_INLINE bool operator==(end_iterator, const iterator & right) noexcept {
    5426              :                         return right.first == right.last;
    5427              :                 }
    5428              :                 friend constexpr CTRE_FORCE_INLINE bool operator!=(const iterator & left, end_iterator) noexcept {
    5429              :                         return left.first != left.last;
    5430              :                 }
    5431              :                 friend constexpr CTRE_FORCE_INLINE bool operator!=(end_iterator, const iterator & right) noexcept {
    5432              :                         return right.first == right.last;
    5433              :                 }
    5434              :         };
    5435              :         
    5436              :         Range range{};
    5437              :         
    5438              :         constexpr CTRE_FORCE_INLINE multi_subject_range() noexcept = default;
    5439              :         constexpr CTRE_FORCE_INLINE multi_subject_range(Range r) noexcept: range{r} { }
    5440              :         
    5441              :         constexpr CTRE_FORCE_INLINE auto begin() const noexcept {
    5442              :                 return iterator{range.begin(), range.end()};
    5443              :         }
    5444              :         constexpr CTRE_FORCE_INLINE auto end() const noexcept {
    5445              :                 return end_iterator{};
    5446              :         }
    5447              : };
    5448              : 
    5449              : // this is not regex range!
    5450              : template <typename... Ts> constexpr bool is_range<multi_subject_range<Ts...>> = true;
    5451              : 
    5452              : }
    5453              : 
    5454              : #if defined __cpp_lib_ranges && __cpp_lib_ranges >= 201911
    5455              : namespace std::ranges {
    5456              : 
    5457              :         template <typename... Ts> inline constexpr bool enable_borrowed_range<::ctre::regex_range<Ts...>> = true;
    5458              :         template <typename... Ts> inline constexpr bool enable_borrowed_range<::ctre::regex_split_range<Ts...>> = true;
    5459              :         template <typename Range, typename RE> inline constexpr bool enable_borrowed_range<::ctre::multi_subject_range<Range, RE>> = enable_borrowed_range<Range>;
    5460              :         template <typename Range, typename RE> inline constexpr bool enable_view<::ctre::multi_subject_range<Range, RE>> = true;
    5461              : 
    5462              : }
    5463              : #endif 
    5464              : 
    5465              : #endif
    5466              : 
    5467              : #ifndef CTRE_IN_A_MODULE
    5468              : #include <string_view>
    5469              : #endif
    5470              : 
    5471              : namespace ctre {
    5472              : 
    5473              : CTRE_EXPORT template <typename RE, typename Method = void, typename Modifier = singleline> struct regular_expression;
    5474              : 
    5475              : struct zero_terminated_string_end_iterator {
    5476              :         // this is here only because I want to support std::make_reverse_iterator
    5477              :         using self_type = zero_terminated_string_end_iterator;
    5478              :         using value_type = char;
    5479              :         using reference = char &;
    5480              :         using pointer = const char *;
    5481              :         using iterator_category = std::bidirectional_iterator_tag;
    5482              :         using difference_type = int;
    5483              : 
    5484              :         // it's just sentinel it won't be ever called
    5485              :         auto operator++() noexcept -> self_type &;
    5486              :         auto operator++(int) noexcept -> self_type;
    5487              :         auto operator--() noexcept -> self_type &;
    5488              :         auto operator--(int) noexcept -> self_type;
    5489              :         friend auto operator==(self_type, self_type) noexcept -> bool;
    5490              :         auto operator*() noexcept -> reference;
    5491              : 
    5492              :         constexpr CTRE_FORCE_INLINE friend bool operator==(const char * ptr, zero_terminated_string_end_iterator) noexcept {
    5493            0 :                 return *ptr == '\0';
    5494              :         }
    5495              :         constexpr CTRE_FORCE_INLINE friend bool operator==(const wchar_t * ptr, zero_terminated_string_end_iterator) noexcept {
    5496              :                 return *ptr == 0;
    5497              :         }
    5498              :         constexpr CTRE_FORCE_INLINE friend bool operator!=(const char * ptr, zero_terminated_string_end_iterator) noexcept {
    5499            0 :                 return *ptr != '\0';
    5500              :         }
    5501              :         constexpr CTRE_FORCE_INLINE friend bool operator!=(const wchar_t * ptr, zero_terminated_string_end_iterator) noexcept {
    5502              :                 return *ptr != 0;
    5503              :         }
    5504              :         constexpr CTRE_FORCE_INLINE friend bool operator==(zero_terminated_string_end_iterator, const char * ptr) noexcept {
    5505            0 :                 return *ptr == '\0';
    5506              :         }
    5507              :         constexpr CTRE_FORCE_INLINE friend bool operator==(zero_terminated_string_end_iterator, const wchar_t * ptr) noexcept {
    5508              :                 return *ptr == 0;
    5509              :         }
    5510              :         constexpr CTRE_FORCE_INLINE friend bool operator!=(zero_terminated_string_end_iterator, const char * ptr) noexcept {
    5511            0 :                 return *ptr != '\0';
    5512              :         }
    5513              :         constexpr CTRE_FORCE_INLINE friend bool operator!=(zero_terminated_string_end_iterator, const wchar_t * ptr) noexcept {
    5514              :                 return *ptr != 0;
    5515              :         }
    5516              : };
    5517              : 
    5518              : template <typename T> class RangeLikeType {
    5519              :         template <typename Y> static auto test(Y *) -> decltype(std::declval<const Y &>().begin(), std::declval<const Y &>().end(), std::true_type());
    5520              :         template <typename> static auto test(...) -> std::false_type;
    5521              : 
    5522              : public:
    5523              :         static constexpr bool value = decltype(test<std::remove_reference_t<std::remove_const_t<T>>>(nullptr))::value;
    5524              : };
    5525              : 
    5526              : struct match_method {
    5527              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin orig_begin, IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5528              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5529              : 
    5530            0 :                 return evaluate(orig_begin, begin, end, Modifier{}, return_type<result_iterator, RE>{}, ctll::list<start_mark, RE, assert_subject_end, end_mark, accept>());
    5531              :         }
    5532              : 
    5533              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5534            0 :                 return exec<Modifier, ResultIterator>(begin, begin, end, RE{});
    5535              :         }
    5536              : };
    5537              : 
    5538              : struct search_method {
    5539              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin orig_begin, IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5540              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5541              : 
    5542            0 :                 constexpr bool fixed = starts_with_anchor(Modifier{}, ctll::list<RE>{});
    5543              : 
    5544            0 :                 auto it = begin;
    5545              : 
    5546            0 :                 for (; end != it && !fixed; ++it) {
    5547            0 :                         if (auto out = evaluate(orig_begin, it, end, Modifier{}, return_type<result_iterator, RE>{}, ctll::list<start_mark, RE, end_mark, accept>())) {
    5548            0 :                                 return out;
    5549              :                         }
    5550              :                 }
    5551              : 
    5552              :                 // in case the RE is empty or fixed
    5553            0 :                 auto out = evaluate(orig_begin, it, end, Modifier{}, return_type<result_iterator, RE>{}, ctll::list<start_mark, RE, end_mark, accept>());
    5554              : 
    5555              :                 // ALERT: ugly hack
    5556              :                 // propagate end even if it didn't match (this is needed for split function)
    5557            0 :                 if (!out) out.set_end_mark(it);
    5558            0 :                 return out;
    5559              :         }
    5560              : 
    5561              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5562            0 :                 return exec<Modifier, ResultIterator>(begin, begin, end, RE{});
    5563              :         }
    5564              : };
    5565              : 
    5566              : struct starts_with_method {
    5567              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin orig_begin, IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5568              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5569              :                 return evaluate(orig_begin, begin, end, Modifier{}, return_type<result_iterator, RE>{}, ctll::list<start_mark, RE, end_mark, accept>());
    5570              :         }
    5571              : 
    5572              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5573              :                 return exec<Modifier, ResultIterator>(begin, begin, end, RE{});
    5574              :         }
    5575              : };
    5576              : 
    5577              : // wrapper which calls search on input
    5578              : struct range_method {
    5579              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5580              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5581              :                 using wrapped_regex = regular_expression<RE, search_method, Modifier>;
    5582              : 
    5583              :                 return regex_range<IteratorBegin, IteratorEnd, wrapped_regex, result_iterator>(begin, end);
    5584              :         }
    5585              : };
    5586              : 
    5587              : struct tokenize_method {
    5588              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5589              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5590              :                 using wrapped_regex = regular_expression<RE, starts_with_method, Modifier>;
    5591              : 
    5592              :                 return regex_range<IteratorBegin, IteratorEnd, wrapped_regex, result_iterator>(begin, end);
    5593              :         }
    5594              : };
    5595              : 
    5596              : struct split_method {
    5597              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5598              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5599              :                 using wrapped_regex = regular_expression<RE, search_method, Modifier>;
    5600              : 
    5601              :                 return regex_split_range<IteratorBegin, IteratorEnd, wrapped_regex, result_iterator>(begin, end);
    5602              :         }
    5603              : };
    5604              : 
    5605              : struct iterator_method {
    5606              :         template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end, RE) noexcept {
    5607              :                 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
    5608              :                 using wrapped_regex = regular_expression<RE, search_method, Modifier>;
    5609              : 
    5610              :                 return regex_iterator<IteratorBegin, IteratorEnd, wrapped_regex, result_iterator>(begin, end);
    5611              :         }
    5612              :         constexpr CTRE_FORCE_INLINE static auto exec() noexcept {
    5613              :                 return regex_end_iterator{};
    5614              :         }
    5615              : };
    5616              : 
    5617              : CTRE_EXPORT template <typename RE, typename Method, typename Modifier> struct regular_expression {
    5618              :         constexpr CTRE_FORCE_INLINE regular_expression() noexcept { }
    5619              :         constexpr CTRE_FORCE_INLINE regular_expression(RE) noexcept { }
    5620              : 
    5621              :         template <typename ResultIterator, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec_with_result_iterator(IteratorBegin orig_begin, IteratorBegin begin, IteratorEnd end) noexcept {
    5622              :                 return Method::template exec<Modifier, ResultIterator>(orig_begin, begin, end, RE{});
    5623              :         }
    5624              :         template <typename ResultIterator, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec_with_result_iterator(IteratorBegin begin, IteratorEnd end) noexcept {
    5625              :                 return Method::template exec<Modifier, ResultIterator>(begin, end, RE{});
    5626              :         }
    5627              :         template <typename Range> constexpr CTRE_FORCE_INLINE static auto multi_exec(Range && range) noexcept {
    5628              :                 return multi_subject_range<Range, regular_expression>{std::forward<Range>(range)};
    5629              :         }
    5630              :         constexpr CTRE_FORCE_INLINE static auto exec() noexcept {
    5631              :                 return Method::exec();
    5632              :         }
    5633              :         template <typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin begin, IteratorEnd end) noexcept {
    5634            0 :                 return Method::template exec<Modifier>(begin, end, RE{});
    5635              :         }
    5636              :         static constexpr CTRE_FORCE_INLINE auto exec(const char * s) noexcept {
    5637            0 :                 return Method::template exec<Modifier>(s, zero_terminated_string_end_iterator(), RE{});
    5638              :         }
    5639              :         static constexpr CTRE_FORCE_INLINE auto exec(const wchar_t * s) noexcept {
    5640              :                 return Method::template exec<Modifier>(s, zero_terminated_string_end_iterator(), RE{});
    5641              :         }
    5642              :         static constexpr CTRE_FORCE_INLINE auto exec(std::string_view sv) noexcept {
    5643              :                 return exec(sv.begin(), sv.end());
    5644              :         }
    5645              :         static constexpr CTRE_FORCE_INLINE auto exec(std::wstring_view sv) noexcept {
    5646              :                 return exec(sv.begin(), sv.end());
    5647              :         }
    5648              : #ifdef CTRE_ENABLE_UTF8_RANGE
    5649              :         static constexpr CTRE_FORCE_INLINE auto exec(std::u8string_view sv) noexcept {
    5650              :                 return exec_with_result_iterator<const char8_t *>(utf8_range(sv).begin(), utf8_range(sv).end());
    5651              :         }
    5652              : #endif
    5653              :         static constexpr CTRE_FORCE_INLINE auto exec(std::u16string_view sv) noexcept {
    5654              :                 return exec(sv.begin(), sv.end());
    5655              :         }
    5656              :         static constexpr CTRE_FORCE_INLINE auto exec(std::u32string_view sv) noexcept {
    5657              :                 return exec(sv.begin(), sv.end());
    5658              :         }
    5659              :         template <typename Range, typename = typename std::enable_if<RangeLikeType<Range>::value>::type> static constexpr CTRE_FORCE_INLINE auto exec(Range && range) noexcept {
    5660            0 :                 return exec(std::begin(range), std::end(range));
    5661              :         }
    5662              : 
    5663              :         // another api
    5664              :         template <typename... Args> CTRE_FORCE_INLINE constexpr auto operator()(Args &&... args) const noexcept {
    5665            0 :                 return exec(std::forward<Args>(args)...);
    5666              :         }
    5667              :         // api for pattern matching
    5668              :         template <typename... Args> CTRE_FORCE_INLINE constexpr auto try_extract(Args &&... args) const noexcept {
    5669              :                 return exec(std::forward<Args>(args)...);
    5670              :         }
    5671              : 
    5672              :         // for compatibility with _ctre literal
    5673              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto match(Args &&... args) noexcept {
    5674              :                 return regular_expression<RE, match_method, singleline>::exec(std::forward<Args>(args)...);
    5675              :         }
    5676              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto search(Args &&... args) noexcept {
    5677              :                 return regular_expression<RE, search_method, singleline>::exec(std::forward<Args>(args)...);
    5678              :         }
    5679              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto starts_with(Args &&... args) noexcept {
    5680              :                 return regular_expression<RE, starts_with_method, singleline>::exec(std::forward<Args>(args)...);
    5681              :         }
    5682              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto range(Args &&... args) noexcept {
    5683              :                 return regular_expression<RE, range_method, singleline>::exec(std::forward<Args>(args)...);
    5684              :         }
    5685              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto split(Args &&... args) noexcept {
    5686              :                 return regular_expression<RE, split_method, singleline>::exec(std::forward<Args>(args)...);
    5687              :         }
    5688              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto tokenize(Args &&... args) noexcept {
    5689              :                 return regular_expression<RE, tokenize_method, singleline>::exec(std::forward<Args>(args)...);
    5690              :         }
    5691              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto iterator(Args &&... args) noexcept {
    5692              :                 return regular_expression<RE, iterator_method, singleline>::exec(std::forward<Args>(args)...);
    5693              :         }
    5694              : 
    5695              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_match(Args &&... args) noexcept {
    5696              :                 return regular_expression<RE, match_method, multiline>::exec(std::forward<Args>(args)...);
    5697              :         }
    5698              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_search(Args &&... args) noexcept {
    5699              :                 return regular_expression<RE, search_method, multiline>::exec(std::forward<Args>(args)...);
    5700              :         }
    5701              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_starts_with(Args &&... args) noexcept {
    5702              :                 return regular_expression<RE, starts_with_method, multiline>::exec(std::forward<Args>(args)...);
    5703              :         }
    5704              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_range(Args &&... args) noexcept {
    5705              :                 return regular_expression<RE, range_method, multiline>::exec(std::forward<Args>(args)...);
    5706              :         }
    5707              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_split(Args &&... args) noexcept {
    5708              :                 return regular_expression<RE, split_method, multiline>::exec(std::forward<Args>(args)...);
    5709              :         }
    5710              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_tokenize(Args &&... args) noexcept {
    5711              :                 return regular_expression<RE, tokenize_method, multiline>::exec(std::forward<Args>(args)...);
    5712              :         }
    5713              :         template <typename... Args> static constexpr CTRE_FORCE_INLINE auto multiline_iterator(Args &&... args) noexcept {
    5714              :                 return regular_expression<RE, iterator_method, multiline>::exec(std::forward<Args>(args)...);
    5715              :         }
    5716              : };
    5717              : 
    5718              : // range style API support for tokenize/range/split operations
    5719              : template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, range_method, Modifier> re) noexcept {
    5720              :         return re.exec(std::forward<Range>(range));
    5721              : }
    5722              : 
    5723              : template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, tokenize_method, Modifier> re) noexcept {
    5724              :         return re.exec(std::forward<Range>(range));
    5725              : }
    5726              : 
    5727              : template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, split_method, Modifier> re) noexcept {
    5728              :         return re.exec(std::forward<Range>(range));
    5729              : }
    5730              : 
    5731              : template <typename Range, typename RE, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, iterator_method, Modifier> re) noexcept = delete;
    5732              : 
    5733              : template <typename Range, typename RE, typename Method, typename Modifier> constexpr auto operator|(Range && range, regular_expression<RE, Method, Modifier> re) noexcept {
    5734              :         return re.multi_exec(std::forward<Range>(range));
    5735              : }
    5736              : 
    5737              : // error reporting of problematic position in a regex
    5738              : template <size_t> struct problem_at_position; // do not define!
    5739              : 
    5740              : template <> struct problem_at_position<~static_cast<size_t>(0)> {
    5741              :         constexpr operator bool() const noexcept {
    5742              :                 return true;
    5743              :         }
    5744              : };
    5745              : 
    5746              : #if CTRE_CNTTP_COMPILER_CHECK
    5747              : #define CTRE_REGEX_INPUT_TYPE ctll::fixed_string
    5748              : #define CTRE_REGEX_TEMPLATE_COPY_TYPE auto
    5749              : #else
    5750              : #define CTRE_REGEX_INPUT_TYPE const auto &
    5751              : #define CTRE_REGEX_TEMPLATE_COPY_TYPE const auto &
    5752              : #endif
    5753              : 
    5754              : template <CTRE_REGEX_TEMPLATE_COPY_TYPE input> struct regex_builder {
    5755              :         static constexpr auto _input = input;
    5756              :         using result = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
    5757              : 
    5758              :         static constexpr auto n = result::is_correct ? ~static_cast<size_t>(0) : result::position;
    5759              : 
    5760              :         static_assert(result::is_correct && problem_at_position<n>{}, "Regular Expression contains syntax error.");
    5761              : 
    5762              :         using type = ctll::conditional<result::is_correct, decltype(ctll::front(typename result::output_type::stack_type())), ctll::list<reject>>;
    5763              : };
    5764              : 
    5765              : // case-sensitive
    5766              : 
    5767              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto match = regular_expression<typename regex_builder<input>::type, match_method, ctll::list<singleline, Modifiers...>>();
    5768              : 
    5769              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto search = regular_expression<typename regex_builder<input>::type, search_method, ctll::list<singleline, Modifiers...>>();
    5770              : 
    5771              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto starts_with = regular_expression<typename regex_builder<input>::type, starts_with_method, ctll::list<singleline, Modifiers...>>();
    5772              : 
    5773              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto search_all = regular_expression<typename regex_builder<input>::type, range_method, ctll::list<singleline, Modifiers...>>();
    5774              : 
    5775              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> [[deprecated("use search_all")]] constexpr auto range = regular_expression<typename regex_builder<input>::type, range_method, ctll::list<singleline, Modifiers...>>();
    5776              : 
    5777              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto split = regular_expression<typename regex_builder<input>::type, split_method, ctll::list<singleline, Modifiers...>>();
    5778              : 
    5779              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto tokenize = regular_expression<typename regex_builder<input>::type, tokenize_method, ctll::list<singleline, Modifiers...>>();
    5780              : 
    5781              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto iterator = regular_expression<typename regex_builder<input>::type, iterator_method, ctll::list<singleline, Modifiers...>>();
    5782              : 
    5783              : CTRE_EXPORT constexpr auto sentinel = regex_end_iterator();
    5784              : 
    5785              : // multiline
    5786              : 
    5787              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_match = regular_expression<typename regex_builder<input>::type, match_method, ctll::list<multiline, Modifiers...>>();
    5788              : 
    5789              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_search = regular_expression<typename regex_builder<input>::type, search_method, ctll::list<multiline, Modifiers...>>();
    5790              : 
    5791              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_starts_with = regular_expression<typename regex_builder<input>::type, starts_with_method, ctll::list<multiline, Modifiers...>>();
    5792              : 
    5793              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_search_all = regular_expression<typename regex_builder<input>::type, range_method, ctll::list<multiline, Modifiers...>>();
    5794              : 
    5795              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> [[deprecated("use multiline_search_all")]] constexpr auto multiline_range = regular_expression<typename regex_builder<input>::type, range_method, ctll::list<multiline, Modifiers...>>();
    5796              : 
    5797              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_split = regular_expression<typename regex_builder<input>::type, split_method, ctll::list<multiline, Modifiers...>>();
    5798              : 
    5799              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_tokenize = regular_expression<typename regex_builder<input>::type, tokenize_method, ctll::list<multiline, Modifiers...>>();
    5800              : 
    5801              : CTRE_EXPORT template <CTRE_REGEX_INPUT_TYPE input, typename... Modifiers> constexpr auto multiline_iterator = regular_expression<typename regex_builder<input>::type, iterator_method, ctll::list<multiline, Modifiers...>>();
    5802              : 
    5803              : CTRE_EXPORT constexpr auto multiline_sentinel = regex_end_iterator();
    5804              : 
    5805              : } // namespace ctre
    5806              : 
    5807              : #endif
    5808              : 
    5809              : #ifndef __EDG__
    5810              : 
    5811              : namespace ctre {
    5812              : 
    5813              : // in C++17 (clang & gcc with gnu extension) we need translate character pack into ctll::fixed_string
    5814              : // in C++20 we have `class nontype template parameters`
    5815              : 
    5816              : #if !CTRE_CNTTP_COMPILER_CHECK
    5817              : template <typename CharT, CharT... input> static inline constexpr auto _fixed_string_reference = ctll::fixed_string< sizeof...(input)>({input...});
    5818              : #endif  
    5819              : 
    5820              : namespace literals {
    5821              :         
    5822              : // clang and GCC <9 supports LITERALS with packs
    5823              : 
    5824              : #ifdef __clang__
    5825              : #pragma clang diagnostic push
    5826              : #pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template"
    5827              : #define CTRE_ENABLE_LITERALS
    5828              : #endif
    5829              :   
    5830              : #ifdef _MSC_VER
    5831              : #ifdef _MSVC_LANG
    5832              : #if _MSVC_LANG >= 202002L
    5833              : #define CTRE_ENABLE_LITERALS
    5834              : #endif
    5835              : #else
    5836              : #define CTRE_ENABLE_LITERALS
    5837              : #endif
    5838              : #endif
    5839              : 
    5840              : #ifdef __INTEL_COMPILER
    5841              : // not enable literals
    5842              : #elif defined __GNUC__
    5843              : #if __GNUC__ < 9
    5844              : #define CTRE_ENABLE_LITERALS
    5845              : #elif __GNUC__ >= 10
    5846              : #if !CTRE_CNTTP_COMPILER_CHECK 
    5847              : // newer versions of GCC will give error when trying to use GNU extension
    5848              : #else
    5849              : #define CTRE_ENABLE_LITERALS
    5850              : #endif  
    5851              : #endif
    5852              : #endif
    5853              : 
    5854              : #ifdef CTRE_ENABLE_LITERALS
    5855              :         
    5856              : // add this when we will have concepts
    5857              : // requires ctll::parser<ctre::pcre, _fixed_string_reference<CharT, charpack...>, ctre::pcre_actions>::template correct_with<pcre_context<>>
    5858              : 
    5859              : #if !CTRE_CNTTP_COMPILER_CHECK
    5860              : template <typename CharT, CharT... charpack> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto operator""_ctre() noexcept {
    5861              :         constexpr auto & _input = _fixed_string_reference<CharT, charpack...>;
    5862              : #else
    5863              : template <ctll::fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto operator""_ctre() noexcept {
    5864              :         constexpr auto _input = input; // workaround for GCC 9 bug 88092
    5865              : #endif
    5866              :         using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
    5867              :         static_assert(tmp(), "Regular Expression contains syntax error.");
    5868              :         if constexpr (tmp()) {
    5869              :                 using re = decltype(front(typename tmp::output_type::stack_type()));
    5870              :                 return ctre::regular_expression(re());
    5871              :         } else {
    5872              :                 return ctre::regular_expression(reject());
    5873              :         }
    5874              : }
    5875              : 
    5876              : // this will need to be fixed with C++20
    5877              : #if !CTRE_CNTTP_COMPILER_CHECK
    5878              : template <typename CharT, CharT... charpack> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto operator""_ctre_id() noexcept {
    5879              :         return id<charpack...>();
    5880              : }
    5881              : #endif
    5882              : 
    5883              : #endif // CTRE_ENABLE_LITERALS
    5884              : 
    5885              : }
    5886              : 
    5887              : namespace test_literals {
    5888              :         
    5889              : #ifdef CTRE_ENABLE_LITERALS
    5890              : 
    5891              : #if !CTRE_CNTTP_COMPILER_CHECK
    5892              : template <typename CharT, CharT... charpack> CTRE_FLATTEN constexpr inline auto operator""_ctre_test() noexcept {
    5893              :         constexpr auto & _input = _fixed_string_reference<CharT, charpack...>;
    5894              : #else
    5895              : template <ctll::fixed_string input> CTRE_FLATTEN constexpr inline auto operator""_ctre_test() noexcept {
    5896              :         constexpr auto _input = input; // workaround for GCC 9 bug 88092
    5897              : #endif
    5898              :         return ctll::parser<ctre::pcre, _input>::template correct_with<>;
    5899              : }
    5900              : 
    5901              : #if !CTRE_CNTTP_COMPILER_CHECK
    5902              : template <typename CharT, CharT... charpack> CTRE_FLATTEN constexpr inline auto operator""_ctre_gen() noexcept {
    5903              :         constexpr auto & _input = _fixed_string_reference<CharT, charpack...>;
    5904              : #else
    5905              : template <ctll::fixed_string input> CTRE_FLATTEN constexpr inline auto operator""_ctre_gen() noexcept {
    5906              :         constexpr auto _input = input; // workaround for GCC 9 bug 88092
    5907              : #endif
    5908              :         using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
    5909              :         static_assert(tmp(), "Regular Expression contains syntax error.");
    5910              :         return typename tmp::output_type::stack_type();
    5911              : }
    5912              : 
    5913              : #if !CTRE_CNTTP_COMPILER_CHECK
    5914              : template <typename CharT, CharT... charpack> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto operator""_ctre_syntax() noexcept {
    5915              :         constexpr auto & _input = _fixed_string_reference<CharT, charpack...>;
    5916              : #else
    5917              : template <ctll::fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto operator""_ctre_syntax() noexcept {
    5918              :         constexpr auto _input = input; // workaround for GCC 9 bug 88092
    5919              : #endif
    5920              :         return ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template correct_with<pcre_context<>>;
    5921              : }
    5922              : 
    5923              : #endif
    5924              : 
    5925              : #ifdef __clang__
    5926              : #pragma clang diagnostic pop
    5927              : #endif
    5928              : 
    5929              : } // literals
    5930              : 
    5931              : } // ctre
    5932              : 
    5933              : #endif
    5934              : 
    5935              : #endif
    5936              : 
    5937              : #ifndef CTRE_V2__CTRE__FUNCTIONS__HPP
    5938              : #define CTRE_V2__CTRE__FUNCTIONS__HPP
    5939              : 
    5940              : namespace ctre {
    5941              : 
    5942              : #if !CTRE_CNTTP_COMPILER_CHECK
    5943              : // avoiding CTAD limitation in C++17
    5944              : template <typename CharT, size_t N> class pattern: public ctll::fixed_string<N> {
    5945              :         using parent = ctll::fixed_string<N>;
    5946              : public:
    5947              :         constexpr pattern(const CharT (&input)[N]) noexcept: parent(input) { }
    5948              : };
    5949              : 
    5950              : template <typename CharT, size_t N> pattern(const CharT (&)[N]) -> pattern<CharT, N>;
    5951              : 
    5952              : // for better examples
    5953              : template <typename CharT, size_t N> class fixed_string: public ctll::fixed_string<N> {
    5954              :         using parent = ctll::fixed_string<N>;
    5955              : public:
    5956              :         constexpr fixed_string(const CharT (&input)[N]) noexcept: parent(input) { }
    5957              : };
    5958              : 
    5959              : template <typename CharT, size_t N> fixed_string(const CharT (&)[N]) -> fixed_string<CharT, N>;
    5960              : #endif
    5961              : 
    5962              : #if CTRE_CNTTP_COMPILER_CHECK
    5963              : template <ctll::fixed_string input, typename Modifier = void> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto re() noexcept {
    5964              : constexpr auto _input = input; // workaround for GCC 9 bug 88092
    5965              : #else
    5966              : template <auto & input, typename Modifier = void> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto re() noexcept {       
    5967              : constexpr auto & _input = input; 
    5968              : #endif
    5969              :         
    5970              :         using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
    5971              :         static_assert(tmp(), "Regular Expression contains syntax error.");
    5972              :         using regex = decltype(front(typename tmp::output_type::stack_type()));
    5973              :         return ctre::regular_expression<regex, Modifier, singleline>();
    5974              : }
    5975              : 
    5976              : }
    5977              : 
    5978              : #endif
    5979              : 
    5980              : #ifndef CTRE_V2__CTRE__OPERATORS__HPP
    5981              : #define CTRE_V2__CTRE__OPERATORS__HPP
    5982              : 
    5983              : template <typename A, typename B> constexpr auto operator|(ctre::regular_expression<A>, ctre::regular_expression<B>) -> ctre::regular_expression<ctre::select<A,B>> {
    5984              :         return {};
    5985              : }
    5986              : 
    5987              : template <typename A, typename B> constexpr auto operator>>(ctre::regular_expression<A>, ctre::regular_expression<B>) -> ctre::regular_expression<ctre::sequence<A,B>> {
    5988              :         return {};
    5989              : }
    5990              : 
    5991              : #endif
    5992              : 
    5993              : #endif
        

Generated by: LCOV version 2.0-1