change the mechanism for "internal" buffer storage
[folly.git] / folly / Conv.h
1 /*
2  * Copyright 2013 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
17 /**
18  * Converts anything to anything, with an emphasis on performance and
19  * safety.
20  *
21  * @author Andrei Alexandrescu (andrei.alexandrescu@fb.com)
22  */
23
24 #ifndef FOLLY_BASE_CONV_H_
25 #define FOLLY_BASE_CONV_H_
26
27 #include "folly/FBString.h"
28 #include "folly/Likely.h"
29 #include "folly/Preprocessor.h"
30 #include "folly/Range.h"
31
32 #include <boost/implicit_cast.hpp>
33 #include <type_traits>
34 #include <limits>
35 #include <string>
36 #include <tuple>
37 #include <stdexcept>
38 #include <typeinfo>
39
40 #include <limits.h>
41
42 #include "double-conversion.h"   // V8 JavaScript implementation
43
44 #define FOLLY_RANGE_CHECK(condition, message)                           \
45   ((condition) ? (void)0 : throw std::range_error(                      \
46     (__FILE__ "(" + std::to_string((long long int) __LINE__) + "): "    \
47      + (message)).c_str()))
48
49 namespace folly {
50
51 /*******************************************************************************
52  * Integral to integral
53  ******************************************************************************/
54
55 /**
56  * Checked conversion from integral to integral. The checks are only
57  * performed when meaningful, e.g. conversion from int to long goes
58  * unchecked.
59  */
60 template <class Tgt, class Src>
61 typename std::enable_if<
62   std::is_integral<Src>::value && std::is_integral<Tgt>::value,
63   Tgt>::type
64 to(const Src & value) {
65   /* static */ if (std::numeric_limits<Tgt>::max()
66                    < std::numeric_limits<Src>::max()) {
67     FOLLY_RANGE_CHECK(
68       (!greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)),
69       "Overflow"
70     );
71   }
72   /* static */ if (std::is_signed<Src>::value &&
73                    (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
74     FOLLY_RANGE_CHECK(
75       (!less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)),
76       "Negative overflow"
77     );
78   }
79   return static_cast<Tgt>(value);
80 }
81
82 /*******************************************************************************
83  * Floating point to floating point
84  ******************************************************************************/
85
86 template <class Tgt, class Src>
87 typename std::enable_if<
88   std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value,
89   Tgt>::type
90 to(const Src & value) {
91   /* static */ if (std::numeric_limits<Tgt>::max() <
92                    std::numeric_limits<Src>::max()) {
93     FOLLY_RANGE_CHECK(value <= std::numeric_limits<Tgt>::max(),
94                       "Overflow");
95     FOLLY_RANGE_CHECK(value >= -std::numeric_limits<Tgt>::max(),
96                       "Negative overflow");
97   }
98   return boost::implicit_cast<Tgt>(value);
99 }
100
101 /*******************************************************************************
102  * Anything to string
103  ******************************************************************************/
104
105 namespace detail {
106
107 template <class T> struct IsSomeString {
108   enum { value = std::is_same<T, std::string>::value
109          || std::is_same<T, fbstring>::value };
110 };
111
112 template <class T>
113 const T& getLastElement(const T & v) {
114   return v;
115 }
116
117 template <class T, class... Ts>
118 typename std::tuple_element<
119   sizeof...(Ts),
120   std::tuple<T, Ts...> >::type const&
121   getLastElement(const T& v, const Ts&... vs) {
122   return getLastElement(vs...);
123 }
124
125 // This class exists to specialize away std::tuple_element in the case where we
126 // have 0 template arguments. Without this, Clang/libc++ will blow a
127 // static_assert even if tuple_element is protected by an enable_if.
128 template <class... Ts>
129 struct last_element {
130   typedef typename std::enable_if<
131     sizeof...(Ts) >= 1,
132     typename std::tuple_element<
133       sizeof...(Ts) - 1, std::tuple<Ts...>
134     >::type>::type type;
135 };
136
137 template <>
138 struct last_element<> {
139   typedef void type;
140 };
141
142 } // namespace detail
143
144 /*******************************************************************************
145  * Conversions from integral types to string types.
146  ******************************************************************************/
147
148 #if FOLLY_HAVE_INT128_T
149 namespace detail {
150
151 template <typename IntegerType>
152 constexpr unsigned int
153 digitsEnough() {
154   return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
155 }
156
157 inline unsigned int
158 unsafeTelescope128(char * buffer, unsigned int room, unsigned __int128 x) {
159   typedef unsigned __int128 Usrc;
160   unsigned int p = room - 1;
161
162   while (x >= (Usrc(1) << 64)) { // Using 128-bit division while needed
163     const auto y = x / 10;
164     const auto digit = x % 10;
165
166     buffer[p--] = '0' + digit;
167     x = y;
168   }
169
170   uint64_t xx = x; // Moving to faster 64-bit division thereafter
171
172   while (xx >= 10) {
173     const auto y = xx / 10ULL;
174     const auto digit = xx % 10ULL;
175
176     buffer[p--] = '0' + digit;
177     xx = y;
178   }
179
180   buffer[p] = '0' + xx;
181
182   return p;
183 }
184
185 }
186 #endif
187
188 /**
189  * Returns the number of digits in the base 10 representation of an
190  * uint64_t. Useful for preallocating buffers and such. It's also used
191  * internally, see below. Measurements suggest that defining a
192  * separate overload for 32-bit integers is not worthwhile.
193  */
194
195 inline uint32_t digits10(uint64_t v) {
196   uint32_t result = 1;
197   for (;;) {
198     if (LIKELY(v < 10)) return result;
199     if (LIKELY(v < 100)) return result + 1;
200     if (LIKELY(v < 1000)) return result + 2;
201     if (LIKELY(v < 10000)) return result + 3;
202     // Skip ahead by 4 orders of magnitude
203     v /= 10000U;
204     result += 4;
205   }
206 }
207
208 /**
209  * Copies the ASCII base 10 representation of v into buffer and
210  * returns the number of bytes written. Does NOT append a \0. Assumes
211  * the buffer points to digits10(v) bytes of valid memory. Note that
212  * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
213  * uint16_t needs at most 5 bytes, and so on. Measurements suggest
214  * that defining a separate overload for 32-bit integers is not
215  * worthwhile.
216  *
217  * This primitive is unsafe because it makes the size assumption and
218  * because it does not add a terminating \0.
219  */
220
221 inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
222   auto const result = digits10(v);
223   // WARNING: using size_t or pointer arithmetic for pos slows down
224   // the loop below 20x. This is because several 32-bit ops can be
225   // done in parallel, but only fewer 64-bit ones.
226   uint32_t pos = result - 1;
227   while (v >= 10) {
228     // Keep these together so a peephole optimization "sees" them and
229     // computes them in one shot.
230     auto const q = v / 10;
231     auto const r = static_cast<uint32_t>(v % 10);
232     buffer[pos--] = '0' + r;
233     v = q;
234   }
235   // Last digit is trivial to handle
236   buffer[pos] = static_cast<uint32_t>(v) + '0';
237   return result;
238 }
239
240 /**
241  * A single char gets appended.
242  */
243 template <class Tgt>
244 void toAppend(char value, Tgt * result) {
245   *result += value;
246 }
247
248 /**
249  * Everything implicitly convertible to const char* gets appended.
250  */
251 template <class Tgt, class Src>
252 typename std::enable_if<
253   std::is_convertible<Src, const char*>::value
254   && detail::IsSomeString<Tgt>::value>::type
255 toAppend(Src value, Tgt * result) {
256   // Treat null pointers like an empty string, as in:
257   // operator<<(std::ostream&, const char*).
258   const char* c = value;
259   if (c) {
260     result->append(value);
261   }
262 }
263
264 /**
265  * Strings get appended, too.
266  */
267 template <class Tgt, class Src>
268 typename std::enable_if<
269   detail::IsSomeString<Src>::value && detail::IsSomeString<Tgt>::value>::type
270 toAppend(const Src& value, Tgt * result) {
271   result->append(value);
272 }
273
274 /**
275  * and StringPiece objects too
276  */
277 template <class Tgt>
278 typename std::enable_if<
279    detail::IsSomeString<Tgt>::value>::type
280 toAppend(StringPiece value, Tgt * result) {
281   result->append(value.data(), value.size());
282 }
283
284 /**
285  * There's no implicit conversion from fbstring to other string types,
286  * so make a specialization.
287  */
288 template <class Tgt>
289 typename std::enable_if<
290    detail::IsSomeString<Tgt>::value>::type
291 toAppend(const fbstring& value, Tgt * result) {
292   result->append(value.data(), value.size());
293 }
294
295 #if FOLLY_HAVE_INT128_T
296 /**
297  * Special handling for 128 bit integers.
298  */
299
300 template <class Tgt>
301 void
302 toAppend(__int128 value, Tgt * result) {
303   typedef unsigned __int128 Usrc;
304   char buffer[detail::digitsEnough<unsigned __int128>() + 1];
305   unsigned int p;
306
307   if (value < 0) {
308     p = detail::unsafeTelescope128(buffer, sizeof(buffer), Usrc(-value));
309     buffer[--p] = '-';
310   } else {
311     p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
312   }
313
314   result->append(buffer + p, buffer + sizeof(buffer));
315 }
316
317 template <class Tgt>
318 void
319 toAppend(unsigned __int128 value, Tgt * result) {
320   char buffer[detail::digitsEnough<unsigned __int128>()];
321   unsigned int p;
322
323   p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
324
325   result->append(buffer + p, buffer + sizeof(buffer));
326 }
327
328 #endif
329
330 /**
331  * int32_t and int64_t to string (by appending) go through here. The
332  * result is APPENDED to a preexisting string passed as the second
333  * parameter. This should be efficient with fbstring because fbstring
334  * incurs no dynamic allocation below 23 bytes and no number has more
335  * than 22 bytes in its textual representation (20 for digits, one for
336  * sign, one for the terminating 0).
337  */
338 template <class Tgt, class Src>
339 typename std::enable_if<
340   std::is_integral<Src>::value && std::is_signed<Src>::value &&
341   detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
342 toAppend(Src value, Tgt * result) {
343   char buffer[20];
344   if (value < 0) {
345     result->push_back('-');
346     result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
347   } else {
348     result->append(buffer, uint64ToBufferUnsafe(value, buffer));
349   }
350 }
351
352 /**
353  * As above, but for uint32_t and uint64_t.
354  */
355 template <class Tgt, class Src>
356 typename std::enable_if<
357   std::is_integral<Src>::value && !std::is_signed<Src>::value
358   && detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
359 toAppend(Src value, Tgt * result) {
360   char buffer[20];
361   result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
362 }
363
364 /**
365  * All small signed and unsigned integers to string go through 32-bit
366  * types int32_t and uint32_t, respectively.
367  */
368 template <class Tgt, class Src>
369 typename std::enable_if<
370   std::is_integral<Src>::value
371   && detail::IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
372 toAppend(Src value, Tgt * result) {
373   typedef typename
374     std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
375     Intermediate;
376   toAppend<Tgt>(static_cast<Intermediate>(value), result);
377 }
378
379 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
380 // std::underlying_type became available by gcc 4.7.0
381
382 /**
383  * Enumerated values get appended as integers.
384  */
385 template <class Tgt, class Src>
386 typename std::enable_if<
387   std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
388 toAppend(Src value, Tgt * result) {
389   toAppend(
390       static_cast<typename std::underlying_type<Src>::type>(value), result);
391 }
392
393 #else
394
395 /**
396  * Enumerated values get appended as integers.
397  */
398 template <class Tgt, class Src>
399 typename std::enable_if<
400   std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
401 toAppend(Src value, Tgt * result) {
402   /* static */ if (Src(-1) < 0) {
403     /* static */ if (sizeof(Src) <= sizeof(int)) {
404       toAppend(static_cast<int>(value), result);
405     } else {
406       toAppend(static_cast<long>(value), result);
407     }
408   } else {
409     /* static */ if (sizeof(Src) <= sizeof(int)) {
410       toAppend(static_cast<unsigned int>(value), result);
411     } else {
412       toAppend(static_cast<unsigned long>(value), result);
413     }
414   }
415 }
416
417 #endif // gcc 4.7 onwards
418
419 /*******************************************************************************
420  * Conversions from floating-point types to string types.
421  ******************************************************************************/
422
423 /** Wrapper around DoubleToStringConverter **/
424 template <class Tgt, class Src>
425 typename std::enable_if<
426   std::is_floating_point<Src>::value
427   && detail::IsSomeString<Tgt>::value>::type
428 toAppend(
429   Src value,
430   Tgt * result,
431   double_conversion::DoubleToStringConverter::DtoaMode mode,
432   unsigned int numDigits) {
433   using namespace double_conversion;
434   DoubleToStringConverter
435     conv(DoubleToStringConverter::NO_FLAGS,
436          "infinity", "NaN", 'E',
437          -6,  // decimal in shortest low
438          21,  // decimal in shortest high
439          6,   // max leading padding zeros
440          1);  // max trailing padding zeros
441   char buffer[256];
442   StringBuilder builder(buffer, sizeof(buffer));
443   switch (mode) {
444     case DoubleToStringConverter::SHORTEST:
445       conv.ToShortest(value, &builder);
446       break;
447     case DoubleToStringConverter::FIXED:
448       conv.ToFixed(value, numDigits, &builder);
449       break;
450     default:
451       CHECK(mode == DoubleToStringConverter::PRECISION);
452       conv.ToPrecision(value, numDigits, &builder);
453       break;
454   }
455   const size_t length = builder.position();
456   builder.Finalize();
457   result->append(buffer, length);
458 }
459
460 /**
461  * As above, but for floating point
462  */
463 template <class Tgt, class Src>
464 typename std::enable_if<
465   std::is_floating_point<Src>::value
466   && detail::IsSomeString<Tgt>::value>::type
467 toAppend(Src value, Tgt * result) {
468   toAppend(
469     value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
470 }
471
472 /**
473  * Variadic conversion to string. Appends each element in turn.
474  */
475 template <class T, class... Ts>
476 typename std::enable_if<sizeof...(Ts) >= 2
477   && detail::IsSomeString<
478   typename std::remove_pointer<
479     typename detail::last_element<Ts...>::type
480   >::type>::value>::type
481 toAppend(const T& v, const Ts&... vs) {
482   toAppend(v, detail::getLastElement(vs...));
483   toAppend(vs...);
484 }
485
486 /**
487  * Variadic base case: do nothing.
488  */
489 template <class Tgt>
490 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
491 toAppend(Tgt* result) {
492 }
493
494 /**
495  * Variadic base case: do nothing.
496  */
497 template <class Delimiter, class Tgt>
498 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
499 toAppendDelim(const Delimiter& delim, Tgt* result) {
500 }
501
502 /**
503  * 1 element: same as toAppend.
504  */
505 template <class Delimiter, class T, class Tgt>
506 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
507 toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
508   toAppend(v, tgt);
509 }
510
511 /**
512  * Append to string with a delimiter in between elements.
513  */
514 template <class Delimiter, class T, class... Ts>
515 typename std::enable_if<sizeof...(Ts) >= 2
516   && detail::IsSomeString<
517   typename std::remove_pointer<
518     typename detail::last_element<Ts...>::type
519   >::type>::value>::type
520 toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
521   toAppend(v, delim, detail::getLastElement(vs...));
522   toAppendDelim(delim, vs...);
523 }
524
525 /**
526  * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
527  * for all types.
528  */
529 template <class Tgt, class... Ts>
530 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
531 to(const Ts&... vs) {
532   Tgt result;
533   toAppend(vs..., &result);
534   return result;
535 }
536
537 /**
538  * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
539  * back-end for all types.
540  */
541 template <class Tgt, class Delim, class... Ts>
542 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
543 toDelim(const Delim& delim, const Ts&... vs) {
544   Tgt result;
545   toAppendDelim(delim, vs..., &result);
546   return result;
547 }
548
549 /*******************************************************************************
550  * Conversions from string types to integral types.
551  ******************************************************************************/
552
553 namespace detail {
554
555 /**
556  * Finds the first non-digit in a string. The number of digits
557  * searched depends on the precision of the Tgt integral. Assumes the
558  * string starts with NO whitespace and NO sign.
559  *
560  * The semantics of the routine is:
561  *   for (;; ++b) {
562  *     if (b >= e || !isdigit(*b)) return b;
563  *   }
564  *
565  *  Complete unrolling marks bottom-line (i.e. entire conversion)
566  *  improvements of 20%.
567  */
568   template <class Tgt>
569   const char* findFirstNonDigit(const char* b, const char* e) {
570     for (; b < e; ++b) {
571       auto const c = static_cast<unsigned>(*b) - '0';
572       if (c >= 10) break;
573     }
574     return b;
575   }
576
577   // Maximum value of number when represented as a string
578   template <class T> struct MaxString {
579     static const char*const value;
580   };
581
582
583 /*
584  * Lookup tables that converts from a decimal character value to an integral
585  * binary value, shifted by a decimal "shift" multiplier.
586  * For all character values in the range '0'..'9', the table at those
587  * index locations returns the actual decimal value shifted by the multiplier.
588  * For all other values, the lookup table returns an invalid OOR value.
589  */
590 // Out-of-range flag value, larger than the largest value that can fit in
591 // four decimal bytes (9999), but four of these added up together should
592 // still not overflow uint16_t.
593 constexpr int32_t OOR = 10000;
594
595 __attribute__((aligned(16))) constexpr uint16_t shift1[] = {
596   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
597   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
598   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
599   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
600   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
601   1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
602   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
603   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
604   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
605   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
606   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
607   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
608   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
609   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
610   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
611   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
612   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
613   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
614   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
615   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
616   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
617   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
618   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
619   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
620   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
621   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
622 };
623
624 __attribute__((aligned(16))) constexpr uint16_t shift10[] = {
625   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
626   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
627   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
628   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
629   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
630   10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
631   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
632   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
633   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
634   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
635   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
636   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
637   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
638   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
639   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
640   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
641   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
642   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
643   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
644   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
645   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
646   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
647   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
648   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
649   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
650   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
651 };
652
653 __attribute__((aligned(16))) constexpr uint16_t shift100[] = {
654   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
655   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
656   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
657   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
658   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
659   100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
660   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
661   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
662   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
663   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
664   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
665   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
666   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
667   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
668   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
669   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
670   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
671   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
672   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
673   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
674   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
675   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
676   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
677   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
678   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
679   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
680 };
681
682 __attribute__((aligned(16))) constexpr uint16_t shift1000[] = {
683   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9
684   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10
685   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20
686   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30
687   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40
688   1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
689   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60
690   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70
691   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80
692   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90
693   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100
694   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110
695   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120
696   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130
697   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140
698   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150
699   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160
700   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170
701   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180
702   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190
703   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200
704   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210
705   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220
706   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230
707   OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240
708   OOR, OOR, OOR, OOR, OOR, OOR                       // 250
709 };
710
711 /**
712  * String represented as a pair of pointers to char to unsigned
713  * integrals. Assumes NO whitespace before or after, and also that the
714  * string is composed entirely of digits. Tgt must be unsigned, and no
715  * sign is allowed in the string (even it's '+'). String may be empty,
716  * in which case digits_to throws.
717  */
718   template <class Tgt>
719   Tgt digits_to(const char * b, const char * e) {
720
721     static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
722     assert(b <= e);
723
724     const size_t size = e - b;
725
726     /* Although the string is entirely made of digits, we still need to
727      * check for overflow.
728      */
729     if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
730       // Leading zeros? If so, recurse to keep things simple
731       if (b < e && *b == '0') {
732         for (++b;; ++b) {
733           if (b == e) return 0; // just zeros, e.g. "0000"
734           if (*b != '0') return digits_to<Tgt>(b, e);
735         }
736       }
737       FOLLY_RANGE_CHECK(size == std::numeric_limits<Tgt>::digits10 + 1 &&
738                         strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
739                         "Numeric overflow upon conversion");
740     }
741
742     // Here we know that the number won't overflow when
743     // converted. Proceed without checks.
744
745     Tgt result = 0;
746
747     for (; e - b >= 4; b += 4) {
748       result *= 10000;
749       const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
750       const int32_t r1 = shift100[static_cast<size_t>(b[1])];
751       const int32_t r2 = shift10[static_cast<size_t>(b[2])];
752       const int32_t r3 = shift1[static_cast<size_t>(b[3])];
753       const auto sum = r0 + r1 + r2 + r3;
754       assert(sum < OOR && "Assumption: string only has digits");
755       result += sum;
756     }
757
758     switch (e - b) {
759       case 3: {
760         const int32_t r0 = shift100[static_cast<size_t>(b[0])];
761         const int32_t r1 = shift10[static_cast<size_t>(b[1])];
762         const int32_t r2 = shift1[static_cast<size_t>(b[2])];
763         const auto sum = r0 + r1 + r2;
764         assert(sum < OOR && "Assumption: string only has digits");
765         return result * 1000 + sum;
766       }
767       case 2: {
768         const int32_t r0 = shift10[static_cast<size_t>(b[0])];
769         const int32_t r1 = shift1[static_cast<size_t>(b[1])];
770         const auto sum = r0 + r1;
771         assert(sum < OOR && "Assumption: string only has digits");
772         return result * 100 + sum;
773       }
774       case 1: {
775         const int32_t sum = shift1[static_cast<size_t>(b[0])];
776         assert(sum < OOR && "Assumption: string only has digits");
777         return result * 10 + sum;
778       }
779     }
780
781     assert(b == e);
782     FOLLY_RANGE_CHECK(size > 0, "Found no digits to convert in input");
783     return result;
784   }
785
786
787   bool str_to_bool(StringPiece * src);
788
789 }                                 // namespace detail
790
791 /**
792  * String represented as a pair of pointers to char to unsigned
793  * integrals. Assumes NO whitespace before or after.
794  */
795 template <class Tgt>
796 typename std::enable_if<
797   std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
798   && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
799   Tgt>::type
800 to(const char * b, const char * e) {
801   return detail::digits_to<Tgt>(b, e);
802 }
803
804 /**
805  * String represented as a pair of pointers to char to signed
806  * integrals. Assumes NO whitespace before or after. Allows an
807  * optional leading sign.
808  */
809 template <class Tgt>
810 typename std::enable_if<
811   std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
812   Tgt>::type
813 to(const char * b, const char * e) {
814   FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral");
815   if (!isdigit(*b)) {
816     if (*b == '-') {
817       Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
818       FOLLY_RANGE_CHECK(result <= 0, "Negative overflow.");
819       return result;
820     }
821     FOLLY_RANGE_CHECK(*b == '+', "Invalid lead character");
822     ++b;
823   }
824   Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
825   FOLLY_RANGE_CHECK(result >= 0, "Overflow.");
826   return result;
827 }
828
829 /**
830  * Parsing strings to integrals. These routines differ from
831  * to<integral>(string) in that they take a POINTER TO a StringPiece
832  * and alter that StringPiece to reflect progress information.
833  */
834
835 /**
836  * StringPiece to integrals, with progress information. Alters the
837  * StringPiece parameter to munch the already-parsed characters.
838  */
839 template <class Tgt>
840 typename std::enable_if<
841   std::is_integral<Tgt>::value
842   && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
843   Tgt>::type
844 to(StringPiece * src) {
845
846   auto b = src->data(), past = src->data() + src->size();
847   for (;; ++b) {
848     FOLLY_RANGE_CHECK(b < past, "No digits found in input string");
849     if (!isspace(*b)) break;
850   }
851
852   auto m = b;
853
854   // First digit is customized because we test for sign
855   bool negative = false;
856   /* static */ if (std::is_signed<Tgt>::value) {
857     if (!isdigit(*m)) {
858       if (*m == '-') {
859         negative = true;
860       } else {
861         FOLLY_RANGE_CHECK(*m == '+', "Invalid leading character in conversion"
862                           " to integral");
863       }
864       ++b;
865       ++m;
866     }
867   }
868   FOLLY_RANGE_CHECK(m < past, "No digits found in input string");
869   FOLLY_RANGE_CHECK(isdigit(*m), "Non-digit character found");
870   m = detail::findFirstNonDigit<Tgt>(m + 1, past);
871
872   Tgt result;
873   /* static */ if (!std::is_signed<Tgt>::value) {
874     result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
875   } else {
876     auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
877     if (negative) {
878       result = -t;
879       FOLLY_RANGE_CHECK(is_non_positive(result), "Negative overflow");
880     } else {
881       result = t;
882       FOLLY_RANGE_CHECK(is_non_negative(result), "Overflow");
883     }
884   }
885   src->advance(m - src->data());
886   return result;
887 }
888
889 /**
890  * StringPiece to bool, with progress information. Alters the
891  * StringPiece parameter to munch the already-parsed characters.
892  */
893 template <class Tgt>
894 typename std::enable_if<
895   std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
896   Tgt>::type
897 to(StringPiece * src) {
898   return detail::str_to_bool(src);
899 }
900
901 namespace detail {
902
903 /**
904  * Enforce that the suffix following a number is made up only of whitespace.
905  */
906 inline void enforceWhitespace(const char* b, const char* e) {
907   for (; b != e; ++b) {
908     FOLLY_RANGE_CHECK(isspace(*b), to<std::string>("Non-whitespace: ", *b));
909   }
910 }
911
912 }  // namespace detail
913
914 /**
915  * String or StringPiece to integrals. Accepts leading and trailing
916  * whitespace, but no non-space trailing characters.
917  */
918 template <class Tgt>
919 typename std::enable_if<
920   std::is_integral<Tgt>::value,
921   Tgt>::type
922 to(StringPiece src) {
923   Tgt result = to<Tgt>(&src);
924   detail::enforceWhitespace(src.data(), src.data() + src.size());
925   return result;
926 }
927
928 /*******************************************************************************
929  * Conversions from string types to floating-point types.
930  ******************************************************************************/
931
932 /**
933  * StringPiece to double, with progress information. Alters the
934  * StringPiece parameter to munch the already-parsed characters.
935  */
936 template <class Tgt>
937 inline typename std::enable_if<
938   std::is_floating_point<Tgt>::value,
939   Tgt>::type
940 to(StringPiece *const src) {
941   using namespace double_conversion;
942   static StringToDoubleConverter
943     conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
944          | StringToDoubleConverter::ALLOW_LEADING_SPACES,
945          0.0,
946          // return this for junk input string
947          std::numeric_limits<double>::quiet_NaN(),
948          nullptr, nullptr);
949
950   FOLLY_RANGE_CHECK(!src->empty(), "No digits found in input string");
951
952   int length;
953   auto result = conv.StringToDouble(src->data(), src->size(),
954                                        &length); // processed char count
955
956   if (!std::isnan(result)) {
957     src->advance(length);
958     return result;
959   }
960
961   for (;; src->advance(1)) {
962     if (src->empty()) {
963       throw std::range_error("Unable to convert an empty string"
964                              " to a floating point value.");
965     }
966     if (!isspace(src->front())) {
967       break;
968     }
969   }
970
971   // Was that "inf[inity]"?
972   if (src->size() >= 3 && toupper((*src)[0]) == 'I'
973         && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
974     if (src->size() >= 8 &&
975         toupper((*src)[3]) == 'I' &&
976         toupper((*src)[4]) == 'N' &&
977         toupper((*src)[5]) == 'I' &&
978         toupper((*src)[6]) == 'T' &&
979         toupper((*src)[7]) == 'Y') {
980       src->advance(8);
981     } else {
982       src->advance(3);
983     }
984     return std::numeric_limits<Tgt>::infinity();
985   }
986
987   // Was that "-inf[inity]"?
988   if (src->size() >= 4 && toupper((*src)[0]) == '-'
989       && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
990       && toupper((*src)[3]) == 'F') {
991     if (src->size() >= 9 &&
992         toupper((*src)[4]) == 'I' &&
993         toupper((*src)[5]) == 'N' &&
994         toupper((*src)[6]) == 'I' &&
995         toupper((*src)[7]) == 'T' &&
996         toupper((*src)[8]) == 'Y') {
997       src->advance(9);
998     } else {
999       src->advance(4);
1000     }
1001     return -std::numeric_limits<Tgt>::infinity();
1002   }
1003
1004   // "nan"?
1005   if (src->size() >= 3 && toupper((*src)[0]) == 'N'
1006         && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
1007     src->advance(3);
1008     return std::numeric_limits<Tgt>::quiet_NaN();
1009   }
1010
1011   // "-nan"?
1012   if (src->size() >= 4 &&
1013       toupper((*src)[0]) == '-' &&
1014       toupper((*src)[1]) == 'N' &&
1015       toupper((*src)[2]) == 'A' &&
1016       toupper((*src)[3]) == 'N') {
1017     src->advance(4);
1018     return -std::numeric_limits<Tgt>::quiet_NaN();
1019   }
1020
1021   // All bets are off
1022   throw std::range_error("Unable to convert \"" + src->toString()
1023                          + "\" to a floating point value.");
1024 }
1025
1026 /**
1027  * Any string, const char*, or StringPiece to double.
1028  */
1029 template <class Tgt>
1030 typename std::enable_if<
1031   std::is_floating_point<Tgt>::value,
1032   Tgt>::type
1033 to(StringPiece src) {
1034   Tgt result = to<double>(&src);
1035   detail::enforceWhitespace(src.data(), src.data() + src.size());
1036   return result;
1037 }
1038
1039 /*******************************************************************************
1040  * Integral to floating point and back
1041  ******************************************************************************/
1042
1043 /**
1044  * Checked conversion from integral to flating point and back. The
1045  * result must be convertible back to the source type without loss of
1046  * precision. This seems Draconian but sometimes is what's needed, and
1047  * complements existing routines nicely. For various rounding
1048  * routines, see <math>.
1049  */
1050 template <class Tgt, class Src>
1051 typename std::enable_if<
1052   (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1053   ||
1054   (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1055   Tgt>::type
1056 to(const Src & value) {
1057   Tgt result = value;
1058   auto witness = static_cast<Src>(result);
1059   if (value != witness) {
1060     throw std::range_error(
1061       to<std::string>("to<>: loss of precision when converting ", value,
1062                       " to type ", typeid(Tgt).name()).c_str());
1063   }
1064   return result;
1065 }
1066
1067 /*******************************************************************************
1068  * Enum to anything and back
1069  ******************************************************************************/
1070
1071 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
1072 // std::underlying_type became available by gcc 4.7.0
1073
1074 template <class Tgt, class Src>
1075 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1076 to(const Src & value) {
1077   return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1078 }
1079
1080 template <class Tgt, class Src>
1081 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1082 to(const Src & value) {
1083   return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1084 }
1085
1086 #else
1087
1088 template <class Tgt, class Src>
1089 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1090 to(const Src & value) {
1091   /* static */ if (Src(-1) < 0) {
1092     /* static */ if (sizeof(Src) <= sizeof(int)) {
1093       return to<Tgt>(static_cast<int>(value));
1094     } else {
1095       return to<Tgt>(static_cast<long>(value));
1096     }
1097   } else {
1098     /* static */ if (sizeof(Src) <= sizeof(int)) {
1099       return to<Tgt>(static_cast<unsigned int>(value));
1100     } else {
1101       return to<Tgt>(static_cast<unsigned long>(value));
1102     }
1103   }
1104 }
1105
1106 template <class Tgt, class Src>
1107 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1108 to(const Src & value) {
1109   /* static */ if (Tgt(-1) < 0) {
1110     /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1111       return static_cast<Tgt>(to<int>(value));
1112     } else {
1113       return static_cast<Tgt>(to<long>(value));
1114     }
1115   } else {
1116     /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1117       return static_cast<Tgt>(to<unsigned int>(value));
1118     } else {
1119       return static_cast<Tgt>(to<unsigned long>(value));
1120     }
1121   }
1122 }
1123
1124 #endif // gcc 4.7 onwards
1125
1126 } // namespace folly
1127
1128 // FOLLY_CONV_INTERNAL is defined by Conv.cpp.  Keep the FOLLY_RANGE_CHECK
1129 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1130 // to avoid defining this global macro name in other files that include Conv.h.
1131 #ifndef FOLLY_CONV_INTERNAL
1132 #undef FOLLY_RANGE_CHECK
1133 #endif
1134
1135 #endif /* FOLLY_BASE_CONV_H_ */