#ifndef TERMINAL_HPP_ #define TERMINAL_HPP_ #include "symbol.hpp" template< char ... > class terminal; template< char Element> class terminal< Element > : public symbol { public: template< class CharType > constexpr terminal( const_string< CharType > str , std::size_t begin = 0 ) : symbol ( begin < str.size() ? str[ begin ] == Element ? begin + 1 : invalid_index : invalid_index ) { } }; constexpr bool const_strcomp( const_string< char > a , std::size_t pos_a , const_string< char > b , std::size_t pos_b ) { return ( pos_a >= a.size() || pos_b >= b.size() ) ? true : ( a[ pos_a ] == b[ pos_b ] ) ? const_strcomp( a , pos_a + 1 , b , pos_b + 1 ) : false; } #define DEF_TERMINAL( TerminalName , StringLiteral ) \ class TerminalName \ : public symbol \ { \ public: \ template< class CharType > \ constexpr TerminalName( const_string< CharType > str , std::size_t begin = 0 ) \ : symbol \ ( \ begin + const_string< char >( StringLiteral ).size() > str.size() ? \ invalid_index : \ const_strcomp( str , begin , const_string< char >( StringLiteral ) , 0 ) ? \ begin + const_string< char >( StringLiteral ).size() : \ invalid_index \ ) \ { \ } \ }; #endif