folly: allow folly::init to build on systems without the symbolizer (macOS)
[folly.git] / folly / Conv.h
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
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 #pragma once
25
26 #include <algorithm>
27 #include <cctype>
28 #include <climits>
29 #include <cstddef>
30 #include <limits>
31 #include <stdexcept>
32 #include <string>
33 #include <tuple>
34 #include <type_traits>
35 #include <typeinfo>
36 #include <utility>
37
38 #include <boost/implicit_cast.hpp>
39 #include <double-conversion/double-conversion.h> // V8 JavaScript implementation
40
41 #include <folly/Demangle.h>
42 #include <folly/FBString.h>
43 #include <folly/Likely.h>
44 #include <folly/Range.h>
45 #include <folly/portability/Math.h>
46
47 namespace folly {
48
49 class ConversionError : public std::range_error {
50  public:
51   // Keep this in sync with kErrorStrings in Conv.cpp
52   enum Code {
53     SUCCESS,
54     EMPTY_INPUT_STRING,
55     NO_DIGITS,
56     BOOL_OVERFLOW,
57     BOOL_INVALID_VALUE,
58     NON_DIGIT_CHAR,
59     INVALID_LEADING_CHAR,
60     POSITIVE_OVERFLOW,
61     NEGATIVE_OVERFLOW,
62     STRING_TO_FLOAT_ERROR,
63     NON_WHITESPACE_AFTER_END,
64     ARITH_POSITIVE_OVERFLOW,
65     ARITH_NEGATIVE_OVERFLOW,
66     ARITH_LOSS_OF_PRECISION,
67     NUM_ERROR_CODES, // has to be the last entry
68   };
69
70   ConversionError(const std::string& str, Code code)
71       : std::range_error(str), code_(code) {}
72
73   ConversionError(const char* str, Code code)
74       : std::range_error(str), code_(code) {}
75
76   Code errorCode() const { return code_; }
77
78  private:
79   Code code_;
80 };
81
82 namespace detail {
83
84 ConversionError makeConversionError(
85     ConversionError::Code code,
86     const char* input,
87     size_t inputLen);
88
89 inline ConversionError makeConversionError(
90     ConversionError::Code code,
91     const std::string& str) {
92   return makeConversionError(code, str.data(), str.size());
93 }
94
95 inline ConversionError makeConversionError(
96     ConversionError::Code code,
97     StringPiece sp) {
98   return makeConversionError(code, sp.data(), sp.size());
99 }
100
101 /**
102  * Enforce that the suffix following a number is made up only of whitespace.
103  */
104 inline ConversionError::Code enforceWhitespaceErr(StringPiece sp) {
105   for (auto c : sp) {
106     if (!std::isspace(c)) {
107       return ConversionError::NON_WHITESPACE_AFTER_END;
108     }
109   }
110   return ConversionError::SUCCESS;
111 }
112
113 /**
114  * Keep this implementation around for prettyToDouble().
115  */
116 inline void enforceWhitespace(StringPiece sp) {
117   auto err = enforceWhitespaceErr(sp);
118   if (err != ConversionError::SUCCESS) {
119     throw detail::makeConversionError(err, sp);
120   }
121 }
122
123 /**
124  * A simple std::pair-like wrapper to wrap both a value and an error
125  */
126 template <typename T>
127 struct ConversionResult {
128   explicit ConversionResult(T v) : value(v) {}
129   explicit ConversionResult(ConversionError::Code e) : error(e) {}
130
131   bool success() const {
132     return error == ConversionError::SUCCESS;
133   }
134
135   T value;
136   ConversionError::Code error{ConversionError::SUCCESS};
137 };
138 }
139
140 /**
141  * The identity conversion function.
142  * to<T>(T) returns itself for all types T.
143  */
144 template <class Tgt, class Src>
145 typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
146 to(const Src & value) {
147   return value;
148 }
149
150 template <class Tgt, class Src>
151 typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
152 to(Src && value) {
153   return std::forward<Src>(value);
154 }
155
156 /*******************************************************************************
157  * Anything to string
158  ******************************************************************************/
159
160 namespace detail {
161
162 template <class T>
163 const T& getLastElement(const T & v) {
164   return v;
165 }
166
167 template <class T, class... Ts>
168 typename std::tuple_element<
169   sizeof...(Ts),
170   std::tuple<T, Ts...> >::type const&
171   getLastElement(const T&, const Ts&... vs) {
172   return getLastElement(vs...);
173 }
174
175 // This class exists to specialize away std::tuple_element in the case where we
176 // have 0 template arguments. Without this, Clang/libc++ will blow a
177 // static_assert even if tuple_element is protected by an enable_if.
178 template <class... Ts>
179 struct last_element {
180   typedef typename std::enable_if<
181     sizeof...(Ts) >= 1,
182     typename std::tuple_element<
183       sizeof...(Ts) - 1, std::tuple<Ts...>
184     >::type>::type type;
185 };
186
187 template <>
188 struct last_element<> {
189   typedef void type;
190 };
191
192 } // namespace detail
193
194 /*******************************************************************************
195  * Conversions from integral types to string types.
196  ******************************************************************************/
197
198 #if FOLLY_HAVE_INT128_T
199 namespace detail {
200
201 template <typename IntegerType>
202 constexpr unsigned int
203 digitsEnough() {
204   return (unsigned int)(ceil(sizeof(IntegerType) * CHAR_BIT * M_LN2 / M_LN10));
205 }
206
207 inline size_t
208 unsafeTelescope128(char * buffer, size_t room, unsigned __int128 x) {
209   typedef unsigned __int128 Usrc;
210   size_t p = room - 1;
211
212   while (x >= (Usrc(1) << 64)) { // Using 128-bit division while needed
213     const auto y = x / 10;
214     const auto digit = x % 10;
215
216     buffer[p--] = '0' + digit;
217     x = y;
218   }
219
220   uint64_t xx = x; // Moving to faster 64-bit division thereafter
221
222   while (xx >= 10) {
223     const auto y = xx / 10ULL;
224     const auto digit = xx % 10ULL;
225
226     buffer[p--] = '0' + digit;
227     xx = y;
228   }
229
230   buffer[p] = '0' + xx;
231
232   return p;
233 }
234
235 }
236 #endif
237
238 /**
239  * Returns the number of digits in the base 10 representation of an
240  * uint64_t. Useful for preallocating buffers and such. It's also used
241  * internally, see below. Measurements suggest that defining a
242  * separate overload for 32-bit integers is not worthwhile.
243  */
244
245 inline uint32_t digits10(uint64_t v) {
246 #ifdef __x86_64__
247
248   // For this arch we can get a little help from specialized CPU instructions
249   // which can count leading zeroes; 64 minus that is appx. log (base 2).
250   // Use that to approximate base-10 digits (log_10) and then adjust if needed.
251
252   // 10^i, defined for i 0 through 19.
253   // This is 20 * 8 == 160 bytes, which fits neatly into 5 cache lines
254   // (assuming a cache line size of 64).
255   static const uint64_t powersOf10[20] FOLLY_ALIGNED(64) = {
256       1,
257       10,
258       100,
259       1000,
260       10000,
261       100000,
262       1000000,
263       10000000,
264       100000000,
265       1000000000,
266       10000000000,
267       100000000000,
268       1000000000000,
269       10000000000000,
270       100000000000000,
271       1000000000000000,
272       10000000000000000,
273       100000000000000000,
274       1000000000000000000,
275       10000000000000000000UL,
276   };
277
278   // "count leading zeroes" operation not valid; for 0; special case this.
279   if UNLIKELY (! v) {
280     return 1;
281   }
282
283   // bits is in the ballpark of log_2(v).
284   const uint8_t leadingZeroes = __builtin_clzll(v);
285   const auto bits = 63 - leadingZeroes;
286
287   // approximate log_10(v) == log_10(2) * bits.
288   // Integer magic below: 77/256 is appx. 0.3010 (log_10(2)).
289   // The +1 is to make this the ceiling of the log_10 estimate.
290   const uint32_t minLength = 1 + ((bits * 77) >> 8);
291
292   // return that log_10 lower bound, plus adjust if input >= 10^(that bound)
293   // in case there's a small error and we misjudged length.
294   return minLength + (uint32_t) (UNLIKELY (v >= powersOf10[minLength]));
295
296 #else
297
298   uint32_t result = 1;
299   for (;;) {
300     if (LIKELY(v < 10)) return result;
301     if (LIKELY(v < 100)) return result + 1;
302     if (LIKELY(v < 1000)) return result + 2;
303     if (LIKELY(v < 10000)) return result + 3;
304     // Skip ahead by 4 orders of magnitude
305     v /= 10000U;
306     result += 4;
307   }
308
309 #endif
310 }
311
312 /**
313  * Copies the ASCII base 10 representation of v into buffer and
314  * returns the number of bytes written. Does NOT append a \0. Assumes
315  * the buffer points to digits10(v) bytes of valid memory. Note that
316  * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
317  * uint16_t needs at most 5 bytes, and so on. Measurements suggest
318  * that defining a separate overload for 32-bit integers is not
319  * worthwhile.
320  *
321  * This primitive is unsafe because it makes the size assumption and
322  * because it does not add a terminating \0.
323  */
324
325 inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
326   auto const result = digits10(v);
327   // WARNING: using size_t or pointer arithmetic for pos slows down
328   // the loop below 20x. This is because several 32-bit ops can be
329   // done in parallel, but only fewer 64-bit ones.
330   uint32_t pos = result - 1;
331   while (v >= 10) {
332     // Keep these together so a peephole optimization "sees" them and
333     // computes them in one shot.
334     auto const q = v / 10;
335     auto const r = static_cast<uint32_t>(v % 10);
336     buffer[pos--] = '0' + r;
337     v = q;
338   }
339   // Last digit is trivial to handle
340   buffer[pos] = static_cast<uint32_t>(v) + '0';
341   return result;
342 }
343
344 /**
345  * A single char gets appended.
346  */
347 template <class Tgt>
348 void toAppend(char value, Tgt * result) {
349   *result += value;
350 }
351
352 template<class T>
353 constexpr typename std::enable_if<
354   std::is_same<T, char>::value,
355   size_t>::type
356 estimateSpaceNeeded(T) {
357   return 1;
358 }
359
360 /**
361  * Everything implicitly convertible to const char* gets appended.
362  */
363 template <class Tgt, class Src>
364 typename std::enable_if<
365   std::is_convertible<Src, const char*>::value
366   && IsSomeString<Tgt>::value>::type
367 toAppend(Src value, Tgt * result) {
368   // Treat null pointers like an empty string, as in:
369   // operator<<(std::ostream&, const char*).
370   const char* c = value;
371   if (c) {
372     result->append(value);
373   }
374 }
375
376 template<class Src>
377 typename std::enable_if<
378   std::is_convertible<Src, const char*>::value,
379   size_t>::type
380 estimateSpaceNeeded(Src value) {
381   const char *c = value;
382   if (c) {
383     return folly::StringPiece(value).size();
384   };
385   return 0;
386 }
387
388 template<class Src>
389 typename std::enable_if<
390   (std::is_convertible<Src, folly::StringPiece>::value ||
391   IsSomeString<Src>::value) &&
392   !std::is_convertible<Src, const char*>::value,
393   size_t>::type
394 estimateSpaceNeeded(Src value) {
395   return folly::StringPiece(value).size();
396 }
397
398 template <>
399 inline size_t estimateSpaceNeeded(std::nullptr_t /* value */) {
400   return 0;
401 }
402
403 template<class Src>
404 typename std::enable_if<
405   std::is_pointer<Src>::value &&
406   IsSomeString<std::remove_pointer<Src>>::value,
407   size_t>::type
408 estimateSpaceNeeded(Src value) {
409   return value->size();
410 }
411
412 /**
413  * Strings get appended, too.
414  */
415 template <class Tgt, class Src>
416 typename std::enable_if<
417   IsSomeString<Src>::value && IsSomeString<Tgt>::value>::type
418 toAppend(const Src& value, Tgt * result) {
419   result->append(value);
420 }
421
422 /**
423  * and StringPiece objects too
424  */
425 template <class Tgt>
426 typename std::enable_if<
427    IsSomeString<Tgt>::value>::type
428 toAppend(StringPiece value, Tgt * result) {
429   result->append(value.data(), value.size());
430 }
431
432 /**
433  * There's no implicit conversion from fbstring to other string types,
434  * so make a specialization.
435  */
436 template <class Tgt>
437 typename std::enable_if<
438    IsSomeString<Tgt>::value>::type
439 toAppend(const fbstring& value, Tgt * result) {
440   result->append(value.data(), value.size());
441 }
442
443 #if FOLLY_HAVE_INT128_T
444 /**
445  * Special handling for 128 bit integers.
446  */
447
448 template <class Tgt>
449 void
450 toAppend(__int128 value, Tgt * result) {
451   typedef unsigned __int128 Usrc;
452   char buffer[detail::digitsEnough<unsigned __int128>() + 1];
453   size_t p;
454
455   if (value < 0) {
456     p = detail::unsafeTelescope128(buffer, sizeof(buffer), -Usrc(value));
457     buffer[--p] = '-';
458   } else {
459     p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
460   }
461
462   result->append(buffer + p, buffer + sizeof(buffer));
463 }
464
465 template <class Tgt>
466 void
467 toAppend(unsigned __int128 value, Tgt * result) {
468   char buffer[detail::digitsEnough<unsigned __int128>()];
469   size_t p;
470
471   p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
472
473   result->append(buffer + p, buffer + sizeof(buffer));
474 }
475
476 template<class T>
477 constexpr typename std::enable_if<
478   std::is_same<T, __int128>::value,
479   size_t>::type
480 estimateSpaceNeeded(T) {
481   return detail::digitsEnough<__int128>();
482 }
483
484 template<class T>
485 constexpr typename std::enable_if<
486   std::is_same<T, unsigned __int128>::value,
487   size_t>::type
488 estimateSpaceNeeded(T) {
489   return detail::digitsEnough<unsigned __int128>();
490 }
491
492 #endif
493
494 /**
495  * int32_t and int64_t to string (by appending) go through here. The
496  * result is APPENDED to a preexisting string passed as the second
497  * parameter. This should be efficient with fbstring because fbstring
498  * incurs no dynamic allocation below 23 bytes and no number has more
499  * than 22 bytes in its textual representation (20 for digits, one for
500  * sign, one for the terminating 0).
501  */
502 template <class Tgt, class Src>
503 typename std::enable_if<
504   std::is_integral<Src>::value && std::is_signed<Src>::value &&
505   IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
506 toAppend(Src value, Tgt * result) {
507   char buffer[20];
508   if (value < 0) {
509     result->push_back('-');
510     result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
511   } else {
512     result->append(buffer, uint64ToBufferUnsafe(value, buffer));
513   }
514 }
515
516 template <class Src>
517 typename std::enable_if<
518   std::is_integral<Src>::value && std::is_signed<Src>::value
519   && sizeof(Src) >= 4 && sizeof(Src) < 16,
520   size_t>::type
521 estimateSpaceNeeded(Src value) {
522   if (value < 0) {
523     // When "value" is the smallest negative, negating it would evoke
524     // undefined behavior, so, instead of writing "-value" below, we write
525     // "~static_cast<uint64_t>(value) + 1"
526     return 1 + digits10(~static_cast<uint64_t>(value) + 1);
527   }
528
529   return digits10(static_cast<uint64_t>(value));
530 }
531
532 /**
533  * As above, but for uint32_t and uint64_t.
534  */
535 template <class Tgt, class Src>
536 typename std::enable_if<
537   std::is_integral<Src>::value && !std::is_signed<Src>::value
538   && IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
539 toAppend(Src value, Tgt * result) {
540   char buffer[20];
541   result->append(buffer, uint64ToBufferUnsafe(value, buffer));
542 }
543
544 template <class Src>
545 typename std::enable_if<
546   std::is_integral<Src>::value && !std::is_signed<Src>::value
547   && sizeof(Src) >= 4 && sizeof(Src) < 16,
548   size_t>::type
549 estimateSpaceNeeded(Src value) {
550   return digits10(value);
551 }
552
553 /**
554  * All small signed and unsigned integers to string go through 32-bit
555  * types int32_t and uint32_t, respectively.
556  */
557 template <class Tgt, class Src>
558 typename std::enable_if<
559   std::is_integral<Src>::value
560   && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
561 toAppend(Src value, Tgt * result) {
562   typedef typename
563     std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
564     Intermediate;
565   toAppend<Tgt>(static_cast<Intermediate>(value), result);
566 }
567
568 template <class Src>
569 typename std::enable_if<
570   std::is_integral<Src>::value
571   && sizeof(Src) < 4
572   && !std::is_same<Src, char>::value,
573   size_t>::type
574 estimateSpaceNeeded(Src value) {
575   typedef typename
576     std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
577     Intermediate;
578   return estimateSpaceNeeded(static_cast<Intermediate>(value));
579 }
580
581 /**
582  * Enumerated values get appended as integers.
583  */
584 template <class Tgt, class Src>
585 typename std::enable_if<
586   std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
587 toAppend(Src value, Tgt * result) {
588   toAppend(
589       static_cast<typename std::underlying_type<Src>::type>(value), result);
590 }
591
592 template <class Src>
593 typename std::enable_if<
594   std::is_enum<Src>::value, size_t>::type
595 estimateSpaceNeeded(Src value) {
596   return estimateSpaceNeeded(
597       static_cast<typename std::underlying_type<Src>::type>(value));
598 }
599
600 /*******************************************************************************
601  * Conversions from floating-point types to string types.
602  ******************************************************************************/
603
604 namespace detail {
605 constexpr int kConvMaxDecimalInShortestLow = -6;
606 constexpr int kConvMaxDecimalInShortestHigh = 21;
607 } // folly::detail
608
609 /** Wrapper around DoubleToStringConverter **/
610 template <class Tgt, class Src>
611 typename std::enable_if<
612   std::is_floating_point<Src>::value
613   && IsSomeString<Tgt>::value>::type
614 toAppend(
615   Src value,
616   Tgt * result,
617   double_conversion::DoubleToStringConverter::DtoaMode mode,
618   unsigned int numDigits) {
619   using namespace double_conversion;
620   DoubleToStringConverter
621     conv(DoubleToStringConverter::NO_FLAGS,
622          "Infinity", "NaN", 'E',
623          detail::kConvMaxDecimalInShortestLow,
624          detail::kConvMaxDecimalInShortestHigh,
625          6,   // max leading padding zeros
626          1);  // max trailing padding zeros
627   char buffer[256];
628   StringBuilder builder(buffer, sizeof(buffer));
629   switch (mode) {
630     case DoubleToStringConverter::SHORTEST:
631       conv.ToShortest(value, &builder);
632       break;
633     case DoubleToStringConverter::FIXED:
634       conv.ToFixed(value, numDigits, &builder);
635       break;
636     default:
637       CHECK(mode == DoubleToStringConverter::PRECISION);
638       conv.ToPrecision(value, numDigits, &builder);
639       break;
640   }
641   const size_t length = builder.position();
642   builder.Finalize();
643   result->append(buffer, length);
644 }
645
646 /**
647  * As above, but for floating point
648  */
649 template <class Tgt, class Src>
650 typename std::enable_if<
651   std::is_floating_point<Src>::value
652   && IsSomeString<Tgt>::value>::type
653 toAppend(Src value, Tgt * result) {
654   toAppend(
655     value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
656 }
657
658 /**
659  * Upper bound of the length of the output from
660  * DoubleToStringConverter::ToShortest(double, StringBuilder*),
661  * as used in toAppend(double, string*).
662  */
663 template <class Src>
664 typename std::enable_if<
665   std::is_floating_point<Src>::value, size_t>::type
666 estimateSpaceNeeded(Src value) {
667   // kBase10MaximalLength is 17. We add 1 for decimal point,
668   // e.g. 10.0/9 is 17 digits and 18 characters, including the decimal point.
669   constexpr int kMaxMantissaSpace =
670     double_conversion::DoubleToStringConverter::kBase10MaximalLength + 1;
671   // strlen("E-") + digits10(numeric_limits<double>::max_exponent10)
672   constexpr int kMaxExponentSpace = 2 + 3;
673   static const int kMaxPositiveSpace = std::max({
674       // E.g. 1.1111111111111111E-100.
675       kMaxMantissaSpace + kMaxExponentSpace,
676       // E.g. 0.000001.1111111111111111, if kConvMaxDecimalInShortestLow is -6.
677       kMaxMantissaSpace - detail::kConvMaxDecimalInShortestLow,
678       // If kConvMaxDecimalInShortestHigh is 21, then 1e21 is the smallest
679       // number > 1 which ToShortest outputs in exponential notation,
680       // so 21 is the longest non-exponential number > 1.
681       detail::kConvMaxDecimalInShortestHigh
682     });
683   return kMaxPositiveSpace + (value < 0);  // +1 for minus sign, if negative
684 }
685
686 /**
687  * This can be specialized, together with adding specialization
688  * for estimateSpaceNeed for your type, so that we allocate
689  * as much as you need instead of the default
690  */
691 template<class Src>
692 struct HasLengthEstimator : std::false_type {};
693
694 template <class Src>
695 constexpr typename std::enable_if<
696   !std::is_fundamental<Src>::value
697 #if FOLLY_HAVE_INT128_T
698   // On OSX 10.10, is_fundamental<__int128> is false :-O
699   && !std::is_same<__int128, Src>::value
700   && !std::is_same<unsigned __int128, Src>::value
701 #endif
702   && !IsSomeString<Src>::value
703   && !std::is_convertible<Src, const char*>::value
704   && !std::is_convertible<Src, StringPiece>::value
705   && !std::is_enum<Src>::value
706   && !HasLengthEstimator<Src>::value,
707   size_t>::type
708 estimateSpaceNeeded(const Src&) {
709   return sizeof(Src) + 1; // dumbest best effort ever?
710 }
711
712 namespace detail {
713
714 template <class Tgt>
715 typename std::enable_if<IsSomeString<Tgt>::value, size_t>::type
716 estimateSpaceToReserve(size_t sofar, Tgt*) {
717   return sofar;
718 }
719
720 template <class T, class... Ts>
721 size_t estimateSpaceToReserve(size_t sofar, const T& v, const Ts&... vs) {
722   return estimateSpaceToReserve(sofar + estimateSpaceNeeded(v), vs...);
723 }
724
725 template<class...Ts>
726 void reserveInTarget(const Ts&...vs) {
727   getLastElement(vs...)->reserve(estimateSpaceToReserve(0, vs...));
728 }
729
730 template<class Delimiter, class...Ts>
731 void reserveInTargetDelim(const Delimiter& d, const Ts&...vs) {
732   static_assert(sizeof...(vs) >= 2, "Needs at least 2 args");
733   size_t fordelim = (sizeof...(vs) - 2) *
734       estimateSpaceToReserve(0, d, static_cast<std::string*>(nullptr));
735   getLastElement(vs...)->reserve(estimateSpaceToReserve(fordelim, vs...));
736 }
737
738 /**
739  * Variadic base case: append one element
740  */
741 template <class T, class Tgt>
742 typename std::enable_if<
743   IsSomeString<typename std::remove_pointer<Tgt>::type>
744   ::value>::type
745 toAppendStrImpl(const T& v, Tgt result) {
746   toAppend(v, result);
747 }
748
749 template <class T, class... Ts>
750 typename std::enable_if<sizeof...(Ts) >= 2
751   && IsSomeString<
752   typename std::remove_pointer<
753     typename detail::last_element<Ts...>::type
754   >::type>::value>::type
755 toAppendStrImpl(const T& v, const Ts&... vs) {
756   toAppend(v, getLastElement(vs...));
757   toAppendStrImpl(vs...);
758 }
759
760 template <class Delimiter, class T, class Tgt>
761 typename std::enable_if<
762     IsSomeString<typename std::remove_pointer<Tgt>::type>::value>::type
763 toAppendDelimStrImpl(const Delimiter& /* delim */, const T& v, Tgt result) {
764   toAppend(v, result);
765 }
766
767 template <class Delimiter, class T, class... Ts>
768 typename std::enable_if<sizeof...(Ts) >= 2
769   && IsSomeString<
770   typename std::remove_pointer<
771     typename detail::last_element<Ts...>::type
772   >::type>::value>::type
773 toAppendDelimStrImpl(const Delimiter& delim, const T& v, const Ts&... vs) {
774   // we are really careful here, calling toAppend with just one element does
775   // not try to estimate space needed (as we already did that). If we call
776   // toAppend(v, delim, ....) we would do unnecesary size calculation
777   toAppend(v, detail::getLastElement(vs...));
778   toAppend(delim, detail::getLastElement(vs...));
779   toAppendDelimStrImpl(delim, vs...);
780 }
781 } // folly::detail
782
783
784 /**
785  * Variadic conversion to string. Appends each element in turn.
786  * If we have two or more things to append, we it will not reserve
787  * the space for them and will depend on strings exponential growth.
788  * If you just append once consider using toAppendFit which reserves
789  * the space needed (but does not have exponential as a result).
790  *
791  * Custom implementations of toAppend() can be provided in the same namespace as
792  * the type to customize printing. estimateSpaceNeed() may also be provided to
793  * avoid reallocations in toAppendFit():
794  *
795  * namespace other_namespace {
796  *
797  * template <class String>
798  * void toAppend(const OtherType&, String* out);
799  *
800  * // optional
801  * size_t estimateSpaceNeeded(const OtherType&);
802  *
803  * }
804  */
805 template <class... Ts>
806 typename std::enable_if<sizeof...(Ts) >= 3
807   && IsSomeString<
808   typename std::remove_pointer<
809     typename detail::last_element<Ts...>::type
810   >::type>::value>::type
811 toAppend(const Ts&... vs) {
812   ::folly::detail::toAppendStrImpl(vs...);
813 }
814
815 #ifdef _MSC_VER
816 // Special case pid_t on MSVC, because it's a void* rather than an
817 // integral type. We can't do a global special case because this is already
818 // dangerous enough (as most pointers will implicitly convert to a void*)
819 // just doing it for MSVC.
820 template <class Tgt>
821 void toAppend(const pid_t a, Tgt* res) {
822   toAppend(uint64_t(a), res);
823 }
824 #endif
825
826 /**
827  * Special version of the call that preallocates exaclty as much memory
828  * as need for arguments to be stored in target. This means we are
829  * not doing exponential growth when we append. If you are using it
830  * in a loop you are aiming at your foot with a big perf-destroying
831  * bazooka.
832  * On the other hand if you are appending to a string once, this
833  * will probably save a few calls to malloc.
834  */
835 template <class... Ts>
836 typename std::enable_if<
837   IsSomeString<
838   typename std::remove_pointer<
839     typename detail::last_element<Ts...>::type
840   >::type>::value>::type
841 toAppendFit(const Ts&... vs) {
842   ::folly::detail::reserveInTarget(vs...);
843   toAppend(vs...);
844 }
845
846 template <class Ts>
847 void toAppendFit(const Ts&) {}
848
849 /**
850  * Variadic base case: do nothing.
851  */
852 template <class Tgt>
853 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
854     Tgt* /* result */) {}
855
856 /**
857  * Variadic base case: do nothing.
858  */
859 template <class Delimiter, class Tgt>
860 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
861     const Delimiter& /* delim */, Tgt* /* result */) {}
862
863 /**
864  * 1 element: same as toAppend.
865  */
866 template <class Delimiter, class T, class Tgt>
867 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
868     const Delimiter& /* delim */, const T& v, Tgt* tgt) {
869   toAppend(v, tgt);
870 }
871
872 /**
873  * Append to string with a delimiter in between elements. Check out
874  * comments for toAppend for details about memory allocation.
875  */
876 template <class Delimiter, class... Ts>
877 typename std::enable_if<sizeof...(Ts) >= 3
878   && IsSomeString<
879   typename std::remove_pointer<
880     typename detail::last_element<Ts...>::type
881   >::type>::value>::type
882 toAppendDelim(const Delimiter& delim, const Ts&... vs) {
883   detail::toAppendDelimStrImpl(delim, vs...);
884 }
885
886 /**
887  * Detail in comment for toAppendFit
888  */
889 template <class Delimiter, class... Ts>
890 typename std::enable_if<
891   IsSomeString<
892   typename std::remove_pointer<
893     typename detail::last_element<Ts...>::type
894   >::type>::value>::type
895 toAppendDelimFit(const Delimiter& delim, const Ts&... vs) {
896   detail::reserveInTargetDelim(delim, vs...);
897   toAppendDelim(delim, vs...);
898 }
899
900 template <class De, class Ts>
901 void toAppendDelimFit(const De&, const Ts&) {}
902
903 /**
904  * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
905  * for all types.
906  */
907 template <class Tgt, class... Ts>
908 typename std::enable_if<
909   IsSomeString<Tgt>::value && (
910     sizeof...(Ts) != 1 ||
911     !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
912   Tgt>::type
913 to(const Ts&... vs) {
914   Tgt result;
915   toAppendFit(vs..., &result);
916   return result;
917 }
918
919 /**
920  * toDelim<SomeString>(SomeString str) returns itself.
921  */
922 template <class Tgt, class Delim, class Src>
923 typename std::enable_if<IsSomeString<Tgt>::value &&
924                             std::is_same<Tgt, Src>::value,
925                         Tgt>::type
926 toDelim(const Delim& /* delim */, const Src& value) {
927   return value;
928 }
929
930 /**
931  * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
932  * back-end for all types.
933  */
934 template <class Tgt, class Delim, class... Ts>
935 typename std::enable_if<
936   IsSomeString<Tgt>::value && (
937     sizeof...(Ts) != 1 ||
938     !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
939   Tgt>::type
940 toDelim(const Delim& delim, const Ts&... vs) {
941   Tgt result;
942   toAppendDelimFit(delim, vs..., &result);
943   return result;
944 }
945
946 /*******************************************************************************
947  * Conversions from string types to integral types.
948  ******************************************************************************/
949
950 namespace detail {
951
952 ConversionResult<bool> str_to_bool(StringPiece* src);
953
954 template <typename T>
955 ConversionResult<T> str_to_floating(StringPiece* src);
956
957 extern template ConversionResult<float> str_to_floating<float>(
958     StringPiece* src);
959 extern template ConversionResult<double> str_to_floating<double>(
960     StringPiece* src);
961
962 template <class Tgt>
963 ConversionResult<Tgt> digits_to(const char* b, const char* e);
964
965 extern template ConversionResult<char> digits_to<char>(
966     const char*,
967     const char*);
968 extern template ConversionResult<signed char> digits_to<signed char>(
969     const char*,
970     const char*);
971 extern template ConversionResult<unsigned char> digits_to<unsigned char>(
972     const char*,
973     const char*);
974
975 extern template ConversionResult<short> digits_to<short>(
976     const char*,
977     const char*);
978 extern template ConversionResult<unsigned short> digits_to<unsigned short>(
979     const char*,
980     const char*);
981
982 extern template ConversionResult<int> digits_to<int>(const char*, const char*);
983 extern template ConversionResult<unsigned int> digits_to<unsigned int>(
984     const char*,
985     const char*);
986
987 extern template ConversionResult<long> digits_to<long>(
988     const char*,
989     const char*);
990 extern template ConversionResult<unsigned long> digits_to<unsigned long>(
991     const char*,
992     const char*);
993
994 extern template ConversionResult<long long> digits_to<long long>(
995     const char*,
996     const char*);
997 extern template ConversionResult<unsigned long long>
998 digits_to<unsigned long long>(const char*, const char*);
999
1000 #if FOLLY_HAVE_INT128_T
1001 extern template ConversionResult<__int128> digits_to<__int128>(
1002     const char*,
1003     const char*);
1004 extern template ConversionResult<unsigned __int128>
1005 digits_to<unsigned __int128>(const char*, const char*);
1006 #endif
1007
1008 template <class T>
1009 ConversionResult<T> str_to_integral(StringPiece* src);
1010
1011 extern template ConversionResult<char> str_to_integral<char>(StringPiece* src);
1012 extern template ConversionResult<signed char> str_to_integral<signed char>(
1013     StringPiece* src);
1014 extern template ConversionResult<unsigned char> str_to_integral<unsigned char>(
1015     StringPiece* src);
1016
1017 extern template ConversionResult<short> str_to_integral<short>(
1018     StringPiece* src);
1019 extern template ConversionResult<unsigned short>
1020 str_to_integral<unsigned short>(StringPiece* src);
1021
1022 extern template ConversionResult<int> str_to_integral<int>(StringPiece* src);
1023 extern template ConversionResult<unsigned int> str_to_integral<unsigned int>(
1024     StringPiece* src);
1025
1026 extern template ConversionResult<long> str_to_integral<long>(StringPiece* src);
1027 extern template ConversionResult<unsigned long> str_to_integral<unsigned long>(
1028     StringPiece* src);
1029
1030 extern template ConversionResult<long long> str_to_integral<long long>(
1031     StringPiece* src);
1032 extern template ConversionResult<unsigned long long>
1033 str_to_integral<unsigned long long>(StringPiece* src);
1034
1035 #if FOLLY_HAVE_INT128_T
1036 extern template ConversionResult<__int128> str_to_integral<__int128>(
1037     StringPiece* src);
1038 extern template ConversionResult<unsigned __int128>
1039 str_to_integral<unsigned __int128>(StringPiece* src);
1040 #endif
1041
1042 template <typename T>
1043 typename std::enable_if<std::is_same<T, bool>::value, ConversionResult<T>>::type
1044 convertTo(StringPiece* src) {
1045   return str_to_bool(src);
1046 }
1047
1048 template <typename T>
1049 typename std::enable_if<
1050     std::is_floating_point<T>::value, ConversionResult<T>>::type
1051 convertTo(StringPiece* src) {
1052   return str_to_floating<T>(src);
1053 }
1054
1055 template <typename T>
1056 typename std::enable_if<
1057     std::is_integral<T>::value && !std::is_same<T, bool>::value,
1058     ConversionResult<T>>::type
1059 convertTo(StringPiece* src) {
1060   return str_to_integral<T>(src);
1061 }
1062
1063 template <typename T>
1064 struct WrapperInfo { using type = T; };
1065
1066 template <typename T, typename Gen>
1067 typename std::enable_if<
1068     std::is_same<typename WrapperInfo<T>::type, T>::value, T>::type
1069 inline wrap(ConversionResult<typename WrapperInfo<T>::type> res, Gen&& gen) {
1070   if (LIKELY(res.success())) {
1071     return res.value;
1072   }
1073   throw detail::makeConversionError(res.error, gen());
1074 }
1075
1076 } // namespace detail
1077
1078 /**
1079  * String represented as a pair of pointers to char to unsigned
1080  * integrals. Assumes NO whitespace before or after.
1081  */
1082 template <typename Tgt>
1083 typename std::enable_if<
1084     std::is_integral<typename detail::WrapperInfo<Tgt>::type>::value &&
1085     !std::is_same<typename detail::WrapperInfo<Tgt>::type, bool>::value,
1086     Tgt>::type
1087 to(const char* b, const char* e) {
1088   auto res = detail::digits_to<typename detail::WrapperInfo<Tgt>::type>(b, e);
1089   return detail::wrap<Tgt>(res, [&] { return StringPiece(b, e); });
1090 }
1091
1092 /*******************************************************************************
1093  * Conversions from string types to arithmetic types.
1094  ******************************************************************************/
1095
1096 /**
1097  * Parsing strings to numeric types. These routines differ from
1098  * parseTo(str, numeric) routines in that they take a POINTER TO a StringPiece
1099  * and alter that StringPiece to reflect progress information.
1100  */
1101 template <typename Tgt>
1102 typename std::enable_if<
1103     std::is_arithmetic<typename detail::WrapperInfo<Tgt>::type>::value>::type
1104 parseTo(StringPiece* src, Tgt& out) {
1105   auto res = detail::convertTo<typename detail::WrapperInfo<Tgt>::type>(src);
1106   out = detail::wrap<Tgt>(res, [&] { return *src; });
1107 }
1108
1109 template <typename Tgt>
1110 typename std::enable_if<
1111     std::is_arithmetic<typename detail::WrapperInfo<Tgt>::type>::value>::type
1112 parseTo(StringPiece src, Tgt& out) {
1113   auto res = detail::convertTo<typename detail::WrapperInfo<Tgt>::type>(&src);
1114   if (LIKELY(res.success())) {
1115     res.error = detail::enforceWhitespaceErr(src);
1116   }
1117   out = detail::wrap<Tgt>(res, [&] { return src; });
1118 }
1119
1120 /*******************************************************************************
1121  * Integral / Floating Point to integral / Floating Point
1122  ******************************************************************************/
1123
1124 /**
1125  * Unchecked conversion from arithmetic to boolean. This is different from the
1126  * other arithmetic conversions because we use the C convention of treating any
1127  * non-zero value as true, instead of range checking.
1128  */
1129 template <class Tgt, class Src>
1130 typename std::enable_if<
1131     std::is_arithmetic<Src>::value && !std::is_same<Tgt, Src>::value &&
1132         std::is_same<Tgt, bool>::value,
1133     Tgt>::type
1134 to(const Src& value) {
1135   return value != Src();
1136 }
1137
1138 namespace detail {
1139
1140 /**
1141  * Checked conversion from integral to integral. The checks are only
1142  * performed when meaningful, e.g. conversion from int to long goes
1143  * unchecked.
1144  */
1145 template <class Tgt, class Src>
1146 typename std::enable_if<
1147     std::is_integral<Src>::value && !std::is_same<Tgt, Src>::value &&
1148         !std::is_same<Tgt, bool>::value &&
1149         std::is_integral<Tgt>::value,
1150     ConversionResult<Tgt>>::type
1151 convertTo(const Src& value) {
1152   /* static */ if (
1153       std::numeric_limits<Tgt>::max() < std::numeric_limits<Src>::max()) {
1154     if (greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)) {
1155       return ConversionResult<Tgt>(ConversionError::ARITH_POSITIVE_OVERFLOW);
1156     }
1157   }
1158   /* static */ if (
1159       std::is_signed<Src>::value &&
1160       (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
1161     if (less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)) {
1162       return ConversionResult<Tgt>(ConversionError::ARITH_NEGATIVE_OVERFLOW);
1163     }
1164   }
1165   return ConversionResult<Tgt>(static_cast<Tgt>(value));
1166 }
1167
1168 /**
1169  * Checked conversion from floating to floating. The checks are only
1170  * performed when meaningful, e.g. conversion from float to double goes
1171  * unchecked.
1172  */
1173 template <class Tgt, class Src>
1174 typename std::enable_if<
1175     std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value &&
1176         !std::is_same<Tgt, Src>::value,
1177     ConversionResult<Tgt>>::type
1178 convertTo(const Src& value) {
1179   /* static */ if (
1180       std::numeric_limits<Tgt>::max() < std::numeric_limits<Src>::max()) {
1181     if (value > std::numeric_limits<Tgt>::max()) {
1182       return ConversionResult<Tgt>(ConversionError::ARITH_POSITIVE_OVERFLOW);
1183     }
1184     if (value < std::numeric_limits<Tgt>::lowest()) {
1185       return ConversionResult<Tgt>(ConversionError::ARITH_NEGATIVE_OVERFLOW);
1186     }
1187   }
1188   return ConversionResult<Tgt>(boost::implicit_cast<Tgt>(value));
1189 }
1190
1191 /**
1192  * Check if a floating point value can safely be converted to an
1193  * integer value without triggering undefined behaviour.
1194  */
1195 template <typename Tgt, typename Src>
1196 inline typename std::enable_if<
1197     std::is_floating_point<Src>::value && std::is_integral<Tgt>::value &&
1198         !std::is_same<Tgt, bool>::value,
1199     bool>::type
1200 checkConversion(const Src& value) {
1201   constexpr Src tgtMaxAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::max());
1202   constexpr Src tgtMinAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::min());
1203   if (value >= tgtMaxAsSrc) {
1204     if (value > tgtMaxAsSrc) {
1205       return false;
1206     }
1207     const Src mmax = folly::nextafter(tgtMaxAsSrc, Src());
1208     if (static_cast<Tgt>(value - mmax) >
1209         std::numeric_limits<Tgt>::max() - static_cast<Tgt>(mmax)) {
1210       return false;
1211     }
1212   } else if (std::is_signed<Tgt>::value && value <= tgtMinAsSrc) {
1213     if (value < tgtMinAsSrc) {
1214       return false;
1215     }
1216     const Src mmin = folly::nextafter(tgtMinAsSrc, Src());
1217     if (static_cast<Tgt>(value - mmin) <
1218         std::numeric_limits<Tgt>::min() - static_cast<Tgt>(mmin)) {
1219       return false;
1220     }
1221   }
1222   return true;
1223 }
1224
1225 // Integers can always safely be converted to floating point values
1226 template <typename Tgt, typename Src>
1227 constexpr typename std::enable_if<
1228     std::is_integral<Src>::value && std::is_floating_point<Tgt>::value,
1229     bool>::type
1230 checkConversion(const Src&) {
1231   return true;
1232 }
1233
1234 // Also, floating point values can always be safely converted to bool
1235 // Per the standard, any floating point value that is not zero will yield true
1236 template <typename Tgt, typename Src>
1237 constexpr typename std::enable_if<
1238     std::is_floating_point<Src>::value && std::is_same<Tgt, bool>::value,
1239     bool>::type
1240 checkConversion(const Src&) {
1241   return true;
1242 }
1243
1244 /**
1245  * Checked conversion from integral to floating point and back. The
1246  * result must be convertible back to the source type without loss of
1247  * precision. This seems Draconian but sometimes is what's needed, and
1248  * complements existing routines nicely. For various rounding
1249  * routines, see <math>.
1250  */
1251 template <typename Tgt, typename Src>
1252 typename std::enable_if<
1253     (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value) ||
1254         (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1255     ConversionResult<Tgt>>::type
1256 convertTo(const Src& value) {
1257   if (LIKELY(checkConversion<Tgt>(value))) {
1258     Tgt result = static_cast<Tgt>(value);
1259     if (LIKELY(checkConversion<Src>(result))) {
1260       Src witness = static_cast<Src>(result);
1261       if (LIKELY(value == witness)) {
1262         return ConversionResult<Tgt>(result);
1263       }
1264     }
1265   }
1266   return ConversionResult<Tgt>(ConversionError::ARITH_LOSS_OF_PRECISION);
1267 }
1268
1269 template <typename Tgt, typename Src>
1270 inline std::string errorValue(const Src& value) {
1271 #ifdef FOLLY_HAS_RTTI
1272   return to<std::string>("(", demangle(typeid(Tgt)), ") ", value);
1273 #else
1274   return to<std::string>(value);
1275 #endif
1276 }
1277
1278 template <typename Tgt, typename Src>
1279 using IsArithToArith = std::integral_constant<
1280     bool,
1281     !std::is_same<Tgt, Src>::value && !std::is_same<Tgt, bool>::value &&
1282         std::is_arithmetic<Src>::value &&
1283         std::is_arithmetic<Tgt>::value>;
1284
1285 } // namespace detail
1286
1287 template <typename Tgt, typename Src>
1288 typename std::enable_if<
1289     detail::IsArithToArith<
1290         typename detail::WrapperInfo<Tgt>::type, Src>::value, Tgt>::type
1291 to(const Src& value) {
1292   auto res = detail::convertTo<typename detail::WrapperInfo<Tgt>::type>(value);
1293   return detail::wrap<Tgt>(res, [&] {
1294     return detail::errorValue<typename detail::WrapperInfo<Tgt>::type>(value);
1295   });
1296 }
1297
1298 /*******************************************************************************
1299  * Custom Conversions
1300  *
1301  * Any type can be used with folly::to by implementing parseTo. The
1302  * implementation should be provided in the namespace of the type to facilitate
1303  * argument-dependent lookup:
1304  *
1305  * namespace other_namespace {
1306  * void parseTo(::folly::StringPiece, OtherType&);
1307  * }
1308  ******************************************************************************/
1309 template <class T>
1310 typename std::enable_if<std::is_enum<T>::value>::type
1311 parseTo(StringPiece in, T& out) {
1312   typename std::underlying_type<T>::type tmp;
1313   parseTo(in, tmp);
1314   out = static_cast<T>(tmp);
1315 }
1316
1317 inline void parseTo(StringPiece in, StringPiece& out) {
1318   out = in;
1319 }
1320
1321 inline void parseTo(StringPiece in, std::string& out) {
1322   out.clear();
1323   out.append(in.data(), in.size());
1324 }
1325
1326 inline void parseTo(StringPiece in, fbstring& out) {
1327   out.clear();
1328   out.append(in.data(), in.size());
1329 }
1330
1331 /**
1332  * String or StringPiece to target conversion. Accepts leading and trailing
1333  * whitespace, but no non-space trailing characters.
1334  */
1335
1336 template <class Tgt>
1337 typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
1338 to(StringPiece src) {
1339   Tgt result;
1340   parseTo(src, result);
1341   return result;
1342 }
1343
1344 template <class Tgt>
1345 Tgt to(StringPiece* src) {
1346   Tgt result;
1347   parseTo(src, result);
1348   return result;
1349 }
1350
1351 /*******************************************************************************
1352  * Enum to anything and back
1353  ******************************************************************************/
1354
1355 template <class Tgt, class Src>
1356 typename std::enable_if<
1357   std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1358 to(const Src & value) {
1359   return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1360 }
1361
1362 template <class Tgt, class Src>
1363 typename std::enable_if<
1364   std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1365 to(const Src & value) {
1366   return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1367 }
1368
1369 } // namespace folly