1 // Copyright (c) 2014-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_NORMAL_HPP
5 #define TAO_PEGTL_NORMAL_HPP
6 
7 #include <string>
8 #include <type_traits>
9 #include <utility>
10 
11 #include "apply_mode.hpp"
12 #include "config.hpp"
13 #include "demangle.hpp"
14 #include "match.hpp"
15 #include "parse_error.hpp"
16 #include "rewind_mode.hpp"
17 
18 #include "internal/enable_control.hpp"
19 #include "internal/has_match.hpp"
20 
21 namespace TAO_PEGTL_NAMESPACE
22 {
23    template< typename Rule >
24    struct normal
25    {
26       static constexpr bool enable = internal::enable_control< Rule >;
27 
28       template< typename ParseInput, typename... States >
startTAO_PEGTL_NAMESPACE::normal29       static void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
30       {}
31 
32       template< typename ParseInput, typename... States >
successTAO_PEGTL_NAMESPACE::normal33       static void success( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
34       {}
35 
36       template< typename ParseInput, typename... States >
failureTAO_PEGTL_NAMESPACE::normal37       static void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
38       {}
39 
40       template< typename ParseInput, typename... States >
raiseTAO_PEGTL_NAMESPACE::normal41       [[noreturn]] static void raise( const ParseInput& in, States&&... /*unused*/ )
42       {
43          throw parse_error( "parse error matching " + std::string( demangle< Rule >() ), in );
44       }
45 
46       template< template< typename... > class Action,
47                 typename Iterator,
48                 typename ParseInput,
49                 typename... States >
applyTAO_PEGTL_NAMESPACE::normal50       static auto apply( const Iterator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( Action< Rule >::apply( std::declval< const typename ParseInput::action_t& >(), st... ) ) )
51          -> decltype( Action< Rule >::apply( std::declval< const typename ParseInput::action_t& >(), st... ) )
52       {
53          const typename ParseInput::action_t action_input( begin, in );
54          return Action< Rule >::apply( action_input, st... );
55       }
56 
57       template< template< typename... > class Action,
58                 typename ParseInput,
59                 typename... States >
apply0TAO_PEGTL_NAMESPACE::normal60       static auto apply0( const ParseInput& /*unused*/, States&&... st ) noexcept( noexcept( Action< Rule >::apply0( st... ) ) )
61          -> decltype( Action< Rule >::apply0( st... ) )
62       {
63          return Action< Rule >::apply0( st... );
64       }
65 
66       template< apply_mode A,
67                 rewind_mode M,
68                 template< typename... >
69                 class Action,
70                 template< typename... >
71                 class Control,
72                 typename ParseInput,
73                 typename... States >
matchTAO_PEGTL_NAMESPACE::normal74       [[nodiscard]] static bool match( ParseInput& in, States&&... st )
75       {
76          if constexpr( internal::has_match< bool, Rule, A, M, Action, Control, ParseInput, States... > ) {
77             return Action< Rule >::template match< Rule, A, M, Action, Control >( in, st... );
78          }
79          else {
80             return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
81          }
82       }
83    };
84 
85 }  // namespace TAO_PEGTL_NAMESPACE
86 
87 #endif
88