37 inline const char* findFirstNonDigit(
const char*
b,
const char* e) {
39 auto const c =
static_cast<unsigned>(*b) -
'0';
59 #if __SIZEOF_LONG__ == 4 64 const char*
const MaxString<unsigned long>::value =
"18446744073709551615";
67 sizeof(
unsigned long) >= 4,
68 "Wrong value for MaxString<unsigned long>::value," 73 sizeof(
unsigned long long) >= 8,
74 "Wrong value for MaxString<unsigned long long>::value" 77 #if FOLLY_HAVE_INT128_T 80 "340282366920938463463374607431768211455";
95 alignas(16) constexpr
uint16_t shift1[] = {
96 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
97 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
98 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
99 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
100 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 1,
101 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
102 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
103 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
104 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
105 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
106 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
107 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
108 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
109 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
110 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
111 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
112 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
113 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
114 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
115 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
116 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
117 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
118 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
119 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
120 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
121 OOR, OOR, OOR, OOR, OOR, OOR
124 alignas(16) constexpr
uint16_t shift10[] = {
125 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
126 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
127 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
128 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
129 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 10,
130 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
131 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
132 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
133 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
134 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
135 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
136 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
137 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
138 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
139 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
140 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
141 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
142 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
143 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
144 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
145 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
146 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
147 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
148 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
149 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
150 OOR, OOR, OOR, OOR, OOR, OOR
153 alignas(16) constexpr
uint16_t shift100[] = {
154 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
155 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
156 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
157 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
158 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 100,
159 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
160 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
161 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
162 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
163 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
164 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
165 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
166 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
167 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
168 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
169 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
170 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
171 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
172 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
173 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
174 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
175 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
176 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
177 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
178 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
179 OOR, OOR, OOR, OOR, OOR, OOR
182 alignas(16) constexpr
uint16_t shift1000[] = {
183 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
184 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
185 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
186 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
187 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, 1000,
188 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
189 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
190 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
191 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
192 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
193 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
194 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
195 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
196 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
197 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
198 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
199 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
200 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
201 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
202 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
203 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
204 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
205 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
206 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
207 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,
208 OOR, OOR, OOR, OOR, OOR, OOR
217 constexpr
const std::array<
222 {
"Empty input string",
true},
223 {
"No digits found in input string",
true},
224 {
"Integer overflow when parsing bool (must be 0 or 1)",
true},
225 {
"Invalid value for bool",
true},
226 {
"Non-digit character found",
true},
227 {
"Invalid leading character",
true},
228 {
"Overflow during conversion",
true},
229 {
"Negative overflow during conversion",
true},
230 {
"Unable to convert string to floating point value",
true},
231 {
"Non-whitespace character found after end of conversion",
true},
232 {
"Overflow during arithmetic conversion",
false},
233 {
"Negative overflow during arithmetic conversion",
false},
234 {
"Loss of precision during arithmetic conversion",
false},
239 bool_constant<'A' == 65 && 'Z' == 90 && 'a' == 97 && 'z' == 122>;
243 inline char tolower_ascii(
char in) {
247 inline bool bool_str_cmp(
const char** b,
size_t len,
const char*
value) {
250 const char* e = *b + len;
253 if (p == e || tolower_ascii(*p) != *v) {
267 auto b = src->begin(), e = src->end();
272 if (!std::isspace(*b)) {
278 size_t len = size_t(e - b);
283 for (; b < e && isdigit(*b); ++
b) {
284 if (result || (*b !=
'0' && *b !=
'1')) {
287 result = (*b ==
'1');
294 if (!bool_str_cmp(&b, len,
"yes")) {
301 if (!bool_str_cmp(&b, len,
"no")) {
308 if (!bool_str_cmp(&b, len,
"true")) {
315 if (!bool_str_cmp(&b, len,
"false")) {
321 if (bool_str_cmp(&b, len,
"on")) {
323 }
else if (bool_str_cmp(&b, len,
"off")) {
344 using namespace double_conversion;
345 static StringToDoubleConverter conv(
346 StringToDoubleConverter::ALLOW_TRAILING_JUNK |
347 StringToDoubleConverter::ALLOW_LEADING_SPACES,
350 std::numeric_limits<double>::quiet_NaN(),
359 auto result = conv.StringToDouble(
361 static_cast<int>(src->size()),
364 if (!std::isnan(result)) {
373 (result == 0.0 && std::isspace((*src)[
size_t(length) - 1]))) {
377 const char*
suffix = src->data() + length - 1;
383 if (*suffix ==
'-' || *suffix ==
'+') {
388 if (*suffix ==
'e' || *suffix ==
'E') {
392 src->advance(
size_t(length));
396 auto* e = src->end();
398 std::find_if_not(src->begin(), e, [](
char c) {
return std::isspace(
c); });
402 size_t size = size_t(e - b);
404 bool negative =
false;
413 switch (tolower_ascii(*b)) {
415 if (size >= 3 && tolower_ascii(b[1]) ==
'n' &&
416 tolower_ascii(b[2]) ==
'f') {
417 if (size >= 8 && tolower_ascii(b[3]) ==
'i' &&
418 tolower_ascii(b[4]) ==
'n' && tolower_ascii(b[5]) ==
'i' &&
419 tolower_ascii(b[6]) ==
't' && tolower_ascii(b[7]) ==
'y') {
424 result = std::numeric_limits<Tgt>::infinity();
429 if (size >= 3 && tolower_ascii(b[1]) ==
'a' &&
430 tolower_ascii(b[2]) ==
'n') {
432 result = std::numeric_limits<Tgt>::quiet_NaN();
466 template <
typename T>
471 if (!std::isdigit(*b)) {
487 template <
typename U>
509 template <
typename T>
541 auto err = sgn.init(b);
546 size_t size = size_t(e - b);
553 if (b < e && *b ==
'0') {
559 size = size_t(e - b);
576 for (; e - b >= 4; b += 4) {
577 result *=
static_cast<UT
>(10000);
578 const int32_t r0 = shift1000[
static_cast<size_t>(b[0])];
579 const int32_t r1 = shift100[
static_cast<size_t>(b[1])];
580 const int32_t r2 = shift10[
static_cast<size_t>(b[2])];
581 const int32_t r3 = shift1[
static_cast<size_t>(b[3])];
582 const auto sum = r0 + r1 + r2 + r3;
591 const int32_t r0 = shift100[
static_cast<size_t>(b[0])];
592 const int32_t r1 = shift10[
static_cast<size_t>(b[1])];
593 const int32_t r2 = shift1[
static_cast<size_t>(b[2])];
594 const auto sum = r0 + r1 + r2;
598 result = UT(1000 * result + sum);
602 const int32_t r0 = shift10[
static_cast<size_t>(b[0])];
603 const int32_t r1 = shift1[
static_cast<size_t>(b[1])];
604 const auto sum = r0 + r1;
608 result = UT(100 * result + sum);
612 const int32_t sum = shift1[
static_cast<size_t>(b[0])];
616 result = UT(10 * result + sum);
627 return sgn.finalize(result);
670 #if FOLLY_HAVE_INT128_T 675 digits_to<unsigned __int128>(
const char*,
const char*)
noexcept;
686 auto b = src->data(), past = src->data() + src->size();
692 if (!std::isspace(*b)) {
698 auto err = sgn.init(b);
710 auto m = findFirstNonDigit(b + 1, past);
712 auto tmp = digits_to<UT>(
b,
m);
720 auto res = sgn.finalize(tmp.value());
722 if (res.hasValue()) {
723 src->advance(
size_t(
m - src->data()));
756 #if FOLLY_HAVE_INT128_T 769 "ConversionCode should be unsigned");
770 assert((std::size_t)code < kErrorStrings.size());
771 const ErrorString& err = kErrorStrings[(std::size_t)code];
773 return {err.string, code};
780 if (input.
size() > 0) {
781 tmp.append(input.
data(), input.
size());
template Expected< unsigned long long, ConversionCode > digits_to< unsigned long long >(const char *, const char *) noexcept
std::atomic< int64_t > sum(0)
template Expected< unsigned long, ConversionCode > digits_to< unsigned long >(const char *, const char *) noexcept
template Expected< double, ConversionCode > str_to_floating< double >(StringPiece *src) noexcept
template Expected< unsigned long long, ConversionCode > str_to_integral< unsigned long long >(StringPiece *src) noexcept
template Expected< short, ConversionCode > str_to_integral< short >(StringPiece *src) noexcept
template Expected< long, ConversionCode > digits_to< long >(const char *, const char *) noexcept
template Expected< unsigned char, ConversionCode > digits_to< unsigned char >(const char *, const char *) noexcept
uint32_t digits10(uint64_t v)
ConversionCode overflow()
constexpr size_type size() const
—— Concurrent Priority Queue Implementation ——
template Expected< unsigned char, ConversionCode > str_to_integral< unsigned char >(StringPiece *src) noexcept
Expected< T, ConversionCode > finalize(U value)
requires E e noexcept(noexcept(s.error(std::move(e))))
ConversionCode init(const char *&)
template Expected< char, ConversionCode > digits_to< char >(const char *, const char *) noexcept
ConversionCode init(const char *&b)
template Expected< short, ConversionCode > digits_to< short >(const char *, const char *) noexcept
ConversionCode overflow()
constexpr auto size(C const &c) -> decltype(c.size())
constexpr bool empty() const
constexpr Unexpected< typename std::decay< Error >::type > makeUnexpected(Error &&)
constexpr Iter data() const
template Expected< long, ConversionCode > str_to_integral< long >(StringPiece *src) noexcept
template Expected< int, ConversionCode > str_to_integral< int >(StringPiece *src) noexcept
static map< string, int > m
template Expected< int, ConversionCode > digits_to< int >(const char *, const char *) noexcept
static const char *const value
template Expected< long long, ConversionCode > str_to_integral< long long >(StringPiece *src) noexcept
template Expected< signed char, ConversionCode > digits_to< signed char >(const char *, const char *) noexcept
template Expected< unsigned short, ConversionCode > digits_to< unsigned short >(const char *, const char *) noexcept
template Expected< unsigned int, ConversionCode > str_to_integral< unsigned int >(StringPiece *src) noexcept
template Expected< unsigned short, ConversionCode > str_to_integral< unsigned short >(StringPiece *src) noexcept
template Expected< char, ConversionCode > str_to_integral< char >(StringPiece *src) noexcept
template Expected< float, ConversionCode > str_to_floating< float >(StringPiece *src) noexcept
Expected< Tgt, ConversionCode > digits_to(const char *b, const char *const e) noexcept
Expected< T, ConversionCode > finalize(T value)
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
Expected< Tgt, ConversionCode > str_to_integral(StringPiece *src) noexcept
template Expected< unsigned int, ConversionCode > digits_to< unsigned int >(const char *, const char *) noexcept
template Expected< unsigned long, ConversionCode > str_to_integral< unsigned long >(StringPiece *src) noexcept
Expected< Tgt, ConversionCode > str_to_floating(StringPiece *src) noexcept
Expected< bool, ConversionCode > str_to_bool(StringPiece *src) noexcept
template Expected< signed char, ConversionCode > str_to_integral< signed char >(StringPiece *src) noexcept
template Expected< long long, ConversionCode > digits_to< long long >(const char *, const char *) noexcept
ConversionError makeConversionError(ConversionCode code, StringPiece input)