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_UNTIL_HPP 5 #define TAO_PEGTL_INTERNAL_UNTIL_HPP 6 7 #include "../config.hpp" 8 9 #include "bytes.hpp" 10 #include "eof.hpp" 11 #include "not_at.hpp" 12 #include "rule_conjunction.hpp" 13 #include "skip_control.hpp" 14 #include "star.hpp" 15 16 #include "../apply_mode.hpp" 17 #include "../rewind_mode.hpp" 18 19 #include "../analysis/generic.hpp" 20 21 namespace tao 22 { 23 namespace TAO_PEGTL_NAMESPACE 24 { 25 namespace internal 26 { 27 template< typename Cond, typename... Rules > 28 struct until; 29 30 template< typename Cond > 31 struct until< Cond > 32 { 33 using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, bytes< 1 > >, Cond >; 34 35 template< apply_mode A, 36 rewind_mode M, 37 template< typename... > class Action, 38 template< typename... > class Control, 39 typename Input, 40 typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::until41 static bool match( Input& in, States&&... st ) 42 { 43 auto m = in.template mark< M >(); 44 45 while( !Control< Cond >::template match< A, rewind_mode::REQUIRED, Action, Control >( in, st... ) ) { 46 if( in.empty() ) { 47 return false; 48 } 49 in.bump(); 50 } 51 return m( true ); 52 } 53 }; 54 55 template< typename Cond, typename... Rules > 56 struct until 57 { 58 using analyze_t = analysis::generic< analysis::rule_type::SEQ, star< not_at< Cond >, not_at< eof >, Rules... >, Cond >; 59 60 template< apply_mode A, 61 rewind_mode M, 62 template< typename... > class Action, 63 template< typename... > class Control, 64 typename Input, 65 typename... States > matchtao::TAO_PEGTL_NAMESPACE::internal::until66 static bool match( Input& in, States&&... st ) 67 { 68 auto m = in.template mark< M >(); 69 using m_t = decltype( m ); 70 71 while( !Control< Cond >::template match< A, rewind_mode::REQUIRED, Action, Control >( in, st... ) ) { 72 if( !rule_conjunction< Rules... >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) { 73 return false; 74 } 75 } 76 return m( true ); 77 } 78 }; 79 80 template< typename Cond, typename... Rules > 81 struct skip_control< until< Cond, Rules... > > : std::true_type 82 { 83 }; 84 85 } // namespace internal 86 87 } // namespace TAO_PEGTL_NAMESPACE 88 89 } // namespace tao 90 91 #endif 92