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_CALLBACK_STRING_HPP_INCLUDED
5 #define LEXY_CALLBACK_STRING_HPP_INCLUDED
6 
8 #include <lexy/callback/base.hpp>
9 #include <lexy/code_point.hpp>
10 #include <lexy/encoding.hpp>
11 #include <lexy/input/base.hpp>
12 #include <lexy/lexeme.hpp>
13 
14 namespace lexy
15 {
16 struct nullopt;
17 
18 template <typename String>
20 
21 template <typename String, typename Encoding, typename CaseFoldingDSL = void>
22 struct _as_string
23 {
24  using return_type = String;
26  static_assert(lexy::_detail::is_compatible_char_type<Encoding, _char_type>,
27  "invalid character type/encoding combination");
28 
29  static constexpr String&& _case_folding(String&& str)
30  {
31  if constexpr (std::is_void_v<CaseFoldingDSL>)
32  {
33  return LEXY_MOV(str);
34  }
35  else if constexpr (CaseFoldingDSL::template is_inplace<Encoding>)
36  {
37  // We can change the string in place.
38  auto original_reader = lexy::_range_reader<Encoding>(str.begin(), str.end());
39  auto reader = typename CaseFoldingDSL::template case_folding<decltype(original_reader)>{
40  original_reader};
41  for (auto ptr = str.data(); true; ++ptr)
42  {
43  auto cur = reader.peek();
44  if (cur == Encoding::eof())
45  break;
46  reader.bump();
47 
48  // Once we've bumped it, we're not looking at it again.
49  *ptr = static_cast<_char_type>(cur);
50  }
51 
52  return LEXY_MOV(str);
53  }
54  else
55  {
56  // We store the existing string somewhere else and clear it.
57  // Then we can read the case folded string and append each code unit.
58  auto original = LEXY_MOV(str);
59  str = String();
60  str.reserve(original.size());
61 
62  auto original_reader = lexy::_range_reader<Encoding>(original.begin(), original.end());
63  auto reader = typename CaseFoldingDSL::template case_folding<decltype(original_reader)>{
64  original_reader};
65  while (true)
66  {
67  auto cur = reader.peek();
68  if (cur == Encoding::eof())
69  break;
70  str.push_back(static_cast<_char_type>(cur));
71  reader.bump();
72  }
73 
74  return LEXY_MOV(str);
75  }
76  }
77 
78  template <typename NewCaseFoldingDSL>
79  constexpr auto case_folding(NewCaseFoldingDSL) const
80  {
82  }
83 
84  constexpr String operator()(nullopt&&) const
85  {
86  return String();
87  }
88  constexpr String&& operator()(String&& str) const
89  {
90  return _case_folding(LEXY_MOV(str));
91  }
92 
93  template <typename Iterator>
94  constexpr auto operator()(Iterator begin, Iterator end) const -> decltype(String(begin, end))
95  {
96  return _case_folding(String(begin, end));
97  }
98  template <typename Str = String, typename Iterator>
99  constexpr auto operator()(const typename Str::allocator_type& allocator, Iterator begin,
100  Iterator end) const -> decltype(String(begin, end, allocator))
101  {
102  return _case_folding(String(begin, end, allocator));
103  }
104 
105  template <typename Reader>
106  constexpr String operator()(lexeme<Reader> lex) const
107  {
108  static_assert(lexy::char_type_compatible_with_reader<Reader, _char_type>,
109  "cannot convert lexeme to this string type");
110 
111  using iterator = typename lexeme<Reader>::iterator;
112  if constexpr (std::is_convertible_v<iterator, const _char_type*>)
113  return _case_folding(String(lex.data(), lex.size()));
114  else
115  return _case_folding(String(lex.begin(), lex.end()));
116  }
117  template <typename Str = String, typename Reader>
118  constexpr String operator()(const typename Str::allocator_type& allocator,
119  lexeme<Reader> lex) const
120  {
121  static_assert(lexy::char_type_compatible_with_reader<Reader, _char_type>,
122  "cannot convert lexeme to this string type");
123 
124  using iterator = typename lexeme<Reader>::iterator;
125  if constexpr (std::is_convertible_v<iterator, const _char_type*>)
126  return _case_folding(String(lex.data(), lex.size(), allocator));
127  else
128  return _case_folding(String(lex.begin(), lex.end(), allocator));
129  }
130 
131  constexpr String operator()(code_point cp) const
132  {
133  typename Encoding::char_type buffer[4] = {};
134  auto size = _detail::encode_code_point<Encoding>(cp.value(), buffer, 4);
135  return _case_folding(String(buffer, buffer + size));
136  }
137  template <typename Str = String>
138  constexpr String operator()(const typename Str::allocator_type& allocator, code_point cp) const
139  {
140  typename Encoding::char_type buffer[4] = {};
141  auto size = _detail::encode_code_point<Encoding>(cp.value(), buffer, 4);
142  return _case_folding(String(buffer, buffer + size, allocator));
143  }
144 
145  struct _sink
146  {
147  String _result;
148 
149  using return_type = String;
150 
151  template <typename CharT, typename = decltype(LEXY_DECLVAL(String).push_back(CharT()))>
152  void operator()(CharT c)
153  {
154  _result.push_back(c);
155  }
156 
157  void operator()(String&& str)
158  {
159  _result.append(LEXY_MOV(str));
160  }
161 
162  template <typename Str = String, typename Iterator>
163  auto operator()(Iterator begin, Iterator end)
164  -> decltype(void(LEXY_DECLVAL(Str).append(begin, end)))
165  {
166  _result.append(begin, end);
167  }
168 
169  template <typename Reader>
171  {
172  static_assert(lexy::char_type_compatible_with_reader<Reader, _char_type>,
173  "cannot convert lexeme to this string type");
174  _result.append(lex.begin(), lex.end());
175  }
176 
178  {
179  typename Encoding::char_type buffer[4] = {};
180  auto size = _detail::encode_code_point<Encoding>(cp.value(), buffer, 4);
181  _result.append(buffer, buffer + size);
182  }
183 
184  String&& finish() &&
185  {
186  return _case_folding(LEXY_MOV(_result));
187  }
188  };
189 
190  constexpr auto sink() const
191  {
192  return _sink{String()};
193  }
194  template <typename S = String>
195  constexpr auto sink(const typename S::allocator_type& allocator) const
196  {
197  return _sink{String(allocator)};
198  }
199 };
200 
205 template <typename String, typename Encoding = deduce_encoding<_string_char_type<String>>>
207 } // namespace lexy
208 
209 #endif // LEXY_CALLBACK_STRING_HPP_INCLUDED
210 
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:21
code_point.hpp
base.hpp
lexy::_string_char_type
LEXY_DECAY_DECLTYPE(LEXY_DECLVAL(String)[0]) _string_char_type
Definition: string.hpp:19
lexy::_as_string::operator()
constexpr auto operator()(const typename Str::allocator_type &allocator, Iterator begin, Iterator end) const -> decltype(String(begin, end, allocator))
Definition: string.hpp:99
lexy::_as_string::operator()
constexpr String operator()(const typename Str::allocator_type &allocator, lexeme< Reader > lex) const
Definition: string.hpp:118
lexy::_as_string::_sink::operator()
void operator()(code_point cp)
Definition: string.hpp:177
magic_enum::char_type
string_view::value_type char_type
Definition: magic_enum.hpp:145
lexy::_as_string::_sink::operator()
void operator()(lexeme< Reader > lex)
Definition: string.hpp:170
lexy::_as_string::operator()
constexpr String operator()(code_point cp) const
Definition: string.hpp:131
encoding.hpp
lexy::_as_string::return_type
String return_type
Definition: string.hpp:24
lexy::as_string
constexpr auto as_string
Definition: string.hpp:206
lexy::nullopt
Definition: option.hpp:25
lexy::lexeme::iterator
typename Reader::iterator iterator
Definition: lexeme.hpp:21
lexy::lexeme::begin
constexpr iterator begin() const noexcept
Definition: lexeme.hpp:38
lexy::_as_string::operator()
constexpr String operator()(const typename Str::allocator_type &allocator, code_point cp) const
Definition: string.hpp:138
lexy::_as_string::_sink::_result
String _result
Definition: string.hpp:147
lexy
Definition: any_ref.hpp:12
lexy::_as_string::operator()
constexpr auto operator()(Iterator begin, Iterator end) const -> decltype(String(begin, end))
Definition: string.hpp:94
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
lexy::code_point::value
constexpr auto value() const noexcept
Definition: code_point.hpp:30
lexy::_as_string::_sink::operator()
void operator()(CharT c)
Definition: string.hpp:152
lexy::_as_string::_sink::finish
String && finish() &&
Definition: string.hpp:184
lexy::_as_string::_sink::operator()
auto operator()(Iterator begin, Iterator end) -> decltype(void(LEXY_DECLVAL(Str).append(begin, end)))
Definition: string.hpp:163
lexy::_as_string::_sink::operator()
void operator()(String &&str)
Definition: string.hpp:157
lexy::_as_string::_char_type
_string_char_type< String > _char_type
Definition: string.hpp:25
lexyd::nullopt
constexpr auto nullopt
Definition: option.hpp:50
lexy::_as_string::operator()
constexpr String operator()(lexeme< Reader > lex) const
Definition: string.hpp:106
lexeme.hpp
lexy::_as_string::case_folding
constexpr auto case_folding(NewCaseFoldingDSL) const
Definition: string.hpp:79
lexy::lexeme::data
constexpr const char_type * data() const noexcept
Definition: lexeme.hpp:47
lexy::lexeme::size
constexpr std::size_t size() const noexcept
Definition: lexeme.hpp:53
LEXY_DECAY_DECLTYPE
#define LEXY_DECAY_DECLTYPE(...)
Definition: config.hpp:26
lexy::_as_string::operator()
constexpr String && operator()(String &&str) const
Definition: string.hpp:88
lexy::lexeme::end
constexpr iterator end() const noexcept
Definition: lexeme.hpp:42
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::_as_string
Definition: string.hpp:22
lexy::_as_string::operator()
constexpr String operator()(nullopt &&) const
Definition: string.hpp:84
lexy::buffer
Definition: buffer.hpp:81
lexy::_as_string::_sink
Definition: string.hpp:145
lexy::lexeme
Definition: lexeme.hpp:16
lexy::_as_string::sink
constexpr auto sink() const
Definition: string.hpp:190
code_point.hpp
base.hpp
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:24
lexyd::eof
constexpr auto eof
Matches EOF.
Definition: eof.hpp:72
lexy::_as_string::_sink::return_type
String return_type
Definition: string.hpp:149
lexy::_as_string::_case_folding
static constexpr String && _case_folding(String &&str)
Definition: string.hpp:29
lexy::code_point
A unicode code point.
Definition: code_point.hpp:24
lexy::_as_string::sink
constexpr auto sink(const typename S::allocator_type &allocator) const
Definition: string.hpp:195


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08