Extensibility for folly::to<> through ADL
[folly.git] / folly / Conv.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define FOLLY_CONV_INTERNAL
17 #include <folly/Conv.h>
18
19 namespace folly {
20 namespace detail {
21
22 extern const char digit1[101] =
23   "00000000001111111111222222222233333333334444444444"
24   "55555555556666666666777777777788888888889999999999";
25 extern const char digit2[101] =
26   "01234567890123456789012345678901234567890123456789"
27   "01234567890123456789012345678901234567890123456789";
28
29 template <> const char *const MaxString<bool>::value = "true";
30 template <> const char *const MaxString<uint8_t>::value = "255";
31 template <> const char *const MaxString<uint16_t>::value = "65535";
32 template <> const char *const MaxString<uint32_t>::value = "4294967295";
33 #if __SIZEOF_LONG__ == 4
34 template <> const char *const MaxString<unsigned long>::value =
35   "4294967295";
36 #else
37 template <> const char *const MaxString<unsigned long>::value =
38   "18446744073709551615";
39 #endif
40 static_assert(sizeof(unsigned long) >= 4,
41               "Wrong value for MaxString<unsigned long>::value,"
42               " please update.");
43 template <> const char *const MaxString<unsigned long long>::value =
44   "18446744073709551615";
45 static_assert(sizeof(unsigned long long) >= 8,
46               "Wrong value for MaxString<unsigned long long>::value"
47               ", please update.");
48
49 #ifdef FOLLY_HAVE_INT128_T
50 template <> const char *const MaxString<__uint128_t>::value =
51   "340282366920938463463374607431768211455";
52 #endif
53
54 namespace {
55 /*
56  * Lookup tables that converts from a decimal character value to an integral
57  * binary value, shifted by a decimal "shift" multiplier.
58  * For all character values in the range '0'..'9', the table at those
59  * index locations returns the actual decimal value shifted by the multiplier.
60  * For all other values, the lookup table returns an invalid OOR value.
61  */
62 // Out-of-range flag value, larger than the largest value that can fit in
63 // four decimal bytes (9999), but four of these added up together should
64 // still not overflow uint16_t.
65 constexpr int32_t OOR = 10000;
66
67 FOLLY_ALIGNED(16) constexpr uint16_t shift1[] = {
68   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
69   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
70   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
71   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
72   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
73   1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
74   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
75   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
76   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
77   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
78   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
79   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
80   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
81   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
82   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
83   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
84   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
85   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
86   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
87   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
88   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
89   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
90   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
91   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
92   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
93   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
94 };
95
96 FOLLY_ALIGNED(16) constexpr uint16_t shift10[] = {
97   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
98   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
99   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
100   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
101   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
102   10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
103   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
104   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
105   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
106   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
107   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
108   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
109   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
110   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
111   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
112   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
113   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
114   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
115   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
116   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
117   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
118   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
119   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
120   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
121   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
122   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
123 };
124
125 FOLLY_ALIGNED(16) constexpr uint16_t shift100[] = {
126   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
127   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
128   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
129   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
130   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
131   100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
132   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
133   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
134   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
135   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
136   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
137   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
138   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
139   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
140   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
141   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
142   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
143   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
144   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
145   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
146   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
147   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
148   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
149   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
150   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
151   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
152 };
153
154 FOLLY_ALIGNED(16) constexpr uint16_t shift1000[] = {
155   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
156   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
157   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
158   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
159   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
160   1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
161   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
162   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
163   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
164   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
165   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
166   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
167   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
168   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
169   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
170   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
171   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
172   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
173   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
174   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
175   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
176   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
177   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
178   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
179   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
180   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
181 };
182 }
183
184 inline bool bool_str_cmp(const char** b, size_t len, const char* value) {
185   // Can't use strncasecmp, since we want to ensure that the full value matches
186   const char* p = *b;
187   const char* e = *b + len;
188   const char* v = value;
189   while (*v != '\0') {
190     if (p == e || tolower(*p) != *v) { // value is already lowercase
191       return false;
192     }
193     ++p;
194     ++v;
195   }
196
197   *b = p;
198   return true;
199 }
200
201 bool str_to_bool(StringPiece* src) {
202   auto b = src->begin(), e = src->end();
203   for (;; ++b) {
204     FOLLY_RANGE_CHECK_STRINGPIECE(
205       b < e, "No non-whitespace characters found in input string", *src);
206     if (!isspace(*b)) break;
207   }
208
209   bool result;
210   size_t len = e - b;
211   switch (*b) {
212     case '0':
213     case '1': {
214       result = false;
215       for (; b < e && isdigit(*b); ++b) {
216         FOLLY_RANGE_CHECK_STRINGPIECE(
217           !result && (*b == '0' || *b == '1'),
218           "Integer overflow when parsing bool: must be 0 or 1", *src);
219         result = (*b == '1');
220       }
221       break;
222     }
223     case 'y':
224     case 'Y':
225       result = true;
226       if (!bool_str_cmp(&b, len, "yes")) {
227         ++b;  // accept the single 'y' character
228       }
229       break;
230     case 'n':
231     case 'N':
232       result = false;
233       if (!bool_str_cmp(&b, len, "no")) {
234         ++b;
235       }
236       break;
237     case 't':
238     case 'T':
239       result = true;
240       if (!bool_str_cmp(&b, len, "true")) {
241         ++b;
242       }
243       break;
244     case 'f':
245     case 'F':
246       result = false;
247       if (!bool_str_cmp(&b, len, "false")) {
248         ++b;
249       }
250       break;
251     case 'o':
252     case 'O':
253       if (bool_str_cmp(&b, len, "on")) {
254         result = true;
255       } else if (bool_str_cmp(&b, len, "off")) {
256         result = false;
257       } else {
258         FOLLY_RANGE_CHECK_STRINGPIECE(false, "Invalid value for bool", *src);
259       }
260       break;
261     default:
262       FOLLY_RANGE_CHECK_STRINGPIECE(false, "Invalid value for bool", *src);
263   }
264
265   src->assign(b, e);
266   return result;
267 }
268
269 namespace {
270 /**
271  * StringPiece to double, with progress information. Alters the
272  * StringPiece parameter to munch the already-parsed characters.
273  */
274 template <class Tgt>
275 Tgt str_to_floating(StringPiece* src) {
276   using namespace double_conversion;
277   static StringToDoubleConverter
278     conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
279          | StringToDoubleConverter::ALLOW_LEADING_SPACES,
280          0.0,
281          // return this for junk input string
282          std::numeric_limits<double>::quiet_NaN(),
283          nullptr, nullptr);
284
285   FOLLY_RANGE_CHECK_STRINGPIECE(!src->empty(),
286                                 "No digits found in input string", *src);
287
288   int length;
289   auto result = conv.StringToDouble(src->data(),
290                                     static_cast<int>(src->size()),
291                                     &length); // processed char count
292
293   if (!std::isnan(result)) {
294     src->advance(length);
295     return result;
296   }
297
298   for (;; src->advance(1)) {
299     if (src->empty()) {
300       throw std::range_error("Unable to convert an empty string"
301                              " to a floating point value.");
302     }
303     if (!isspace(src->front())) {
304       break;
305     }
306   }
307
308   // Was that "inf[inity]"?
309   if (src->size() >= 3 && toupper((*src)[0]) == 'I'
310         && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
311     if (src->size() >= 8 &&
312         toupper((*src)[3]) == 'I' &&
313         toupper((*src)[4]) == 'N' &&
314         toupper((*src)[5]) == 'I' &&
315         toupper((*src)[6]) == 'T' &&
316         toupper((*src)[7]) == 'Y') {
317       src->advance(8);
318     } else {
319       src->advance(3);
320     }
321     return std::numeric_limits<Tgt>::infinity();
322   }
323
324   // Was that "-inf[inity]"?
325   if (src->size() >= 4 && toupper((*src)[0]) == '-'
326       && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
327       && toupper((*src)[3]) == 'F') {
328     if (src->size() >= 9 &&
329         toupper((*src)[4]) == 'I' &&
330         toupper((*src)[5]) == 'N' &&
331         toupper((*src)[6]) == 'I' &&
332         toupper((*src)[7]) == 'T' &&
333         toupper((*src)[8]) == 'Y') {
334       src->advance(9);
335     } else {
336       src->advance(4);
337     }
338     return -std::numeric_limits<Tgt>::infinity();
339   }
340
341   // "nan"?
342   if (src->size() >= 3 && toupper((*src)[0]) == 'N'
343         && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
344     src->advance(3);
345     return std::numeric_limits<Tgt>::quiet_NaN();
346   }
347
348   // "-nan"?
349   if (src->size() >= 4 &&
350       toupper((*src)[0]) == '-' &&
351       toupper((*src)[1]) == 'N' &&
352       toupper((*src)[2]) == 'A' &&
353       toupper((*src)[3]) == 'N') {
354     src->advance(4);
355     return -std::numeric_limits<Tgt>::quiet_NaN();
356   }
357
358   // All bets are off
359   throw std::range_error("Unable to convert \"" + src->toString()
360                          + "\" to a floating point value.");
361 }
362
363 }
364
365 float str_to_float(StringPiece* src) {
366   return str_to_floating<float>(src);
367 }
368
369 double str_to_double(StringPiece* src) {
370   return str_to_floating<double>(src);
371 }
372
373 /**
374  * String represented as a pair of pointers to char to unsigned
375  * integrals. Assumes NO whitespace before or after, and also that the
376  * string is composed entirely of digits. Tgt must be unsigned, and no
377  * sign is allowed in the string (even it's '+'). String may be empty,
378  * in which case digits_to throws.
379  */
380 template <class Tgt>
381 Tgt digits_to(const char* b, const char* e) {
382
383   static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
384   assert(b <= e);
385
386   const size_t size = e - b;
387
388   /* Although the string is entirely made of digits, we still need to
389    * check for overflow.
390    */
391   if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
392     // Leading zeros? If so, recurse to keep things simple
393     if (b < e && *b == '0') {
394       for (++b;; ++b) {
395         if (b == e)
396           return 0; // just zeros, e.g. "0000"
397         if (*b != '0')
398           return digits_to<Tgt>(b, e);
399       }
400     }
401     FOLLY_RANGE_CHECK_BEGIN_END(
402         size == std::numeric_limits<Tgt>::digits10 + 1 &&
403             strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
404         "Numeric overflow upon conversion",
405         b,
406         e);
407   }
408
409   // Here we know that the number won't overflow when
410   // converted. Proceed without checks.
411
412   Tgt result = 0;
413
414   for (; e - b >= 4; b += 4) {
415     result *= 10000;
416     const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
417     const int32_t r1 = shift100[static_cast<size_t>(b[1])];
418     const int32_t r2 = shift10[static_cast<size_t>(b[2])];
419     const int32_t r3 = shift1[static_cast<size_t>(b[3])];
420     const auto sum = r0 + r1 + r2 + r3;
421     assert(sum < OOR && "Assumption: string only has digits");
422     result += sum;
423   }
424
425   switch (e - b) {
426   case 3: {
427     const int32_t r0 = shift100[static_cast<size_t>(b[0])];
428     const int32_t r1 = shift10[static_cast<size_t>(b[1])];
429     const int32_t r2 = shift1[static_cast<size_t>(b[2])];
430     const auto sum = r0 + r1 + r2;
431     assert(sum < OOR && "Assumption: string only has digits");
432     return result * 1000 + sum;
433   }
434   case 2: {
435     const int32_t r0 = shift10[static_cast<size_t>(b[0])];
436     const int32_t r1 = shift1[static_cast<size_t>(b[1])];
437     const auto sum = r0 + r1;
438     assert(sum < OOR && "Assumption: string only has digits");
439     return result * 100 + sum;
440   }
441   case 1: {
442     const int32_t sum = shift1[static_cast<size_t>(b[0])];
443     assert(sum < OOR && "Assumption: string only has digits");
444     return result * 10 + sum;
445   }
446   }
447
448   assert(b == e);
449   FOLLY_RANGE_CHECK_BEGIN_END(
450       size > 0, "Found no digits to convert in input", b, e);
451   return result;
452 }
453
454 template unsigned char digits_to<unsigned char>(const char* b, const char* e);
455 template unsigned short digits_to<unsigned short>(const char* b, const char* e);
456 template unsigned int digits_to<unsigned int>(const char* b, const char* e);
457 template unsigned long digits_to<unsigned long>(const char* b, const char* e);
458 template unsigned long long digits_to<unsigned long long>(const char* b,
459                                                           const char* e);
460 #if FOLLY_HAVE_INT128_T
461 template unsigned __int128 digits_to<unsigned __int128>(const char* b,
462                                                         const char* e);
463 #endif
464
465 } // namespace detail
466 } // namespace folly