1111
1212#include " src/__support/CPP/limits.h"
1313#include " src/__support/CPP/type_traits.h"
14+ #include " src/__support/UInt128.h"
1415#include " src/__support/common.h"
1516#include " src/__support/ctype_utils.h"
1617#include " src/__support/str_to_num_result.h"
@@ -75,8 +76,12 @@ template <class T>
7576LIBC_INLINE StrToNumResult<T>
7677strtointeger (const char *__restrict src, int base,
7778 const size_t src_len = cpp::numeric_limits<size_t >::max()) {
78- // TODO: Rewrite to support numbers longer than long long
79- unsigned long long result = 0 ;
79+ using ResultType = typename cpp::conditional_t <(cpp::is_same_v<T, UInt128> ||
80+ cpp::is_same_v<T, Int128>),
81+ UInt128, unsigned long long >;
82+
83+ ResultType result = 0 ;
84+
8085 bool is_number = false ;
8186 size_t src_cur = 0 ;
8287 int error_val = 0 ;
@@ -101,15 +106,16 @@ strtointeger(const char *__restrict src, int base,
101106 if (base == 16 && is_hex_start (src + src_cur, src_len - src_cur))
102107 src_cur = src_cur + 2 ;
103108
104- constexpr bool IS_UNSIGNED = ( cpp::numeric_limits <T>:: min () == 0 ) ;
109+ constexpr bool IS_UNSIGNED = cpp::is_unsigned_v <T>;
105110 const bool is_positive = (result_sign == ' +' );
106- unsigned long long constexpr NEGATIVE_MAX =
107- !IS_UNSIGNED
108- ? static_cast <unsigned long long >(cpp::numeric_limits<T>::max ()) + 1
109- : cpp::numeric_limits<T>::max ();
110- unsigned long long const abs_max =
111+
112+ ResultType constexpr NEGATIVE_MAX =
113+ !IS_UNSIGNED ? static_cast <ResultType >(cpp::numeric_limits<T>::max ()) + 1
114+ : cpp::numeric_limits<T>::max ();
115+ ResultType const abs_max =
111116 (is_positive ? cpp::numeric_limits<T>::max () : NEGATIVE_MAX);
112- unsigned long long const abs_max_div_by_base = abs_max / base;
117+ ResultType const abs_max_div_by_base = abs_max / base;
118+
113119 while (src_cur < src_len && isalnum (src[src_cur])) {
114120 int cur_digit = b36_char_to_int (src[src_cur]);
115121 if (cur_digit >= base)
@@ -149,10 +155,12 @@ strtointeger(const char *__restrict src, int base,
149155 return {cpp::numeric_limits<T>::min (), str_len, error_val};
150156 }
151157
152- return {is_positive
153- ? static_cast <T>(result)
154- : static_cast <T>(-static_cast <cpp::make_unsigned_t <T>>(result)),
155- str_len, error_val};
158+ return {
159+ is_positive
160+ ? static_cast <T>(result)
161+ : static_cast <T>(
162+ -static_cast <make_integral_or_big_int_unsigned_t <T>>(result)),
163+ str_len, error_val};
156164}
157165
158166} // namespace internal
0 commit comments