#pragma once #include #include #include #include #include namespace stdx { inline namespace v1 { namespace detail { template constexpr static bool is_digit_sep_v = C == '\''; template constexpr static bool is_decimal_digit_v = C >= '0' and C <= '9'; template constexpr static bool is_octal_digit_v = C >= '0' and C <= '7'; template constexpr static bool is_binary_digit_v = C >= '0' and C <= '1'; template constexpr static char force_lower_case = static_cast(C) | 32u; template constexpr static bool is_hex_digit_v = (C >= '0' and C <= '9') or (force_lower_case >= 'a' and force_lower_case <= 'f'); template constexpr static auto integral_value_v = is_decimal_digit_v ? C - '0' : force_lower_case - 'a' + 10; template CONSTEVAL auto maybe_add_digit(Sum s) { if constexpr (not is_digit_sep_v) { s *= Base; s += integral_value_v; } return s; } template struct raw_parser { template CONSTEVAL static auto parse() { using U = decltype(stdx::to_underlying(std::declval())); auto x = U{}; ((x = maybe_add_digit(x)), ...); return T{x}; } }; template struct parser : raw_parser<10, Cs...> { static_assert((... and (is_decimal_digit_v or is_digit_sep_v))); }; template struct parser<'0', Cs...> : raw_parser<8, Cs...> { static_assert((... and (is_octal_digit_v or is_digit_sep_v))); }; template struct parser<'0', 'x', Cs...> : raw_parser<16, Cs...> { static_assert((... and (is_hex_digit_v or is_digit_sep_v))); }; template struct parser<'0', 'X', Cs...> : parser<'0', 'x', Cs...> {}; template struct parser<'0', 'b', Cs...> : raw_parser<2, Cs...> { static_assert((... and (is_binary_digit_v or is_digit_sep_v))); }; template struct parser<'0', 'B', Cs...> : parser<'0', 'b', Cs...> {}; } // namespace detail template CONSTEVAL auto parse_literal() -> T { using parser_t = detail::parser; return parser_t::template parse(); } template using constant = std::integral_constant; template constexpr static constant _c{}; inline namespace literals { template CONSTEVAL auto operator""_c() { return _c()>; } } // namespace literals enum struct lsb_t : std::uint32_t {}; enum struct msb_t : std::uint32_t {}; enum struct length_t : std::uint32_t {}; inline namespace literals { // NOLINTBEGIN(google-runtime-int) CONSTEVAL auto operator""_lsb(unsigned long long int n) -> lsb_t { return static_cast(n); } CONSTEVAL auto operator""_msb(unsigned long long int n) -> msb_t { return static_cast(n); } CONSTEVAL auto operator""_len(unsigned long long int n) -> length_t { return static_cast(n); } // NOLINTEND(google-runtime-int) } // namespace literals inline namespace literals { CONSTEVAL auto operator""_b(char const *, std::size_t) -> bool { return true; } CONSTEVAL auto operator""_true(char const *, std::size_t) -> bool { return true; } CONSTEVAL auto operator""_false(char const *, std::size_t) -> bool { return false; } // NOLINTBEGIN(google-runtime-int) CONSTEVAL auto operator""_k(unsigned long long int n) -> unsigned long long int { return n * 1'000u; } CONSTEVAL auto operator""_M(unsigned long long int n) -> unsigned long long int { return n * 1'000'000u; } CONSTEVAL auto operator""_G(unsigned long long int n) -> unsigned long long int { return n * 1'000'000'000u; } CONSTEVAL auto operator""_ki(unsigned long long int n) -> unsigned long long int { return n * 1'024u; } CONSTEVAL auto operator""_Mi(unsigned long long int n) -> unsigned long long int { return n * 1'024ull * 1'024ull; } CONSTEVAL auto operator""_Gi(unsigned long long int n) -> unsigned long long int { return n * 1'024ull * 1'024ull * 1'024ull; } // NOLINTBEGIN(cppcoreguidelines-macro-usage) #define STDX_SMALL_INT_LITERAL_DEF(x) \ CONSTEVAL auto operator""_##x(char const *, std::size_t) \ ->std::integral_constant { \ return {}; \ } STDX_SMALL_INT_LITERAL_DEF(0) STDX_SMALL_INT_LITERAL_DEF(1) STDX_SMALL_INT_LITERAL_DEF(2) STDX_SMALL_INT_LITERAL_DEF(3) STDX_SMALL_INT_LITERAL_DEF(4) STDX_SMALL_INT_LITERAL_DEF(5) STDX_SMALL_INT_LITERAL_DEF(6) STDX_SMALL_INT_LITERAL_DEF(7) STDX_SMALL_INT_LITERAL_DEF(8) STDX_SMALL_INT_LITERAL_DEF(9) #undef STDX_SMALL_INT_LITERAL_DEF // NOLINTEND(cppcoreguidelines-macro-usage) // NOLINTEND(google-runtime-int) } // namespace literals } // namespace v1 } // namespace stdx