LCOV - code coverage report
Current view: top level - borrowed/ctre - ctre.hpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 0.0 % 118 0
Test Date: 2026-05-25 11:40:44 Functions: 0.0 % 2 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     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                 :             :                 constexpr bool fixed = starts_with_anchor(Modifier{}, ctll::list<RE>{});
    5543                 :             : 
    5544                 :             :                 auto it = begin;
    5545                 :             : 
    5546                 :             :                 for (; end != it && !fixed; ++it) {
    5547                 :             :                         if (auto out = evaluate(orig_begin, it, end, Modifier{}, return_type<result_iterator, RE>{}, ctll::list<start_mark, RE, end_mark, accept>())) {
    5548                 :             :                                 return out;
    5549                 :             :                         }
    5550                 :             :                 }
    5551                 :             : 
    5552                 :             :                 // in case the RE is empty or fixed
    5553                 :             :                 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                 :             :                 if (!out) out.set_end_mark(it);
    5558                 :             :                 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                 :             :                 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                 :             :                 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                 :             :                 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