4 #ifndef LEXY_DSL_CHAR_CLASS_HPP_INCLUDED
5 #define LEXY_DSL_CHAR_CLASS_HPP_INCLUDED
20 template <
typename Fn>
21 constexpr
void visit(Fn fn)
const
23 for (
auto i = 0; i != 128; ++i)
28 template <
typename Fn>
31 auto range_begin = -1;
32 auto last_char = range_begin;
34 if (range_begin == -1)
39 else if (last_char + 1 == c)
45 fn(range_begin, last_char);
50 if (range_begin != -1)
51 fn(range_begin, last_char);
73 template <std::
size_t RangeCount, std::
size_t SingleCount>
78 char singles[SingleCount == 0 ? 1 : SingleCount];
93 constexpr
auto set = T::char_class_ascii();
95 constexpr
auto count = [&set] {
98 std::size_t range_count;
99 std::size_t single_count;
104 ++result.range_count;
106 ++result.single_count;
115 auto cur_single = 0u;
119 result.range_lower[cur_range] = char(
lower);
120 result.range_upper[cur_range] = char(
upper);
125 result.singles[cur_single] = char(
lower);
136 template <
const auto& CompressedAsciiSet,
140 template <
const auto& CompressedAsciiSet, std::size_t... RangeIdx, std::size_t... SingleIdx>
144 template <
typename Encoding>
150 template <
typename Encoding>
155 ((to_int_type<Encoding>(CompressedAsciiSet.range_lower[RangeIdx]) <= cur
156 && cur <= to_int_type<Encoding>(CompressedAsciiSet.range_upper[RangeIdx]))
159 || ((cur == to_int_type<Encoding>(CompressedAsciiSet.singles[SingleIdx])) || ...);
166 template <
typename CharSet>
167 constexpr
auto _cas = lexy::_detail::compress_ascii_set<CharSet>();
169 template <
typename Derived>
186 template <
typename Reader,
typename Context>
190 constexpr
auto name = Derived::char_class_name();
197 template <
typename Encoding>
200 return std::false_type{};
204 template <
typename Reader>
207 typename Reader::iterator
end;
214 if (matcher::template match<typename Reader::encoding>(reader.peek()))
217 end = reader.position();
221 if constexpr (std::is_same_v<decltype(Derived::char_class_match_cp(char32_t())),
226 else if constexpr (std::is_same_v<typename Reader::encoding, lexy::default_encoding>
227 || std::is_same_v<typename Reader::encoding, lexy::byte_encoding>)
229 static_assert(!Derived::char_class_unicode(),
230 "cannot use this character class with default/byte_encoding");
235 auto cp =
static_cast<char32_t
>(reader.peek());
238 if (!Derived::char_class_match_cp(cp))
241 end = reader.position();
246 static_assert(Derived::char_class_unicode(),
247 "cannot use this character class with Unicode encoding");
254 if (!Derived::char_class_match_cp(result.cp))
262 template <
typename Context>
265 Derived::template char_class_report_error<Reader>(context, reader.position());
271 #define LEXY_CHAR_CLASS(Name, Rule) \
273 static_assert(::lexy::is_char_class_rule<LEXY_DECAY_DECLTYPE(Rule)>); \
274 struct c : ::lexyd::char_class_base<c> \
276 static constexpr auto char_class_unicode() \
278 return (Rule).char_class_unicode(); \
280 static LEXY_CONSTEVAL auto char_class_name() \
284 static LEXY_CONSTEVAL auto char_class_ascii() \
286 return (Rule).char_class_ascii(); \
288 static constexpr auto char_class_match_cp(char32_t cp) \
290 return (Rule).char_class_match_cp(cp); \
298 template <
typename CharT, CharT... C>
300 template <char32_t... Cp>
304 template <
char32_t Cp>
315 if constexpr (Cp <= 0x7F)
322 if constexpr (Cp <= 0x7F)
323 return std::false_type{};
328 template <
unsigned char Byte>
344 if constexpr (Byte <= 0x7F)
351 if constexpr (Byte <= 0x7F)
352 return std::false_type{};
358 template <
typename C,
typename = std::enable_if_t<lexy::is_
char_
class_rule<C>>>
363 template <
typename CharT, CharT C,
365 C <= 0x7F || std::is_same_v<CharT, char32_t> || std::is_same_v<CharT, unsigned char>>>
368 if constexpr (std::is_same_v<CharT, unsigned char>)
371 return _ccp<static_cast<char32_t>(C)>{};
373 template <
char32_t CP>
382 template <
typename... Cs>
385 static_assert(
sizeof...(Cs) > 1);
389 constexpr
auto non_unicode = (!Cs::char_class_unicode() || ...);
390 static_assert(!non_unicode
393 || ((!Cs::char_class_unicode()
394 || std::is_same_v<decltype(Cs::char_class_match_cp(0)),
395 std::false_type>)&&...),
396 "cannot mix bytes and Unicode char classes");
408 (result.
insert(Cs::char_class_ascii()), ...);
414 if constexpr ((std::is_same_v<decltype(Cs::char_class_match_cp(cp)),
415 std::false_type> && ...))
416 return std::false_type{};
418 return (Cs::char_class_match_cp(cp) || ...);
422 template <
typename R1,
typename R2>
429 template <
typename... Cs,
typename C>
434 template <
typename C,
typename... Cs>
440 template <
typename... Cs,
typename... Ds>
449 template <
typename C>
454 return C::char_class_unicode();
465 result.
insert(0x00, 0x7F);
466 result.
remove(C::char_class_ascii());
476 if constexpr (std::is_same_v<decltype(C::char_class_match_cp(cp)), std::false_type>)
479 return !C::char_class_match_cp(cp);
483 template <
typename C>
488 template <
typename C>
497 template <
typename Set,
typename Minus>
513 auto result = Set::char_class_ascii();
514 result.remove(Minus::char_class_ascii());
520 if constexpr (std::is_same_v<decltype(Set::char_class_match_cp(cp)), std::false_type>)
521 return std::false_type{};
522 else if constexpr (std::is_same_v<decltype(Minus::char_class_match_cp(cp)),
526 return cp > 0x7F && Set::char_class_match_cp(cp);
529 return cp > 0x7F && Set::char_class_match_cp(cp) && !Minus::char_class_match_cp(cp);
533 template <
typename Set,
typename Minus>
539 template <
typename Set,
typename Minus,
typename OtherMinus>
548 template <
typename... Cs>
551 static_assert(
sizeof...(Cs) > 1);
561 return "intersection";
567 for (
auto c = 0; c <= 0x7F; ++c)
568 if ((Cs::char_class_ascii().contains[c] && ...))
575 if constexpr ((std::is_same_v<decltype(Cs::char_class_match_cp(cp)),
576 std::false_type> && ...))
577 return std::false_type{};
579 return (Cs::char_class_match_cp(cp) && ...);
583 template <
typename C1,
typename C2>
590 template <
typename... Cs,
typename C>
595 template <
typename C,
typename... Cs>
601 template <
typename... Cs,
typename... Ds>
608 #endif // LEXY_DSL_CHAR_CLASS_HPP_INCLUDED