nttp_string.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_NTTP_STRING_HPP_INCLUDED
5 #define LEXY_DETAIL_NTTP_STRING_HPP_INCLUDED
6 
9 #include <lexy/encoding.hpp>
10 
11 namespace lexy::_detail
12 {
13 // Note: we can't use type_string<auto...>, it doesn't work on older GCC.
14 template <typename CharT, CharT... Cs>
16 {
17  using char_type = CharT;
18 
19  template <template <typename C, C...> typename T>
20  using rename = T<CharT, Cs...>;
21 
22  static constexpr auto size = sizeof...(Cs);
23 
24  template <typename T = char_type>
25  static constexpr T c_str[sizeof...(Cs) + 1] = {transcode_char<T>(Cs)..., T()};
26 };
27 } // namespace lexy::_detail
28 
29 #if LEXY_HAS_NTTP // string NTTP implementation
30 
32 
33 namespace lexy::_detail
34 {
35 template <std::size_t N, typename CharT>
36 struct string_literal
37 {
38  CharT data[N];
39 
40  using char_type = CharT;
41 
42  LEXY_CONSTEVAL string_literal(const CharT* str) : data{}
43  {
44  for (auto i = 0u; i != N; ++i)
45  data[i] = str[i];
46  }
47  LEXY_CONSTEVAL string_literal(CharT c) : data{}
48  {
49  data[0] = c;
50  }
51 
52  static LEXY_CONSTEVAL auto size()
53  {
54  return N;
55  }
56 };
57 template <std::size_t N, typename CharT>
58 string_literal(const CharT (&)[N]) -> string_literal<N - 1, CharT>;
59 template <typename CharT>
60 string_literal(CharT) -> string_literal<1, CharT>;
61 
62 template <template <typename C, C... Cs> typename T, string_literal Str, std::size_t... Idx>
63 auto _to_type_string(index_sequence<Idx...>)
64 {
65  return T<typename decltype(Str)::char_type, Str.data[Idx]...>{};
66 }
67 template <template <typename C, C... Cs> typename T, string_literal Str>
68 using to_type_string
69  = decltype(_to_type_string<T, Str>(make_index_sequence<decltype(Str)::size()>{}));
70 } // namespace lexy::_detail
71 
72 # define LEXY_NTTP_STRING(T, Str) \
73  ::lexy::_detail::to_type_string<T, ::lexy::_detail::string_literal(Str)>
74 
75 #elif defined(__GNUC__) // literal implementation
76 
77 # pragma GCC diagnostic push
78 # pragma GCC diagnostic ignored "-Wpedantic"
79 # ifdef __clang__
80 # pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
81 # endif
82 
83 template <typename CharT, CharT... Cs>
84 constexpr ::lexy::_detail::type_string<CharT, Cs...> operator""_lexy_string_udl()
85 {
86  return {};
87 }
88 
89 # define LEXY_NTTP_STRING(T, Str) decltype(Str##_lexy_string_udl)::rename<T>
90 
91 # pragma GCC diagnostic pop
92 
93 #else // string<Cs...> macro implementation
94 
95 namespace lexy::_detail
96 {
97 template <typename A, typename B>
98 struct cat_;
99 template <typename CharT, CharT... C1, CharT... C2>
100 struct cat_<type_string<CharT, C1...>, type_string<CharT, C2...>>
101 {
102  using type = type_string<CharT, C1..., C2...>;
103 };
104 template <typename A, typename B>
105 using cat = typename cat_<A, B>::type;
106 
107 template <template <typename CharT, CharT...> typename T, typename TypeString, std::size_t Size,
108  std::size_t MaxSize>
110 {
111  static_assert(Size <= MaxSize, "string out of range");
112  using type = typename TypeString::template rename<T>;
113 };
114 
115 } // namespace lexy::_detail
116 
117 # define LEXY_NTTP_STRING_LENGTH(Str) (sizeof(Str) / sizeof(Str[0]) - 1)
118 
119 // extract Ith character if not out of bounds
120 # define LEXY_NTTP_STRING1(Str, I) \
121  ::std::conditional_t< \
122  (I < LEXY_NTTP_STRING_LENGTH(Str)), \
123  ::lexy::_detail::type_string<::LEXY_DECAY_DECLTYPE(Str[0]), \
124  (I >= LEXY_NTTP_STRING_LENGTH(Str) ? Str[0] : Str[I])>, \
125  ::lexy::_detail::type_string<::LEXY_DECAY_DECLTYPE(Str[0])>>
126 
127 // recursively split the string in two
128 # define LEXY_NTTP_STRING2(Str, I) \
129  ::lexy::_detail::cat<LEXY_NTTP_STRING1(Str, I), LEXY_NTTP_STRING1(Str, I + 1)>
130 # define LEXY_NTTP_STRING4(Str, I) \
131  ::lexy::_detail::cat<LEXY_NTTP_STRING2(Str, I), LEXY_NTTP_STRING2(Str, I + 2)>
132 # define LEXY_NTTP_STRING8(Str, I) \
133  ::lexy::_detail::cat<LEXY_NTTP_STRING4(Str, I), LEXY_NTTP_STRING4(Str, I + 4)>
134 # define LEXY_NTTP_STRING16(Str, I) \
135  ::lexy::_detail::cat<LEXY_NTTP_STRING8(Str, I), LEXY_NTTP_STRING8(Str, I + 8)>
136 # define LEXY_NTTP_STRING32(Str, I) \
137  ::lexy::_detail::cat<LEXY_NTTP_STRING16(Str, I), LEXY_NTTP_STRING16(Str, I + 16)>
138 
139 // instantiate with overflow check
140 # define LEXY_NTTP_STRING(T, Str) \
141  ::lexy::_detail::macro_type_string<T, LEXY_NTTP_STRING32(Str, 0), \
142  LEXY_NTTP_STRING_LENGTH(Str), 32>::type
143 
144 #endif
145 
146 #endif // LEXY_DETAIL_NTTP_STRING_HPP_INCLUDED
147 
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:90
magic_enum::char_type
string_view::value_type char_type
Definition: magic_enum.hpp:145
config.hpp
encoding.hpp
lexy::_detail::type_string
Definition: nttp_string.hpp:15
lexy::_detail::make_index_sequence
typename _make_index_sequence< Size >::type make_index_sequence
Definition: integer_sequence.hpp:55
lexy::_detail::type_string::char_type
CharT char_type
Definition: nttp_string.hpp:17
lexy::_detail::cat
typename cat_< A, B >::type cat
Definition: nttp_string.hpp:105
lexy::_detail::type_string::size
static constexpr auto size
Definition: nttp_string.hpp:22
lexy::_detail::type_string::rename
T< CharT, Cs... > rename
Definition: nttp_string.hpp:20
lexy::_detail::cat_
Definition: nttp_string.hpp:98
assert.hpp
integer_sequence.hpp
lexy::_detail::macro_type_string
Definition: nttp_string.hpp:109
lexy::_detail
Definition: any_ref.hpp:12
lexy::_detail::type_string::c_str
static constexpr T c_str[sizeof...(Cs)+1]
Definition: nttp_string.hpp:25
lexy::_detail::macro_type_string::type
typename TypeString::template rename< T > type
Definition: nttp_string.hpp:112


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Tue Jun 25 2024 02:20:36