Go to the documentation of this file.
4 #ifndef LEXY_DSL_ASCII_HPP_INCLUDED
5 #define LEXY_DSL_ASCII_HPP_INCLUDED
20 return "ASCII.control";
31 template <
typename Encoding>
38 // We're only checking
for 0x00-0x1F, and allow a
false negative
for 0x7F.
39 return (c & mask) == expected;
66 return "ASCII.newline";
83 return "ASCII.other-space";
100 return "ASCII.space";
119 return "ASCII.lower";
129 template <
typename Encoding>
138 // But we need to eliminate ~ at the beginning and {|}~\x7F at the end.
139 constexpr auto offset_low = lexy::_detail::swar_fill(char_type(1));
140 constexpr auto offset_high = lexy::_detail::swar_fill(char_type(5));
142 return ((c - offset_low) & mask) == expected && ((c + offset_high) & mask) == expected;
145 inline constexpr auto lower = _lower{};
147 struct _upper : char_class_base<_upper>
149 static LEXY_CONSTEVAL auto char_class_name()
151 return "ASCII.upper";
154 static LEXY_CONSTEVAL auto char_class_ascii()
156 lexy::_detail::ascii_set result;
157 result.insert('A
', 'Z
');
161 template <typename Encoding>
162 static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
164 using char_type = typename Encoding::char_type;
166 // All interesting characters are in column 3.
167 constexpr auto mask = lexy::_detail::swar_fill_compl(char_type(0b11111));
168 constexpr auto expected = lexy::_detail::swar_fill(char_type(0b10'00000));
174 return ((c - offset_low) & mask) == expected && ((c + offset_high) & mask) == expected;
183 return "ASCII.alpha";
194 template <
typename Encoding>
198 return _lower::template char_class_match_swar<Encoding>(c);
207 return "ASCII.alpha-underscore";
219 template <
typename Encoding>
223 return _alpha::template char_class_match_swar<Encoding>(c);
233 return "ASCII.digit";
243 template <
typename Encoding>
252 // But we need to eliminate :;<=>? at the end.
253 constexpr auto offset_high = lexy::_detail::swar_fill(char_type(6));
255 return (c & mask) == expected && ((c + offset_high) & mask) == expected;
258 inline constexpr auto digit = _digit{};
260 struct _alnum : char_class_base<_alnum>
262 static LEXY_CONSTEVAL auto char_class_name()
264 return "ASCII.alpha-digit";
267 static LEXY_CONSTEVAL auto char_class_ascii()
269 lexy::_detail::ascii_set result;
270 result.insert(_alpha::char_class_ascii());
271 result.insert(_digit::char_class_ascii());
275 template <typename Encoding>
276 static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
278 // We're assuming
alpha characters are more common, so
do the efficient check only
for them.
279 return _alpha::template char_class_match_swar<Encoding>(c);
300 template <
typename Encoding>
305 return _alphau::template char_class_match_swar<Encoding>(c);
316 return "ASCII.punct";
364 return "ASCII.graph";
370 result.
insert(0x21, 0x7E);
374 template <
typename Encoding>
381 constexpr auto ascii_offset = lexy::_detail::swar_fill(char_type(1));
382 constexpr auto ascii_expected = lexy::_detail::swar_fill(char_type(0));
383 if (((c + ascii_offset) & ascii_mask) != ascii_expected)
386 // The above check also included 0xFF for single byte encodings where it overflowed,
387 // so do a separate check in those cases.
388 if constexpr (sizeof(char_type) == 1)
390 if ((c & ascii_mask) != ascii_expected)
394 // Then we must not have a character in column 0, or space.
395 // If we subtract one we turn 0x21-0x01 into column 0 and 0x00 to a value definitely not in
396 // column 0, so need to check both.
397 constexpr auto mask = lexy::_detail::swar_fill_compl(char_type(0b11111));
398 constexpr auto offset_low = lexy::_detail::swar_fill(char_type(1));
399 return !lexy::_detail::swar_has_zero<char_type>(c & mask)
400 && !lexy::_detail::swar_has_zero<char_type>((c - offset_low) & mask);
403 inline constexpr auto graph = _graph{};
405 struct _print : char_class_base<_print>
407 static LEXY_CONSTEVAL auto char_class_name()
409 return "ASCII.print";
412 static LEXY_CONSTEVAL auto char_class_ascii()
414 lexy::_detail::ascii_set result;
415 result.insert(0x20, 0x7E);
419 template <typename Encoding>
420 static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
422 using char_type = typename Encoding::char_type;
424 // First check that we have only ASCII, but shifted by one, so we also exclude 0x7F.
425 constexpr auto ascii_mask = lexy::_detail::swar_fill_compl(char_type(0b11'11111));
428 if (((c + ascii_offset) & ascii_mask) != ascii_expected)
435 if ((c & ascii_mask) != ascii_expected)
441 return !lexy::_detail::swar_has_zero<char_type>(c & mask);
456 result.
insert(0x00, 0x7F);
460 template <
typename Encoding>
466 constexpr auto expected = lexy::_detail::swar_fill(char_type(0));
468 return (c & mask) == expected;
471 inline constexpr auto character = _char{};
472 } // namespace lexyd::ascii
474 namespace lexyd::ascii
477 struct _alt : char_class_base<_alt<C...>>
479 static_assert(sizeof...(C) > 0);
481 static LEXY_CONSTEVAL auto char_class_name()
483 return lexy::_detail::type_string<char, C...>::template c_str<char>;
486 static LEXY_CONSTEVAL auto char_class_ascii()
488 lexy::_detail::ascii_set result;
489 (result.insert(C), ...);
494 template <typename CharT, CharT... C>
497 static_assert((std::is_same_v<CharT, char> && ... && lexy::_detail::is_ascii(C)),
498 "only ASCII characters are supported");
500 using rule = _alt<C...>;
505 template <lexy::_detail::string_literal Str>
506 constexpr auto one_of = typename lexy::_detail::to_type_string<_one_of, Str>::rule{};
509 #define LEXY_ASCII_ONE_OF(Str) \
510 LEXY_NTTP_STRING(::lexyd::ascii::_one_of, Str)::rule {}
511 } // namespace lexyd::ascii
513 #endif // LEXY_DSL_ASCII_HPP_INCLUDED
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_ascii()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
string_view::value_type char_type
static LEXY_CONSTEVAL auto char_class_name()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static LEXY_CONSTEVAL auto char_class_ascii()
constexpr auto alpha_digit_underscore
constexpr auto alpha_underscore
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_name()
constexpr void insert(int c)
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_name()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_name()
constexpr auto other_space
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static LEXY_CONSTEVAL auto char_class_ascii()
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_ascii()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static LEXY_CONSTEVAL auto char_class_ascii()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
constexpr auto alpha_digit
static LEXY_CONSTEVAL auto char_class_ascii()
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static constexpr auto char_class_match_swar(lexy::_detail::swar_int c)
static LEXY_CONSTEVAL auto char_class_name()
static LEXY_CONSTEVAL auto char_class_ascii()
constexpr swar_int swar_fill_compl(CharT _c)
static LEXY_CONSTEVAL auto char_class_ascii()
constexpr swar_int swar_fill(CharT _c)