38 template<IntegerMode mode>
39 class MatchIntegerPrefixParser :
public ParserBase<MatchIntegerPrefixParser<mode>> {
41 constexpr explicit MatchIntegerPrefixParser(
int radix) : m_radix(radix) {}
43 template<concepts::ParserContext Context>
48 auto parse_digits = [&](
int inferred_radix)
54 if (inferred_radix <= 10) {
66 while (it != sent && valid_digit(*it)) {
79 if (m_radix != 0 && m_radix != 8 && m_radix != 16 && m_radix != 2) {
80 return parse_digits(m_radix);
88 return parse_digits(m_radix == 0 ? 10 : m_radix);
93 return parse_digits(m_radix == 0 ? 10 : m_radix);
99 return parse_digits(m_radix == 0 ? 10 : m_radix);
103 if ((m_radix == 0 || m_radix == 16) && (ch == U
'x' || ch == U
'X')) {
104 context.advance(++it);
105 return parse_digits(16);
107 if ((m_radix == 0 || m_radix == 2) && (ch == U
'b' || ch == U
'B')) {
108 context.advance(++it);
109 return parse_digits(2);
112 if ((m_radix == 0 || m_radix == 8) && (ch == U
'o' || ch == U
'O')) {
113 context.advance(++it);
114 return parse_digits(8);
117 return parse_digits(m_radix == 0 ? 10 : m_radix);
120 return parse_digits(m_radix == 0 ? 8 : m_radix);
127 template<concepts::Integer T, IntegerMode mode = IntegerMode::Improved>
128 struct IntegerFunction {
129 constexpr auto operator()(
int radix = 0)
const {
132 DI_ASSERT(radix == 0 || (radix >= 2 && radix <= 36));
136 return '-'_m ||
'+'_m;
142 return (-
match_one(sign) >> MatchIntegerPrefixParser<mode>(radix))
143 << []<concepts::ParserContext Context>(Context& context,
145 auto [sign, number_part] = results;
151 bool negative =
false;
153 if (sign && *sign ==
'-') {
159 if (inferred_radix <= 10) {
171 auto overflow_error = [&] {
179 auto result = math::Checked<U>(0);
183 result *= inferred_radix;
184 result += to_digit(*it);
187 if (result.invalid()) {
190 auto value = *result.value();
191 if constexpr (concepts::Signed<T>) {
193 if (value > max_magnitude) {
196 return static_cast<T
>(negative ? -
value :
value);
206template<concepts::Integer T, IntegerMode mode = IntegerMode::Improved>
207constexpr inline auto integer = detail::IntegerFunction<T, mode> {};
210 template<concepts::Integer T>
#define DI_ASSERT(...)
Definition assert_bool.h:7
constexpr auto reconstruct
Definition reconstruct.h:75
constexpr auto end
Definition end.h:55
constexpr auto begin
Definition begin.h:52
constexpr auto value
Definition value.h:34
Definition duration_literals.h:20
constexpr auto to_unsigned
Definition to_unsigned.h:16
IntegerError
Definition integer.h:21
@ Underflow
Definition integer.h:23
@ Overflow
Definition integer.h:22
IntegerMode
Mode to use when parsing an integer.
Definition integer.h:32
@ CStandard
Definition integer.h:34
@ Improved
Definition integer.h:33
constexpr auto code_point
Definition code_point_parser.h:35
constexpr auto match_one
Definition match_one.h:27
constexpr auto make_error
Definition make_error.h:19
constexpr auto integer
Definition integer.h:207
constexpr auto parse
Definition parse.h:23
char32_t c32
Definition char.h:6
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto get(T &&value) -> decltype(auto)
Definition get.h:8
constexpr auto make_tuple(Args &&... args)
Definition make_tuple.h:9
Unexpected(E &&) -> Unexpected< meta::UnwrapRefDecay< E > >
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto in_place_type
Definition in_place_type.h:12
static constexpr T max
Definition numeric_limits.h:11
Definition in_place_type.h:5