1 // Copyright (c) 2015-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_PEGTL_STRING_HPP 5 #define TAO_PEGTL_INTERNAL_PEGTL_STRING_HPP 6 7 #include <cstddef> 8 #include <type_traits> 9 10 #include "../ascii.hpp" 11 #include "../config.hpp" 12 13 namespace tao 14 { 15 namespace TAO_PEGTL_NAMESPACE 16 { 17 // Inspired by https://github.com/irrequietus/typestring 18 // Rewritten and reduced to what is needed for the PEGTL 19 // and to work with Visual Studio 2015. 20 21 namespace internal 22 { 23 template< typename, typename, typename, typename, typename, typename, typename, typename > 24 struct string_join; 25 26 template< template< char... > class S, char... C0s, char... C1s, char... C2s, char... C3s, char... C4s, char... C5s, char... C6s, char... C7s > 27 struct string_join< S< C0s... >, S< C1s... >, S< C2s... >, S< C3s... >, S< C4s... >, S< C5s... >, S< C6s... >, S< C7s... > > 28 { 29 using type = S< C0s..., C1s..., C2s..., C3s..., C4s..., C5s..., C6s..., C7s... >; 30 }; 31 32 template< template< char... > class S, char, bool > 33 struct string_at 34 { 35 using type = S<>; 36 }; 37 38 template< template< char... > class S, char C > 39 struct string_at< S, C, true > 40 { 41 using type = S< C >; 42 }; 43 44 template< typename T, std::size_t S > 45 struct string_max_length 46 { 47 static_assert( S <= 512, "String longer than 512 (excluding terminating \\0)!" ); 48 using type = T; 49 }; 50 51 } // namespace internal 52 53 } // namespace TAO_PEGTL_NAMESPACE 54 55 } // namespace tao 56 57 #define TAO_PEGTL_INTERNAL_EMPTY() 58 #define TAO_PEGTL_INTERNAL_DEFER( X ) X TAO_PEGTL_INTERNAL_EMPTY() 59 #define TAO_PEGTL_INTERNAL_EXPAND( ... ) __VA_ARGS__ 60 61 #define TAO_PEGTL_INTERNAL_STRING_AT( S, x, n ) \ 62 tao::TAO_PEGTL_NAMESPACE::internal::string_at< S, ( 0##n < sizeof( x ) ) ? ( x )[ 0##n ] : 0, ( 0##n < sizeof( x ) - 1 ) >::type 63 64 #define TAO_PEGTL_INTERNAL_JOIN_8( M, S, x, n ) \ 65 tao::TAO_PEGTL_NAMESPACE::internal::string_join< TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##0 ), \ 66 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##1 ), \ 67 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##2 ), \ 68 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##3 ), \ 69 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##4 ), \ 70 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##5 ), \ 71 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##6 ), \ 72 TAO_PEGTL_INTERNAL_DEFER( M )( S, x, n##7 ) >::type 73 74 #define TAO_PEGTL_INTERNAL_STRING_8( S, x, n ) \ 75 TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_AT, S, x, n ) 76 77 #define TAO_PEGTL_INTERNAL_STRING_64( S, x, n ) \ 78 TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_8, S, x, n ) 79 80 #define TAO_PEGTL_INTERNAL_STRING_512( S, x, n ) \ 81 TAO_PEGTL_INTERNAL_JOIN_8( TAO_PEGTL_INTERNAL_STRING_64, S, x, n ) 82 83 #define TAO_PEGTL_INTERNAL_STRING( S, x ) \ 84 TAO_PEGTL_INTERNAL_EXPAND( \ 85 TAO_PEGTL_INTERNAL_EXPAND( \ 86 TAO_PEGTL_INTERNAL_EXPAND( \ 87 tao::TAO_PEGTL_NAMESPACE::internal::string_max_length< TAO_PEGTL_INTERNAL_STRING_512( S, x, ), sizeof( x ) - 1 >::type ) ) ) 88 89 #define TAO_PEGTL_STRING( x ) \ 90 TAO_PEGTL_INTERNAL_STRING( tao::TAO_PEGTL_NAMESPACE::ascii::string, x ) 91 92 #define TAO_PEGTL_ISTRING( x ) \ 93 TAO_PEGTL_INTERNAL_STRING( tao::TAO_PEGTL_NAMESPACE::ascii::istring, x ) 94 95 #define TAO_PEGTL_KEYWORD( x ) \ 96 TAO_PEGTL_INTERNAL_STRING( tao::TAO_PEGTL_NAMESPACE::ascii::keyword, x ) 97 98 // Compatibility, remove with 3.0 99 #define TAOCPP_PEGTL_STRING( x ) TAO_PEGTL_STRING( x ) 100 #define TAOCPP_PEGTL_ISTRING( x ) TAO_PEGTL_ISTRING( x ) 101 #define TAOCPP_PEGTL_KEYWORD( x ) TAO_PEGTL_KEYWORD( x ) 102 103 #endif 104