164 enum class state_type : uint8_t {
188 dec_integer_found_e_id,
189 dec_integer_found_E_id,
194 dec_float_found_e_id,
195 dec_float_found_E_id,
205 sqstring_literal_quote,
206 sqstring_literal_escape,
208 dqstring_literal_quote,
209 dqstring_literal_escape,
211 bqstring_literal_quote,
212 bqstring_literal_escape,
215 block_comment_found_star,
216 block_comment_found_dash,
217 block_comment_found_dash_dash,
218 block_comment_found_dash_dash_fin0,
253 struct command_type {
256 state_type next_state = state_type::idle;
260 token::kind_type emit_token = token::none;
264 char char_to_capture =
'\0';
268 uint8_t clear : 1 = 0;
272 uint8_t advance : 1 = 0;
276 uint8_t assigned : 1 = 0;
280 uint8_t advance_line : 1 = 0;
284 uint8_t advance_tab : 1 = 0;
289 struct advance_tag {};
290 struct capture_tag {};
292 class excluding_tag {
296 [[
nodiscard]]
constexpr bool contains(
char c)
const noexcept
298 return _exclusions.
find(c) != _exclusions.npos;
307 constexpr static auto capture = capture_tag{};
311 constexpr static auto advance = advance_tag{};
315 constexpr static auto clear = clear_tag{};
319 constexpr static auto any = any_tag{};
327 template<
typename First,
typename...
Args>
328 [[
nodiscard]]
constexpr static bool _has_advance_tag_argument()
noexcept
330 if constexpr (std::is_same_v<First, advance_tag>) {
332 }
else if constexpr (
sizeof...(Args) == 0) {
335 return _has_advance_tag_argument<
Args...>();
339 template<
typename...
Args>
340 [[
nodiscard]]
constexpr static bool has_advance_tag_argument()
noexcept
342 if constexpr (
sizeof...(Args) == 0) {
345 return _has_advance_tag_argument<
Args...>();
352 using enum state_type;
354 add(idle,
'/', found_slash, advance, capture);
355 add(idle,
'<', found_lt, advance, capture);
356 add(idle,
'#', found_hash, advance, capture);
357 add(idle,
'.', found_dot, advance, capture);
358 add(idle,
'=', found_eq, advance, capture);
359 add(idle,
':', found_colon, advance, capture);
361 add(found_slash, any, idle, token::other);
362 add(found_lt, any, idle, token::other);
363 add(found_hash, any, idle, token::other);
364 add(found_dot, any, idle, token::other);
365 add(found_eq, any, idle, token::other);
366 add(found_colon, any, idle, token::other);
369 add_string_literals();
372 add_number_literals();
378 add_ini_assignment();
382 for (uint8_t i = 0; i != 128; ++i) {
389 command.emit_token = token::error_unexepected_character;
395 [[
nodiscard]]
constexpr command_type& get_command(state_type
from,
char c)
noexcept
400 [[
nodiscard]]
constexpr command_type
const& get_command(state_type
from,
char c)
const noexcept
417 template<
typename It, std::sentinel_for<It> ItEnd>
427 _lexer(
lexer), _first(first), _last(last), _it(first)
431 _token.kind = parse_token();
432 }
while (is_token_filtered(_token));
435 [[
nodiscard]]
constexpr static bool is_token_filtered(
token x)
noexcept
437 return (
Config.filter_white_space
and x == token::ws)
or (
Config.filter_comment
and x == token::lcomment)
or
438 (
Config.filter_comment
and x == token::bcomment);
451 constexpr iterator& operator++()
noexcept
453 hi_axiom(*
this != std::default_sentinel);
455 _token.kind = parse_token();
456 }
while (is_token_filtered(_token));
460 constexpr proxy operator++(
int)
noexcept
462 auto r =
proxy{**
this};
467 [[
nodiscard]]
constexpr bool operator==(std::default_sentinel_t)
const noexcept
469 return _token.kind == token::none;
479 state_type _state = state_type::idle;
481 size_t _column_nr = 0;
487 constexpr void clear()
noexcept
489 _token.capture.
clear();
496 constexpr void capture(
char code_point)
noexcept
505 constexpr void capture(
char32_t code_point)
noexcept
507 hi_axiom(code_point < 0x7fff'ffff);
513 constexpr void advance_counters()
noexcept
515 if (_cp ==
'\n' or _cp ==
'\v' or _cp ==
'\f' or _cp ==
'\x85' or _cp == U
'\u2028' or _cp == U
'\u2029') {
517 }
else if (_cp ==
'\t') {
530 [[
nodiscard]]
constexpr char32_t advance()
noexcept
536 hilet[code_point, valid] =
char_map<
"utf-8">{}.read(_it, _last);
540 [[
nodiscard]]
constexpr token::kind_type parse_token_unicode_identifier()
noexcept
542 switch (ucd_get_lexical_class(_cp & 0x1f'ffff)) {
543 case unicode_lexical_class::id_start:
544 case unicode_lexical_class::id_continue:
551 if (
Config.minus_in_identifier
and _cp ==
'-') {
558 _state = state_type::idle;
564 [[
nodiscard]]
constexpr token::kind_type parse_token_unicode_line_comment()
noexcept
566 hilet
cp_ = _cp & 0x1f'ffff;
567 if (
cp_ == U
'\u0085' or cp_ == U
'\u2028' or cp_ == U
'\u2029') {
568 _state = state_type::idle;
571 return token::lcomment;
581 [[
nodiscard]]
constexpr token::kind_type parse_token_unicode_white_space()
noexcept
583 if (ucd_get_lexical_class(_cp & 0x1f'ffff) == unicode_lexical_class::white_space) {
590 _state = state_type::idle;
595 [[
nodiscard]]
constexpr token::kind_type parse_token_unicode_idle()
noexcept
597 switch (ucd_get_lexical_class(_cp & 0x1f'ffff)) {
598 case unicode_lexical_class::id_start:
599 _state = state_type::identifier;
605 case unicode_lexical_class::white_space:
606 _state = state_type::white_space;
612 case unicode_lexical_class::syntax:
613 _state = state_type::idle;
623 return token::error_unexepected_character;
627 [[
nodiscard]] hi_no_inline
constexpr token::kind_type parse_token_unicode()
noexcept
629 using enum state_type;
634 return parse_token_unicode_idle();
637 return parse_token_unicode_white_space();
640 return parse_token_unicode_line_comment();
643 return parse_token_unicode_identifier();
645 case dqstring_literal:
646 case sqstring_literal:
647 case bqstring_literal:
656 if (_cp == U
'\u0085' or _cp == U
'\u2028' or _cp == U
'\u2029') {
668 return process_command();
672 [[
nodiscard]]
constexpr token::kind_type process_command(
char c =
'\0')
noexcept
674 hilet
command = _lexer->get_command(_state, c);
681 if (
command.char_to_capture !=
'\0') {
682 capture(
command.char_to_capture);
689 }
else if (
command.advance_tab) {
702 [[
nodiscard]]
constexpr token::kind_type parse_token()
noexcept
704 _token.line_nr = _line_nr;
705 _token.column_nr = _column_nr;
708 while (_cp <= 0x7fff'ffff) {
715 auto emit_token = parse_token_unicode();
716 if (emit_token != token::none) {
723 while (_state != state_type::idle) {
735 static_assert(std::movable<iterator<std::string::iterator, std::string::iterator>>);
737 std::is_same_v<std::iterator_traits<iterator<std::string::iterator, std::string::iterator>>::value_type,
token>);
738 static_assert(std::input_or_output_iterator<iterator<std::string::iterator, std::string::iterator>>);
739 static_assert(std::weakly_incrementable<iterator<std::string::iterator, std::string::iterator>>);
747 template<
typename It, std::sentinel_for<It> ItEnd>
760 return parse(str.begin(), str.end());
767 using transition_table_type =
std::array<command_type, std::to_underlying(state_type::_size) * 128>;
769 transition_table_type _transition_table;
771 constexpr void add_string_literal(
778 using enum state_type;
782 for (uint8_t i = 1; i != 128; ++i) {
788 if constexpr (
Config.escape_by_quote_doubling) {
803 for (uint8_t i = 1; i != 128; ++i) {
808 constexpr void add_string_literals()
noexcept
810 using enum state_type;
812 if constexpr (
Config.has_single_quote_string_literal) {
813 add_string_literal(
'\'', token::sstr, sqstring_literal, sqstring_literal_quote, sqstring_literal_escape);
815 add(idle,
'\'', idle, token::other, advance, capture);
818 if constexpr (
Config.has_double_quote_string_literal) {
819 add_string_literal(
'"', token::dstr, dqstring_literal, dqstring_literal_quote, dqstring_literal_escape);
821 add(idle,
'"', idle, token::other, advance, capture);
824 if constexpr (
Config.has_back_quote_string_literal) {
825 add_string_literal(
'`', token::bstr, bqstring_literal, bqstring_literal_quote, bqstring_literal_escape);
827 add(idle,
'`', idle, token::other, advance, capture);
831 constexpr void add_number_literals()
noexcept
833 using enum state_type;
835 add(idle,
"0", zero, advance, capture);
836 add(idle,
"123456789", dec_integer, advance, capture);
838 add(zero, any, idle, token::integer);
839 add(zero,
".", dec_float, advance, capture);
840 add(zero,
"b", zero_b, advance);
841 add(zero,
"B", zero_B, advance);
842 add(zero,
"o", zero_o, advance);
843 add(zero,
"O", zero_O, advance);
844 add(zero,
"d", zero_d, advance);
845 add(zero,
"D", zero_D, advance);
846 add(zero,
"x", zero_x, advance);
847 add(zero,
"X", zero_X, advance);
849 add(zero_b, any, zero_b_id, token::integer);
850 add(zero_B, any, zero_B_id, token::integer);
851 add(zero_o, any, zero_o_id, token::integer);
852 add(zero_O, any, zero_O_id, token::integer);
853 add(zero_d, any, zero_d_id, token::integer);
854 add(zero_D, any, zero_D_id, token::integer);
855 add(zero_x, any, zero_x_id, token::integer);
856 add(zero_X, any, zero_X_id, token::integer);
857 add(zero_b,
"0123456789", bin_integer,
'b');
858 add(zero_B,
"0123456789", bin_integer,
'B');
859 add(zero_o,
"0123456789", oct_integer,
'o');
860 add(zero_O,
"0123456789", oct_integer,
'O');
861 add(zero_d,
"0123456789", dec_integer,
'd');
862 add(zero_D,
"0123456789", dec_integer,
'D');
863 add(zero_x,
"0123456789.", hex_integer,
'x');
864 add(zero_X,
"0123456789.", hex_integer,
'X');
866 add(zero_b_id, any, identifier,
'b');
867 add(zero_B_id, any, identifier,
'B');
868 add(zero_o_id, any, identifier,
'o');
869 add(zero_O_id, any, identifier,
'O');
870 add(zero_d_id, any, identifier,
'd');
871 add(zero_D_id, any, identifier,
'D');
872 add(zero_x_id, any, identifier,
'x');
873 add(zero_X_id, any, identifier,
'X');
875 if constexpr (
Config.zero_starts_octal) {
876 add(zero,
"01234567", oct_integer, advance, capture);
877 add(zero,
"89", idle, token::error_invalid_digit);
879 add(zero,
"0123456789", dec_integer, advance, capture);
883 add(bin_integer, any, idle, token::integer);
884 add(bin_integer,
"01", bin_integer, advance, capture);
885 add(bin_integer,
"23456789", idle, token::error_invalid_digit);
888 add(oct_integer, any, idle, token::integer);
889 add(oct_integer,
"01234567", oct_integer, advance, capture);
890 add(oct_integer,
"89", idle, token::error_invalid_digit);
893 add(dec_integer, any, idle, token::integer);
894 add(dec_integer,
"0123456789", dec_integer, advance, capture);
895 add(dec_integer,
".", dec_float, advance, capture);
896 add(dec_integer,
"e", dec_integer_found_e, advance);
897 add(dec_integer,
"E", dec_integer_found_E, advance);
898 add(dec_integer_found_e, any, dec_integer_found_e_id, token::integer);
899 add(dec_integer_found_E, any, dec_integer_found_E_id, token::integer);
900 add(dec_integer_found_e,
"+-0123456789", dec_sign_exponent,
'e');
901 add(dec_integer_found_E,
"+-0123456789", dec_sign_exponent,
'E');
902 add(dec_integer_found_e_id, any, identifier,
'e');
903 add(dec_integer_found_E_id, any, identifier,
'E');
906 add(hex_integer, any, idle, token::integer);
907 add(hex_integer,
"0123456789abcdefABCDEF", hex_integer, advance, capture);
908 add(hex_integer,
".", hex_float, advance, capture);
909 add(hex_integer,
"pP", hex_sign_exponent, advance, capture);
912 add(found_dot,
"0123456789eE", dec_float);
913 add(dec_float, any, idle, token::real);
914 add(dec_float,
"0123456789", dec_float, advance, capture);
915 add(dec_float,
"e", dec_float_found_e, advance);
916 add(dec_float,
"E", dec_float_found_E, advance);
917 add(dec_float_found_e, any, dec_float_found_e_id, token::real);
918 add(dec_float_found_E, any, dec_float_found_E_id, token::real);
919 add(dec_float_found_e,
"+-0123456789", dec_sign_exponent,
'e');
920 add(dec_float_found_E,
"+-0123456789", dec_sign_exponent,
'E');
921 add(dec_float_found_e_id, any, identifier,
'e');
922 add(dec_float_found_E_id, any, identifier,
'E');
924 add(dec_sign_exponent, any, idle, token::error_incomplete_exponent);
925 add(dec_sign_exponent,
"0123456789", dec_exponent_more, advance, capture);
926 add(dec_sign_exponent,
"+-", dec_exponent, advance, capture);
927 add(dec_exponent, any, idle, token::error_incomplete_exponent);
928 add(dec_exponent,
"0123456789", dec_exponent_more, advance, capture);
929 add(dec_exponent_more, any, idle, token::real);
930 add(dec_exponent_more,
"0123456789", dec_exponent_more, advance, capture);
933 add(hex_float, any, idle, token::real);
934 add(hex_float,
"0123456789abcdefABCDEF", hex_float, advance, capture);
935 add(hex_float,
"pP", hex_sign_exponent, advance, capture);
936 add(hex_sign_exponent, any, idle, token::error_incomplete_exponent);
937 add(hex_sign_exponent,
"0123456789abcdefABCDEF", hex_exponent_more, advance, capture);
938 add(hex_sign_exponent,
"+-", hex_exponent, advance, capture);
939 add(hex_exponent, any, idle, token::error_incomplete_exponent);
940 add(hex_exponent,
"0123456789abcdefABCDEF", hex_exponent_more, advance, capture);
941 add(hex_exponent_more, any, idle, token::real);
942 add(hex_exponent_more,
"0123456789abcdefABCDEF", hex_exponent_more, advance, capture);
944 if constexpr (
Config.digit_separator !=
'\0') {
945 if constexpr (
Config.zero_starts_octal) {
946 add(zero,
Config.digit_separator, oct_integer, advance);
948 add(zero,
Config.digit_separator, dec_integer, advance);
950 add(bin_integer,
Config.digit_separator, bin_integer, advance);
951 add(oct_integer,
Config.digit_separator, oct_integer, advance);
952 add(dec_integer,
Config.digit_separator, dec_integer, advance);
953 add(hex_integer,
Config.digit_separator, hex_integer, advance);
954 add(dec_float,
Config.digit_separator, dec_integer, advance);
955 add(hex_float,
Config.digit_separator, dec_integer, advance);
956 add(dec_exponent,
Config.digit_separator, dec_integer, advance);
957 add(hex_exponent,
Config.digit_separator, dec_integer, advance);
961 constexpr void add_color_literal()
noexcept
963 using enum state_type;
965 if constexpr (
Config.has_color_literal) {
966 add(found_hash,
"0123456789abcdefABCDEF", color_literal, clear, capture, advance);
967 add(color_literal, any, idle, token::color);
968 add(color_literal,
"0123456789abcdefABCDEF", color_literal, advance, capture);
972 constexpr void add_ini_assignment()
noexcept
974 using enum state_type;
976 if constexpr (
Config.equal_is_ini_assignment) {
978 add(found_eq,
" \t", found_eq, advance);
979 add(found_eq,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", ini_string, token::other);
982 if constexpr (
Config.colon_is_ini_assignment) {
984 add(found_colon,
" \t", found_colon, advance);
985 add(found_colon,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", ini_string, token::other);
988 add(ini_string, any, idle, token::istr);
989 add(ini_string, excluding(
"\n\v\f\r\0"), ini_string, advance, capture);
990 add(ini_string,
'\r', ini_string, advance);
993 constexpr void add_comments()
noexcept
995 using enum state_type;
997 if constexpr (
Config.has_double_slash_line_comment) {
998 add(found_slash,
'/', line_comment, clear, advance);
1001 if constexpr (
Config.has_semicolon_line_comment) {
1002 add(idle,
';', line_comment, advance);
1004 add(idle,
';', idle, token::other, capture, advance);
1007 if constexpr (
Config.has_hash_line_comment) {
1008 add(found_hash, excluding(
"\0"), line_comment, clear, advance, capture);
1011 if constexpr (
Config.has_c_block_comment) {
1012 add(found_slash,
'*', block_comment, advance, clear);
1015 if constexpr (
Config.has_sgml_block_comment) {
1016 add(found_lt,
'!', found_lt_bang, advance);
1017 add(found_lt_bang, any, idle, token::error_after_lt_bang);
1018 add(found_lt_bang,
'-', found_lt_bang_dash, advance);
1019 add(found_lt_bang_dash, any, idle, token::error_after_lt_bang);
1020 add(found_lt_bang_dash,
'-', block_comment, advance);
1023 add(line_comment, any, idle, token::lcomment);
1024 add(line_comment, excluding(
"\r\n\f\v\0"), line_comment, advance, capture);
1026 add(line_comment,
'\r', line_comment, advance);
1027 add(line_comment,
"\n\f\v", idle, advance, token::lcomment);
1029 add(block_comment, any, idle, token::error_incomplete_comment);
1031 static_assert(
Config.has_c_block_comment == 0
or Config.has_sgml_block_comment == 0);
1033 if constexpr (
Config.has_c_block_comment) {
1034 add(block_comment, excluding(
"*\0"), block_comment, advance, capture);
1035 add(block_comment,
'*', block_comment_found_star, advance);
1036 add(block_comment_found_star, any, block_comment,
'*');
1037 add(block_comment_found_star,
'/', idle, advance, token::bcomment);
1039 }
else if constexpr (
Config.has_sgml_block_comment) {
1040 add(block_comment, excluding(
"-\0"), block_comment, advance, capture);
1041 add(block_comment,
'-', block_comment_found_dash, advance);
1042 add(block_comment_found_dash, any, block_comment,
'-');
1043 add(block_comment_found_dash,
'-', block_comment_found_dash_dash, advance);
1044 add(block_comment_found_dash_dash, any, block_comment_found_dash_dash_fin0,
'-');
1045 add(block_comment_found_dash_dash_fin0, any, block_comment,
'-');
1046 add(block_comment_found_dash_dash,
'>', idle, advance, token::bcomment);
1050 constexpr void add_white_space()
noexcept
1052 using enum state_type;
1054 add(idle,
'\r', white_space, advance);
1055 add(idle,
" \n\t\v\f", white_space, advance, capture);
1056 add(white_space, any, idle, token::ws);
1057 add(white_space,
'\r', white_space, advance);
1058 add(white_space,
" \n\t\v\f", white_space, advance, capture);
1061 constexpr void add_identifier()
noexcept
1063 using enum state_type;
1065 add(idle,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", identifier, advance, capture);
1066 add(identifier, any, idle, token::id);
1067 add(identifier,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", identifier, advance, capture);
1068 if constexpr (
Config.minus_in_identifier) {
1069 add(identifier,
'-', identifier, advance, capture);
1073 constexpr void add_others()
noexcept
1075 using enum state_type;
1078 add(idle,
"()[]{},@$\\", idle, token::other, capture, advance);
1081 add(idle,
'+', found_plus, advance, capture);
1082 add(idle,
'-', found_minus, advance, capture);
1083 add(idle,
'*', found_star, advance, capture);
1084 add(idle,
'&', found_and, advance, capture);
1085 add(idle,
'|', found_vbar, advance, capture);
1086 add(idle,
'^', found_caret, advance, capture);
1087 add(idle,
'%', found_percent, advance, capture);
1088 add(idle,
'!', found_bang, advance, capture);
1089 add(idle,
'?', found_question, advance, capture);
1090 add(idle,
'~', found_tilde, advance, capture);
1091 add(idle,
'>', found_gt, advance, capture);
1093 add(found_plus, any, idle, token::other);
1094 add(found_minus, any, idle, token::other);
1095 add(found_star, any, idle, token::other);
1096 add(found_and, any, idle, token::other);
1097 add(found_vbar, any, idle, token::other);
1098 add(found_caret, any, idle, token::other);
1099 add(found_percent, any, idle, token::other);
1100 add(found_bang, any, idle, token::other);
1101 add(found_question, any, idle, token::other);
1102 add(found_tilde, any, idle, token::other);
1103 add(found_gt, any, idle, token::other);
1106 add(found_colon,
':', idle, advance, capture, token::other);
1107 if constexpr (
Config.has_dot_star_operator) {
1108 add(found_dot,
'*', idle, advance, capture, token::other);
1110 if constexpr (
Config.has_dot_dot_operator) {
1111 add(found_dot,
'.', found_dot_dot, advance, capture);
1113 add(found_plus,
"+=", idle, advance, capture, token::other);
1114 add(found_minus,
"-=", idle, advance, capture, token::other);
1115 add(found_minus,
'>', found_minus_gt, advance, capture);
1116 add(found_star,
"*=", idle, advance, capture, token::other);
1117 if constexpr (
not Config.has_double_slash_line_comment) {
1118 add(found_slash,
'/', idle, advance, capture, token::other);
1120 add(found_slash,
'=', idle, advance, capture, token::other);
1121 add(found_and,
"&=+-*", idle, advance, capture, token::other);
1122 add(found_vbar,
"|=", idle, advance, capture, token::other);
1123 add(found_caret,
"^=", idle, advance, capture, token::other);
1124 add(found_percent,
"%=", idle, advance, capture, token::other);
1125 add(found_bang,
'=', idle, advance, capture, token::other);
1126 add(found_question,
"?=", idle, advance, capture, token::other);
1127 add(found_tilde,
'=', idle, advance, capture, token::other);
1128 add(found_lt,
'=', found_lt_eq, advance, capture);
1129 add(found_lt,
'<', found_lt_lt, advance, capture);
1130 add(found_gt,
'=', idle, advance, capture, token::other);
1131 add(found_gt,
'>', found_gt_gt, advance, capture);
1132 add(found_eq,
'=', found_eq_eq, advance, capture);
1134 add(found_minus_gt, any, idle, token::other);
1135 add(found_dot_dot, any, idle, token::other);
1136 add(found_lt_eq, any, idle, token::other);
1137 add(found_lt_lt, any, idle, token::other);
1138 add(found_gt_gt, any, idle, token::other);
1139 add(found_eq_eq, any, idle, token::other);
1142 add(found_minus_gt,
'*', idle, advance, capture, token::other);
1143 add(found_dot_dot,
".<", idle, advance, capture, token::other);
1144 add(found_lt_eq,
'>', idle, advance, capture, token::other);
1145 add(found_lt_lt,
'=', idle, advance, capture, token::other);
1146 add(found_gt_gt,
'=', idle, advance, capture, token::other);
1147 add(found_eq_eq,
'=', idle, advance, capture, token::other);
1150 constexpr command_type& _add(state_type
from,
char c, state_type
to)
noexcept
1154 command.char_to_capture =
'\0';
1159 command.emit_token = token::none;
1177 template<
typename First,
typename...
Args>
1178 constexpr command_type& _add(state_type
from,
char c, state_type
to,
First first,
Args const&...args)
noexcept
1181 if constexpr (std::is_same_v<First, token::kind_type>) {
1184 }
else if constexpr (std::is_same_v<First, advance_tag>) {
1186 if (c ==
'\n' or c ==
'\v' or c ==
'\f') {
1188 }
else if (c ==
'\t') {
1192 }
else if constexpr (std::is_same_v<First, clear_tag>) {
1195 }
else if constexpr (std::is_same_v<First, capture_tag>) {
1198 }
else if constexpr (std::is_same_v<First, char>) {
1199 command.char_to_capture = first;
1202 hi_static_no_default();
1208 template<
typename...
Args>
1209 constexpr void add(state_type
from,
char c, state_type
to,
Args const&...args)
noexcept
1212 hi_assert(
not command.assigned,
"Overwriting an already assigned state:char combination.");
1216 template<
typename...
Args>
1217 constexpr void add(state_type
from, std::string_view str, state_type
to,
Args const&...args)
noexcept
1219 for (
auto c : str) {
1221 hi_assert(
not command.assigned,
"Overwriting an already assigned state:char combination.");
1226 template<
typename...
Args>
1227 constexpr void add(state_type
from, any_tag, state_type
to,
Args const&...args)
noexcept
1229 static_assert(
not has_advance_tag_argument<
Args...>(),
"any should not advance");
1231 for (uint8_t c = 0; c != 128; ++c) {
1233 hi_assert(
not command.assigned,
"any should be added first to a state");
1237 template<
typename...
Args>
1238 constexpr void add(state_type
from, excluding_tag
const&
exclusions, state_type
to,
Args const&...args)
noexcept
1240 for (uint8_t c = 0; c != 128; ++c) {
1243 hi_assert(
not command.assigned,
"Overwriting an already assigned state:char combination.");