1 // Copyright (c) 2019-2020 Dr. Colin Hirsch and Daniel Frey 2 // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ 3 4 #ifndef TAO_PEGTL_INTERNAL_REMATCH_HPP 5 #define TAO_PEGTL_INTERNAL_REMATCH_HPP 6 7 #include "../config.hpp" 8 9 #include "skip_control.hpp" 10 11 #include "../apply_mode.hpp" 12 #include "../memory_input.hpp" 13 #include "../rewind_mode.hpp" 14 15 namespace tao 16 { 17 namespace TAO_PEGTL_NAMESPACE 18 { 19 namespace internal 20 { 21 template< typename Head, typename... Rules > 22 struct rematch; 23 24 template< typename Head > 25 struct rematch< Head > 26 { 27 using analyze_t = typename Head::analyze_t; 28 29 template< apply_mode A, 30 rewind_mode M, 31 template< typename... > 32 class Action, 33 template< typename... > 34 class Control, 35 typename Input, 36 typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::rematch37 static bool match( Input& in, States&&... st ) 38 { 39 return Control< Head >::template match< A, M, Action, Control >( in, st... ); 40 } 41 }; 42 43 template< typename Head, typename Rule, typename... Rules > 44 struct rematch< Head, Rule, Rules... > 45 { 46 using analyze_t = typename Head::analyze_t; // NOTE: Rule and Rules are ignored for analyze(). 47 48 template< apply_mode A, 49 rewind_mode, 50 template< typename... > 51 class Action, 52 template< typename... > 53 class Control, 54 typename Input, 55 typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::rematch56 static bool match( Input& in, States&&... st ) 57 { 58 auto m = in.template mark< rewind_mode::required >(); 59 60 if( Control< Head >::template match< A, rewind_mode::active, Action, Control >( in, st... ) ) { 61 memory_input< Input::tracking_mode_v, typename Input::eol_t, typename Input::source_t > i2( m.iterator(), in.current(), in.source() ); 62 #ifdef __cpp_fold_expressions 63 return m( ( Control< Rule >::template match< A, rewind_mode::active, Action, Control >( i2, st... ) && ... && ( i2.restart( m ), Control< Rules >::template match< A, rewind_mode::active, Action, Control >( i2, st... ) ) ) ); 64 #else 65 bool result = Control< Rule >::template match< A, rewind_mode::active, Action, Control >( i2, st... ); 66 using swallow = bool[]; 67 (void)swallow{ result = result && ( i2.restart( m ), Control< Rules >::template match< A, rewind_mode::active, Action, Control >( i2, st... ) )..., true }; 68 return m( result ); 69 #endif 70 } 71 return false; 72 } 73 }; 74 75 template< typename Head, typename... Rules > 76 struct skip_control< rematch< Head, Rules... > > : std::true_type 77 { 78 }; 79 80 } // namespace internal 81 82 } // namespace TAO_PEGTL_NAMESPACE 83 84 } // namespace tao 85 86 #endif 87