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