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