1 // Copyright (c) 2014-2018 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_DUSELTRONIK_HPP 5 #define TAO_PEGTL_INTERNAL_DUSELTRONIK_HPP 6 7 #include "../apply_mode.hpp" 8 #include "../config.hpp" 9 #include "../rewind_mode.hpp" 10 11 #include "dusel_mode.hpp" 12 13 namespace tao 14 { 15 namespace TAO_PEGTL_NAMESPACE 16 { 17 namespace internal 18 { 19 template< typename Rule, 20 apply_mode A, 21 rewind_mode M, 22 template< typename... > class Action, 23 template< typename... > class Control, 24 dusel_mode = dusel_mode::NOTHING > 25 struct duseltronik; 26 27 template< typename Rule, 28 apply_mode A, 29 rewind_mode M, 30 template< typename... > class Action, 31 template< typename... > class Control > 32 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING > 33 { 34 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik35 static auto match( Input& in, States&&... st ) 36 -> decltype( Rule::template match< A, M, Action, Control >( in, st... ), true ) 37 { 38 return Rule::template match< A, M, Action, Control >( in, st... ); 39 } 40 41 // NOTE: The additional "int = 0" is a work-around for missing expression SFINAE in VS2015. 42 43 template< typename Input, typename... States, int = 0 > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik44 static auto match( Input& in, States&&... /*unused*/ ) 45 -> decltype( Rule::match( in ), true ) 46 { 47 return Rule::match( in ); 48 } 49 }; 50 51 template< typename Rule, 52 apply_mode A, 53 rewind_mode M, 54 template< typename... > class Action, 55 template< typename... > class Control > 56 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL > 57 { 58 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik59 static bool match( Input& in, States&&... st ) 60 { 61 Control< Rule >::start( static_cast< const Input& >( in ), st... ); 62 63 if( duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { 64 Control< Rule >::success( static_cast< const Input& >( in ), st... ); 65 return true; 66 } 67 Control< Rule >::failure( static_cast< const Input& >( in ), st... ); 68 return false; 69 } 70 }; 71 72 template< typename Rule, 73 apply_mode A, 74 rewind_mode M, 75 template< typename... > class Action, 76 template< typename... > class Control > 77 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY_VOID > 78 { 79 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik80 static bool match( Input& in, States&&... st ) 81 { 82 auto m = in.template mark< rewind_mode::REQUIRED >(); 83 84 Control< Rule >::start( static_cast< const Input& >( in ), st... ); 85 86 if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { 87 Control< Rule >::template apply< Action >( m.iterator(), static_cast< const Input& >( in ), st... ); 88 Control< Rule >::success( static_cast< const Input& >( in ), st... ); 89 return m( true ); 90 } 91 Control< Rule >::failure( static_cast< const Input& >( in ), st... ); 92 return false; 93 } 94 }; 95 96 template< typename Rule, 97 apply_mode A, 98 rewind_mode M, 99 template< typename... > class Action, 100 template< typename... > class Control > 101 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY_BOOL > 102 { 103 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik104 static bool match( Input& in, States&&... st ) 105 { 106 auto m = in.template mark< rewind_mode::REQUIRED >(); 107 108 Control< Rule >::start( static_cast< const Input& >( in ), st... ); 109 110 if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { 111 if( Control< Rule >::template apply< Action >( m.iterator(), static_cast< const Input& >( in ), st... ) ) { 112 Control< Rule >::success( static_cast< const Input& >( in ), st... ); 113 return m( true ); 114 } 115 } 116 Control< Rule >::failure( static_cast< const Input& >( in ), st... ); 117 return false; 118 } 119 }; 120 121 template< typename Rule, 122 apply_mode A, 123 rewind_mode M, 124 template< typename... > class Action, 125 template< typename... > class Control > 126 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY0_VOID > 127 { 128 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik129 static bool match( Input& in, States&&... st ) 130 { 131 Control< Rule >::start( static_cast< const Input& >( in ), st... ); 132 133 if( duseltronik< Rule, A, M, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { 134 Control< Rule >::template apply0< Action >( static_cast< const Input& >( in ), st... ); 135 Control< Rule >::success( static_cast< const Input& >( in ), st... ); 136 return true; 137 } 138 Control< Rule >::failure( static_cast< const Input& >( in ), st... ); 139 return false; 140 } 141 }; 142 143 template< typename Rule, 144 apply_mode A, 145 rewind_mode M, 146 template< typename... > class Action, 147 template< typename... > class Control > 148 struct duseltronik< Rule, A, M, Action, Control, dusel_mode::CONTROL_AND_APPLY0_BOOL > 149 { 150 template< typename Input, typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::duseltronik151 static bool match( Input& in, States&&... st ) 152 { 153 auto m = in.template mark< rewind_mode::REQUIRED >(); 154 155 Control< Rule >::start( static_cast< const Input& >( in ), st... ); 156 157 if( duseltronik< Rule, A, rewind_mode::ACTIVE, Action, Control, dusel_mode::NOTHING >::match( in, st... ) ) { 158 if( Control< Rule >::template apply0< Action >( static_cast< const Input& >( in ), st... ) ) { 159 Control< Rule >::success( static_cast< const Input& >( in ), st... ); 160 return m( true ); 161 } 162 } 163 Control< Rule >::failure( static_cast< const Input& >( in ), st... ); 164 return false; 165 } 166 }; 167 168 } // namespace internal 169 170 } // namespace TAO_PEGTL_NAMESPACE 171 172 } // namespace tao 173 174 #endif 175