@@ -959,6 +959,7 @@ struct pcre {
959959 struct l {};
960960 struct m {};
961961 struct mod {};
962+ struct mode_switch2 {};
962963 struct n {};
963964 struct number2 {};
964965 struct number {};
@@ -1018,6 +1019,10 @@ struct pcre {
10181019 struct make_range: ctll::action {};
10191020 struct make_relative_back_reference: ctll::action {};
10201021 struct make_sequence: ctll::action {};
1022+ struct mode_case_insensitive: ctll::action {};
1023+ struct mode_case_sensitive: ctll::action {};
1024+ struct mode_multiline: ctll::action {};
1025+ struct mode_singleline: ctll::action {};
10211026 struct negate_class_named: ctll::action {};
10221027 struct prepare_capture: ctll::action {};
10231028 struct push_assert_begin: ctll::action {};
@@ -1190,6 +1195,10 @@ struct pcre {
11901195 static constexpr auto rule(content_in_capture, ctll::term<'\x29'>) -> ctll::push<push_empty>;
11911196 static constexpr auto rule(content_in_capture, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject;
11921197
1198+ static constexpr auto rule(d, ctll::term<'i'>) -> ctll::push<ctll::anything, mode_case_insensitive, mode_switch2>;
1199+ static constexpr auto rule(d, ctll::term<'c'>) -> ctll::push<ctll::anything, mode_case_sensitive, mode_switch2>;
1200+ static constexpr auto rule(d, ctll::term<'m'>) -> ctll::push<ctll::anything, mode_multiline, mode_switch2>;
1201+ static constexpr auto rule(d, ctll::term<'s'>) -> ctll::push<ctll::anything, mode_singleline, mode_switch2>;
11931202 static constexpr auto rule(d, ctll::term<'<'>) -> ctll::push<ctll::anything, o>;
11941203 static constexpr auto rule(d, ctll::term<':'>) -> ctll::push<ctll::anything, reset_capture, content_in_capture, ctll::term<'\x29'>>;
11951204 static constexpr auto rule(d, ctll::term<'>'>) -> ctll::push<ctll::anything, reset_capture, start_atomic, content_in_capture, make_atomic, ctll::term<'\x29'>>;
@@ -1288,6 +1297,12 @@ struct pcre {
12881297 static constexpr auto rule(mod, ctll::term<'+'>) -> ctll::push<ctll::anything, make_possessive>;
12891298 static constexpr auto rule(mod, ctll::set<'*','\x7B','\x7D'>) -> ctll::reject;
12901299
1300+ static constexpr auto rule(mode_switch2, ctll::term<'i'>) -> ctll::push<ctll::anything, mode_case_insensitive, mode_switch2>;
1301+ static constexpr auto rule(mode_switch2, ctll::term<'c'>) -> ctll::push<ctll::anything, mode_case_sensitive, mode_switch2>;
1302+ static constexpr auto rule(mode_switch2, ctll::term<'m'>) -> ctll::push<ctll::anything, mode_multiline, mode_switch2>;
1303+ static constexpr auto rule(mode_switch2, ctll::term<'s'>) -> ctll::push<ctll::anything, mode_singleline, mode_switch2>;
1304+ static constexpr auto rule(mode_switch2, ctll::term<'\x29'>) -> ctll::push<ctll::anything>;
1305+
12911306 static constexpr auto rule(n, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push<ctll::anything, create_number, number2, repeat_ab, ctll::term<'\x7D'>, mod>;
12921307 static constexpr auto rule(n, ctll::term<'\x7D'>) -> ctll::push<repeat_at_least, ctll::anything, mod>;
12931308
@@ -1436,6 +1451,26 @@ struct flags {
14361451 (this->set_flag(Args{}), ...);
14371452 }
14381453
1454+ constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_insensitive) noexcept {
1455+ f.case_insensitive = true;
1456+ return f;
1457+ }
1458+
1459+ constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_case_sensitive) noexcept {
1460+ f.case_insensitive = false;
1461+ return f;
1462+ }
1463+
1464+ constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_singleline) noexcept {
1465+ f.multiline = false;
1466+ return f;
1467+ }
1468+
1469+ constexpr friend CTRE_FORCE_INLINE auto operator+(flags f, pcre::mode_multiline) noexcept {
1470+ f.multiline = true;
1471+ return f;
1472+ }
1473+
14391474 constexpr CTRE_FORCE_INLINE void set_flag(ctre::singleline) noexcept {
14401475 multiline = false;
14411476 }
@@ -1678,6 +1713,8 @@ struct assert_subject_end_line{ };
16781713struct assert_line_begin { };
16791714struct assert_line_end { };
16801715
1716+ template <typename> struct mode_switch { };
1717+
16811718}
16821719
16831720#endif
@@ -2059,13 +2096,16 @@ template <size_t Counter> struct pcre_parameters {
20592096 static constexpr size_t current_counter = Counter;
20602097};
20612098
2062- template <typename Stack = ctll::list<>, typename Parameters = pcre_parameters<0>> struct pcre_context {
2099+ template <typename Stack = ctll::list<>, typename Parameters = pcre_parameters<0>, typename Mode = ctll::list<> > struct pcre_context {
20632100 using stack_type = Stack;
20642101 using parameters_type = Parameters;
2102+ using mode_list = Mode;
20652103 static constexpr inline auto stack = stack_type();
20662104 static constexpr inline auto parameters = parameters_type();
2105+ static constexpr inline auto mode = mode_list();
20672106 constexpr pcre_context() noexcept { }
20682107 constexpr pcre_context(Stack, Parameters) noexcept { }
2108+ constexpr pcre_context(Stack, Parameters, Mode) noexcept { }
20692109};
20702110
20712111template <typename... Content, typename Parameters> pcre_context(ctll::list<Content...>, Parameters) -> pcre_context<ctll::list<Content...>, Parameters>;
@@ -2852,6 +2892,39 @@ template <auto V, auto B, auto A, typename... Ts, typename Parameters> static co
28522892
28532893#endif
28542894
2895+ #ifndef CTRE__ACTIONS__MODE__HPP
2896+ #define CTRE__ACTIONS__MODE__HPP
2897+
2898+ // we need to reset counter and wrap Mode into mode_switch
2899+ template <typename Mode, typename... Ts, typename Parameters> static constexpr auto apply_mode(Mode, ctll::list<Ts...>, Parameters) {
2900+ return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, Parameters>{};
2901+ }
2902+
2903+ 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>) {
2904+ return pcre_context<ctll::list<mode_switch<Mode>, Ts...>, pcre_parameters<Counter-1>>{};
2905+ }
2906+
2907+ // catch a semantic action into mode
2908+ 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>) {
2909+ return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2910+ }
2911+
2912+ 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>) {
2913+ return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2914+ }
2915+
2916+ template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_singleline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2917+ return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2918+ }
2919+
2920+ template <auto V, typename... Ts, typename Parameters> static constexpr auto apply(pcre::mode_multiline mode, ctll::term<V>,pcre_context<ctll::list<Ts...>, Parameters>) {
2921+ return apply_mode(mode, ctll::list<Ts...>{}, Parameters{});
2922+ }
2923+
2924+ // to properly reset capture
2925+
2926+ #endif
2927+
28552928};
28562929
28572930}
@@ -4768,6 +4841,12 @@ constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator curre
47684841 }
47694842}
47704843
4844+ // switching modes
4845+ template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename Mode, typename... Tail>
4846+ 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 {
4847+ return evaluate(begin, current, last, f + Mode{}, captures, ctll::list<Tail...>());
4848+ }
4849+
47714850}
47724851
47734852#endif
0 commit comments