Clean up int128_t macro gating
[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  * Ubiquitous helper template for writing string appenders
362  */
363 template <class T> struct IsSomeString {
364   enum { value = std::is_same<T, std::string>::value
365          || std::is_same<T, fbstring>::value };
366 };
367
368 /**
369  * Everything implicitly convertible to const char* gets appended.
370  */
371 template <class Tgt, class Src>
372 typename std::enable_if<
373   std::is_convertible<Src, const char*>::value
374   && IsSomeString<Tgt>::value>::type
375 toAppend(Src value, Tgt * result) {
376   // Treat null pointers like an empty string, as in:
377   // operator<<(std::ostream&, const char*).
378   const char* c = value;
379   if (c) {
380     result->append(value);
381   }
382 }
383
384 template<class Src>
385 typename std::enable_if<
386   std::is_convertible<Src, const char*>::value,
387   size_t>::type
388 estimateSpaceNeeded(Src value) {
389   const char *c = value;
390   if (c) {
391     return folly::StringPiece(value).size();
392   };
393   return 0;
394 }
395
396 template<class Src>
397 typename std::enable_if<
398   (std::is_convertible<Src, folly::StringPiece>::value ||
399   IsSomeString<Src>::value) &&
400   !std::is_convertible<Src, const char*>::value,
401   size_t>::type
402 estimateSpaceNeeded(Src value) {
403   return folly::StringPiece(value).size();
404 }
405
406 template <>
407 inline size_t estimateSpaceNeeded(std::nullptr_t /* value */) {
408   return 0;
409 }
410
411 template<class Src>
412 typename std::enable_if<
413   std::is_pointer<Src>::value &&
414   IsSomeString<std::remove_pointer<Src>>::value,
415   size_t>::type
416 estimateSpaceNeeded(Src value) {
417   return value->size();
418 }
419
420 /**
421  * Strings get appended, too.
422  */
423 template <class Tgt, class Src>
424 typename std::enable_if<
425   IsSomeString<Src>::value && IsSomeString<Tgt>::value>::type
426 toAppend(const Src& value, Tgt * result) {
427   result->append(value);
428 }
429
430 /**
431  * and StringPiece objects too
432  */
433 template <class Tgt>
434 typename std::enable_if<
435    IsSomeString<Tgt>::value>::type
436 toAppend(StringPiece value, Tgt * result) {
437   result->append(value.data(), value.size());
438 }
439
440 /**
441  * There's no implicit conversion from fbstring to other string types,
442  * so make a specialization.
443  */
444 template <class Tgt>
445 typename std::enable_if<
446    IsSomeString<Tgt>::value>::type
447 toAppend(const fbstring& value, Tgt * result) {
448   result->append(value.data(), value.size());
449 }
450
451 #if FOLLY_HAVE_INT128_T
452 /**
453  * Special handling for 128 bit integers.
454  */
455
456 template <class Tgt>
457 void
458 toAppend(__int128 value, Tgt * result) {
459   typedef unsigned __int128 Usrc;
460   char buffer[detail::digitsEnough<unsigned __int128>() + 1];
461   size_t p;
462
463   if (value < 0) {
464     p = detail::unsafeTelescope128(buffer, sizeof(buffer), -Usrc(value));
465     buffer[--p] = '-';
466   } else {
467     p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
468   }
469
470   result->append(buffer + p, buffer + sizeof(buffer));
471 }
472
473 template <class Tgt>
474 void
475 toAppend(unsigned __int128 value, Tgt * result) {
476   char buffer[detail::digitsEnough<unsigned __int128>()];
477   size_t p;
478
479   p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
480
481   result->append(buffer + p, buffer + sizeof(buffer));
482 }
483
484 template<class T>
485 constexpr typename std::enable_if<
486   std::is_same<T, __int128>::value,
487   size_t>::type
488 estimateSpaceNeeded(T) {
489   return detail::digitsEnough<__int128>();
490 }
491
492 template<class T>
493 constexpr typename std::enable_if<
494   std::is_same<T, unsigned __int128>::value,
495   size_t>::type
496 estimateSpaceNeeded(T) {
497   return detail::digitsEnough<unsigned __int128>();
498 }
499
500 #endif
501
502 /**
503  * int32_t and int64_t to string (by appending) go through here. The
504  * result is APPENDED to a preexisting string passed as the second
505  * parameter. This should be efficient with fbstring because fbstring
506  * incurs no dynamic allocation below 23 bytes and no number has more
507  * than 22 bytes in its textual representation (20 for digits, one for
508  * sign, one for the terminating 0).
509  */
510 template <class Tgt, class Src>
511 typename std::enable_if<
512   std::is_integral<Src>::value && std::is_signed<Src>::value &&
513   IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
514 toAppend(Src value, Tgt * result) {
515   char buffer[20];
516   if (value < 0) {
517     result->push_back('-');
518     result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
519   } else {
520     result->append(buffer, uint64ToBufferUnsafe(value, buffer));
521   }
522 }
523
524 template <class Src>
525 typename std::enable_if<
526   std::is_integral<Src>::value && std::is_signed<Src>::value
527   && sizeof(Src) >= 4 && sizeof(Src) < 16,
528   size_t>::type
529 estimateSpaceNeeded(Src value) {
530   if (value < 0) {
531     // When "value" is the smallest negative, negating it would evoke
532     // undefined behavior, so, instead of writing "-value" below, we write
533     // "~static_cast<uint64_t>(value) + 1"
534     return 1 + digits10(~static_cast<uint64_t>(value) + 1);
535   }
536
537   return digits10(static_cast<uint64_t>(value));
538 }
539
540 /**
541  * As above, but for uint32_t and uint64_t.
542  */
543 template <class Tgt, class Src>
544 typename std::enable_if<
545   std::is_integral<Src>::value && !std::is_signed<Src>::value
546   && IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
547 toAppend(Src value, Tgt * result) {
548   char buffer[20];
549   result->append(buffer, uint64ToBufferUnsafe(value, buffer));
550 }
551
552 template <class Src>
553 typename std::enable_if<
554   std::is_integral<Src>::value && !std::is_signed<Src>::value
555   && sizeof(Src) >= 4 && sizeof(Src) < 16,
556   size_t>::type
557 estimateSpaceNeeded(Src value) {
558   return digits10(value);
559 }
560
561 /**
562  * All small signed and unsigned integers to string go through 32-bit
563  * types int32_t and uint32_t, respectively.
564  */
565 template <class Tgt, class Src>
566 typename std::enable_if<
567   std::is_integral<Src>::value
568   && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
569 toAppend(Src value, Tgt * result) {
570   typedef typename
571     std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
572     Intermediate;
573   toAppend<Tgt>(static_cast<Intermediate>(value), result);
574 }
575
576 template <class Src>
577 typename std::enable_if<
578   std::is_integral<Src>::value
579   && sizeof(Src) < 4
580   && !std::is_same<Src, char>::value,
581   size_t>::type
582 estimateSpaceNeeded(Src value) {
583   typedef typename
584     std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
585     Intermediate;
586   return estimateSpaceNeeded(static_cast<Intermediate>(value));
587 }
588
589 /**
590  * Enumerated values get appended as integers.
591  */
592 template <class Tgt, class Src>
593 typename std::enable_if<
594   std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
595 toAppend(Src value, Tgt * result) {
596   toAppend(
597       static_cast<typename std::underlying_type<Src>::type>(value), result);
598 }
599
600 template <class Src>
601 typename std::enable_if<
602   std::is_enum<Src>::value, size_t>::type
603 estimateSpaceNeeded(Src value) {
604   return estimateSpaceNeeded(
605       static_cast<typename std::underlying_type<Src>::type>(value));
606 }
607
608 /*******************************************************************************
609  * Conversions from floating-point types to string types.
610  ******************************************************************************/
611
612 namespace detail {
613 constexpr int kConvMaxDecimalInShortestLow = -6;
614 constexpr int kConvMaxDecimalInShortestHigh = 21;
615 } // folly::detail
616
617 /** Wrapper around DoubleToStringConverter **/
618 template <class Tgt, class Src>
619 typename std::enable_if<
620   std::is_floating_point<Src>::value
621   && IsSomeString<Tgt>::value>::type
622 toAppend(
623   Src value,
624   Tgt * result,
625   double_conversion::DoubleToStringConverter::DtoaMode mode,
626   unsigned int numDigits) {
627   using namespace double_conversion;
628   DoubleToStringConverter
629     conv(DoubleToStringConverter::NO_FLAGS,
630          "Infinity", "NaN", 'E',
631          detail::kConvMaxDecimalInShortestLow,
632          detail::kConvMaxDecimalInShortestHigh,
633          6,   // max leading padding zeros
634          1);  // max trailing padding zeros
635   char buffer[256];
636   StringBuilder builder(buffer, sizeof(buffer));
637   switch (mode) {
638     case DoubleToStringConverter::SHORTEST:
639       conv.ToShortest(value, &builder);
640       break;
641     case DoubleToStringConverter::FIXED:
642       conv.ToFixed(value, numDigits, &builder);
643       break;
644     default:
645       CHECK(mode == DoubleToStringConverter::PRECISION);
646       conv.ToPrecision(value, numDigits, &builder);
647       break;
648   }
649   const size_t length = builder.position();
650   builder.Finalize();
651   result->append(buffer, length);
652 }
653
654 /**
655  * As above, but for floating point
656  */
657 template <class Tgt, class Src>
658 typename std::enable_if<
659   std::is_floating_point<Src>::value
660   && IsSomeString<Tgt>::value>::type
661 toAppend(Src value, Tgt * result) {
662   toAppend(
663     value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
664 }
665
666 /**
667  * Upper bound of the length of the output from
668  * DoubleToStringConverter::ToShortest(double, StringBuilder*),
669  * as used in toAppend(double, string*).
670  */
671 template <class Src>
672 typename std::enable_if<
673   std::is_floating_point<Src>::value, size_t>::type
674 estimateSpaceNeeded(Src value) {
675   // kBase10MaximalLength is 17. We add 1 for decimal point,
676   // e.g. 10.0/9 is 17 digits and 18 characters, including the decimal point.
677   constexpr int kMaxMantissaSpace =
678     double_conversion::DoubleToStringConverter::kBase10MaximalLength + 1;
679   // strlen("E-") + digits10(numeric_limits<double>::max_exponent10)
680   constexpr int kMaxExponentSpace = 2 + 3;
681   static const int kMaxPositiveSpace = std::max({
682       // E.g. 1.1111111111111111E-100.
683       kMaxMantissaSpace + kMaxExponentSpace,
684       // E.g. 0.000001.1111111111111111, if kConvMaxDecimalInShortestLow is -6.
685       kMaxMantissaSpace - detail::kConvMaxDecimalInShortestLow,
686       // If kConvMaxDecimalInShortestHigh is 21, then 1e21 is the smallest
687       // number > 1 which ToShortest outputs in exponential notation,
688       // so 21 is the longest non-exponential number > 1.
689       detail::kConvMaxDecimalInShortestHigh
690     });
691   return kMaxPositiveSpace + (value < 0);  // +1 for minus sign, if negative
692 }
693
694 /**
695  * This can be specialized, together with adding specialization
696  * for estimateSpaceNeed for your type, so that we allocate
697  * as much as you need instead of the default
698  */
699 template<class Src>
700 struct HasLengthEstimator : std::false_type {};
701
702 template <class Src>
703 constexpr typename std::enable_if<
704   !std::is_fundamental<Src>::value
705 #if FOLLY_HAVE_INT128_T
706   // On OSX 10.10, is_fundamental<__int128> is false :-O
707   && !std::is_same<__int128, Src>::value
708   && !std::is_same<unsigned __int128, Src>::value
709 #endif
710   && !IsSomeString<Src>::value
711   && !std::is_convertible<Src, const char*>::value
712   && !std::is_convertible<Src, StringPiece>::value
713   && !std::is_enum<Src>::value
714   && !HasLengthEstimator<Src>::value,
715   size_t>::type
716 estimateSpaceNeeded(const Src&) {
717   return sizeof(Src) + 1; // dumbest best effort ever?
718 }
719
720 namespace detail {
721
722 template <class Tgt>
723 typename std::enable_if<IsSomeString<Tgt>::value, size_t>::type
724 estimateSpaceToReserve(size_t sofar, Tgt*) {
725   return sofar;
726 }
727
728 template <class T, class... Ts>
729 size_t estimateSpaceToReserve(size_t sofar, const T& v, const Ts&... vs) {
730   return estimateSpaceToReserve(sofar + estimateSpaceNeeded(v), vs...);
731 }
732
733 template<class...Ts>
734 void reserveInTarget(const Ts&...vs) {
735   getLastElement(vs...)->reserve(estimateSpaceToReserve(0, vs...));
736 }
737
738 template<class Delimiter, class...Ts>
739 void reserveInTargetDelim(const Delimiter& d, const Ts&...vs) {
740   static_assert(sizeof...(vs) >= 2, "Needs at least 2 args");
741   size_t fordelim = (sizeof...(vs) - 2) *
742       estimateSpaceToReserve(0, d, static_cast<std::string*>(nullptr));
743   getLastElement(vs...)->reserve(estimateSpaceToReserve(fordelim, vs...));
744 }
745
746 /**
747  * Variadic base case: append one element
748  */
749 template <class T, class Tgt>
750 typename std::enable_if<
751   IsSomeString<typename std::remove_pointer<Tgt>::type>
752   ::value>::type
753 toAppendStrImpl(const T& v, Tgt result) {
754   toAppend(v, result);
755 }
756
757 template <class T, class... Ts>
758 typename std::enable_if<sizeof...(Ts) >= 2
759   && IsSomeString<
760   typename std::remove_pointer<
761     typename detail::last_element<Ts...>::type
762   >::type>::value>::type
763 toAppendStrImpl(const T& v, const Ts&... vs) {
764   toAppend(v, getLastElement(vs...));
765   toAppendStrImpl(vs...);
766 }
767
768 template <class Delimiter, class T, class Tgt>
769 typename std::enable_if<
770     IsSomeString<typename std::remove_pointer<Tgt>::type>::value>::type
771 toAppendDelimStrImpl(const Delimiter& /* delim */, const T& v, Tgt result) {
772   toAppend(v, result);
773 }
774
775 template <class Delimiter, class T, class... Ts>
776 typename std::enable_if<sizeof...(Ts) >= 2
777   && IsSomeString<
778   typename std::remove_pointer<
779     typename detail::last_element<Ts...>::type
780   >::type>::value>::type
781 toAppendDelimStrImpl(const Delimiter& delim, const T& v, const Ts&... vs) {
782   // we are really careful here, calling toAppend with just one element does
783   // not try to estimate space needed (as we already did that). If we call
784   // toAppend(v, delim, ....) we would do unnecesary size calculation
785   toAppend(v, detail::getLastElement(vs...));
786   toAppend(delim, detail::getLastElement(vs...));
787   toAppendDelimStrImpl(delim, vs...);
788 }
789 } // folly::detail
790
791
792 /**
793  * Variadic conversion to string. Appends each element in turn.
794  * If we have two or more things to append, we it will not reserve
795  * the space for them and will depend on strings exponential growth.
796  * If you just append once consider using toAppendFit which reserves
797  * the space needed (but does not have exponential as a result).
798  *
799  * Custom implementations of toAppend() can be provided in the same namespace as
800  * the type to customize printing. estimateSpaceNeed() may also be provided to
801  * avoid reallocations in toAppendFit():
802  *
803  * namespace other_namespace {
804  *
805  * template <class String>
806  * void toAppend(const OtherType&, String* out);
807  *
808  * // optional
809  * size_t estimateSpaceNeeded(const OtherType&);
810  *
811  * }
812  */
813 template <class... Ts>
814 typename std::enable_if<sizeof...(Ts) >= 3
815   && IsSomeString<
816   typename std::remove_pointer<
817     typename detail::last_element<Ts...>::type
818   >::type>::value>::type
819 toAppend(const Ts&... vs) {
820   ::folly::detail::toAppendStrImpl(vs...);
821 }
822
823 #ifdef _MSC_VER
824 // Special case pid_t on MSVC, because it's a void* rather than an
825 // integral type. We can't do a global special case because this is already
826 // dangerous enough (as most pointers will implicitly convert to a void*)
827 // just doing it for MSVC.
828 template <class Tgt>
829 void toAppend(const pid_t a, Tgt* res) {
830   toAppend(uint64_t(a), res);
831 }
832 #endif
833
834 /**
835  * Special version of the call that preallocates exaclty as much memory
836  * as need for arguments to be stored in target. This means we are
837  * not doing exponential growth when we append. If you are using it
838  * in a loop you are aiming at your foot with a big perf-destroying
839  * bazooka.
840  * On the other hand if you are appending to a string once, this
841  * will probably save a few calls to malloc.
842  */
843 template <class... Ts>
844 typename std::enable_if<
845   IsSomeString<
846   typename std::remove_pointer<
847     typename detail::last_element<Ts...>::type
848   >::type>::value>::type
849 toAppendFit(const Ts&... vs) {
850   ::folly::detail::reserveInTarget(vs...);
851   toAppend(vs...);
852 }
853
854 template <class Ts>
855 void toAppendFit(const Ts&) {}
856
857 /**
858  * Variadic base case: do nothing.
859  */
860 template <class Tgt>
861 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
862     Tgt* /* result */) {}
863
864 /**
865  * Variadic base case: do nothing.
866  */
867 template <class Delimiter, class Tgt>
868 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
869     const Delimiter& /* delim */, Tgt* /* result */) {}
870
871 /**
872  * 1 element: same as toAppend.
873  */
874 template <class Delimiter, class T, class Tgt>
875 typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
876     const Delimiter& /* delim */, const T& v, Tgt* tgt) {
877   toAppend(v, tgt);
878 }
879
880 /**
881  * Append to string with a delimiter in between elements. Check out
882  * comments for toAppend for details about memory allocation.
883  */
884 template <class Delimiter, class... Ts>
885 typename std::enable_if<sizeof...(Ts) >= 3
886   && IsSomeString<
887   typename std::remove_pointer<
888     typename detail::last_element<Ts...>::type
889   >::type>::value>::type
890 toAppendDelim(const Delimiter& delim, const Ts&... vs) {
891   detail::toAppendDelimStrImpl(delim, vs...);
892 }
893
894 /**
895  * Detail in comment for toAppendFit
896  */
897 template <class Delimiter, class... Ts>
898 typename std::enable_if<
899   IsSomeString<
900   typename std::remove_pointer<
901     typename detail::last_element<Ts...>::type
902   >::type>::value>::type
903 toAppendDelimFit(const Delimiter& delim, const Ts&... vs) {
904   detail::reserveInTargetDelim(delim, vs...);
905   toAppendDelim(delim, vs...);
906 }
907
908 template <class De, class Ts>
909 void toAppendDelimFit(const De&, const Ts&) {}
910
911 /**
912  * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
913  * for all types.
914  */
915 template <class Tgt, class... Ts>
916 typename std::enable_if<
917   IsSomeString<Tgt>::value && (
918     sizeof...(Ts) != 1 ||
919     !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
920   Tgt>::type
921 to(const Ts&... vs) {
922   Tgt result;
923   toAppendFit(vs..., &result);
924   return result;
925 }
926
927 /**
928  * toDelim<SomeString>(SomeString str) returns itself.
929  */
930 template <class Tgt, class Delim, class Src>
931 typename std::enable_if<IsSomeString<Tgt>::value &&
932                             std::is_same<Tgt, Src>::value,
933                         Tgt>::type
934 toDelim(const Delim& /* delim */, const Src& value) {
935   return value;
936 }
937
938 /**
939  * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
940  * back-end for all types.
941  */
942 template <class Tgt, class Delim, class... Ts>
943 typename std::enable_if<
944   IsSomeString<Tgt>::value && (
945     sizeof...(Ts) != 1 ||
946     !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
947   Tgt>::type
948 toDelim(const Delim& delim, const Ts&... vs) {
949   Tgt result;
950   toAppendDelimFit(delim, vs..., &result);
951   return result;
952 }
953
954 /*******************************************************************************
955  * Conversions from string types to integral types.
956  ******************************************************************************/
957
958 namespace detail {
959
960 ConversionResult<bool> str_to_bool(StringPiece* src);
961
962 template <typename T>
963 ConversionResult<T> str_to_floating(StringPiece* src);
964
965 extern template ConversionResult<float> str_to_floating<float>(
966     StringPiece* src);
967 extern template ConversionResult<double> str_to_floating<double>(
968     StringPiece* src);
969
970 template <class Tgt>
971 ConversionResult<Tgt> digits_to(const char* b, const char* e);
972
973 extern template ConversionResult<char> digits_to<char>(
974     const char*,
975     const char*);
976 extern template ConversionResult<signed char> digits_to<signed char>(
977     const char*,
978     const char*);
979 extern template ConversionResult<unsigned char> digits_to<unsigned char>(
980     const char*,
981     const char*);
982
983 extern template ConversionResult<short> digits_to<short>(
984     const char*,
985     const char*);
986 extern template ConversionResult<unsigned short> digits_to<unsigned short>(
987     const char*,
988     const char*);
989
990 extern template ConversionResult<int> digits_to<int>(const char*, const char*);
991 extern template ConversionResult<unsigned int> digits_to<unsigned int>(
992     const char*,
993     const char*);
994
995 extern template ConversionResult<long> digits_to<long>(
996     const char*,
997     const char*);
998 extern template ConversionResult<unsigned long> digits_to<unsigned long>(
999     const char*,
1000     const char*);
1001
1002 extern template ConversionResult<long long> digits_to<long long>(
1003     const char*,
1004     const char*);
1005 extern template ConversionResult<unsigned long long>
1006 digits_to<unsigned long long>(const char*, const char*);
1007
1008 #if FOLLY_HAVE_INT128_T
1009 extern template ConversionResult<__int128> digits_to<__int128>(
1010     const char*,
1011     const char*);
1012 extern template ConversionResult<unsigned __int128>
1013 digits_to<unsigned __int128>(const char*, const char*);
1014 #endif
1015
1016 template <class T>
1017 ConversionResult<T> str_to_integral(StringPiece* src);
1018
1019 extern template ConversionResult<char> str_to_integral<char>(StringPiece* src);
1020 extern template ConversionResult<signed char> str_to_integral<signed char>(
1021     StringPiece* src);
1022 extern template ConversionResult<unsigned char> str_to_integral<unsigned char>(
1023     StringPiece* src);
1024
1025 extern template ConversionResult<short> str_to_integral<short>(
1026     StringPiece* src);
1027 extern template ConversionResult<unsigned short>
1028 str_to_integral<unsigned short>(StringPiece* src);
1029
1030 extern template ConversionResult<int> str_to_integral<int>(StringPiece* src);
1031 extern template ConversionResult<unsigned int> str_to_integral<unsigned int>(
1032     StringPiece* src);
1033
1034 extern template ConversionResult<long> str_to_integral<long>(StringPiece* src);
1035 extern template ConversionResult<unsigned long> str_to_integral<unsigned long>(
1036     StringPiece* src);
1037
1038 extern template ConversionResult<long long> str_to_integral<long long>(
1039     StringPiece* src);
1040 extern template ConversionResult<unsigned long long>
1041 str_to_integral<unsigned long long>(StringPiece* src);
1042
1043 #if FOLLY_HAVE_INT128_T
1044 extern template ConversionResult<__int128> str_to_integral<__int128>(
1045     StringPiece* src);
1046 extern template ConversionResult<unsigned __int128>
1047 str_to_integral<unsigned __int128>(StringPiece* src);
1048 #endif
1049
1050 template <typename T>
1051 typename std::enable_if<std::is_same<T, bool>::value, ConversionResult<T>>::type
1052 convertTo(StringPiece* src) {
1053   return str_to_bool(src);
1054 }
1055
1056 template <typename T>
1057 typename std::enable_if<
1058     std::is_floating_point<T>::value, ConversionResult<T>>::type
1059 convertTo(StringPiece* src) {
1060   return str_to_floating<T>(src);
1061 }
1062
1063 template <typename T>
1064 typename std::enable_if<
1065     std::is_integral<T>::value && !std::is_same<T, bool>::value,
1066     ConversionResult<T>>::type
1067 convertTo(StringPiece* src) {
1068   return str_to_integral<T>(src);
1069 }
1070
1071 template <typename T>
1072 struct WrapperInfo { using type = T; };
1073
1074 template <typename T, typename Gen>
1075 typename std::enable_if<
1076     std::is_same<typename WrapperInfo<T>::type, T>::value, T>::type
1077 inline wrap(ConversionResult<typename WrapperInfo<T>::type> res, Gen&& gen) {
1078   if (LIKELY(res.success())) {
1079     return res.value;
1080   }
1081   throw detail::makeConversionError(res.error, gen());
1082 }
1083
1084 } // namespace detail
1085
1086 /**
1087  * String represented as a pair of pointers to char to unsigned
1088  * integrals. Assumes NO whitespace before or after.
1089  */
1090 template <typename Tgt>
1091 typename std::enable_if<
1092     std::is_integral<typename detail::WrapperInfo<Tgt>::type>::value &&
1093     !std::is_same<typename detail::WrapperInfo<Tgt>::type, bool>::value,
1094     Tgt>::type
1095 to(const char* b, const char* e) {
1096   auto res = detail::digits_to<typename detail::WrapperInfo<Tgt>::type>(b, e);
1097   return detail::wrap<Tgt>(res, [&] { return StringPiece(b, e); });
1098 }
1099
1100 /*******************************************************************************
1101  * Conversions from string types to arithmetic types.
1102  ******************************************************************************/
1103
1104 /**
1105  * Parsing strings to numeric types. These routines differ from
1106  * parseTo(str, numeric) routines in that they take a POINTER TO a StringPiece
1107  * and alter that StringPiece to reflect progress information.
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   out = detail::wrap<Tgt>(res, [&] { return *src; });
1115 }
1116
1117 template <typename Tgt>
1118 typename std::enable_if<
1119     std::is_arithmetic<typename detail::WrapperInfo<Tgt>::type>::value>::type
1120 parseTo(StringPiece src, Tgt& out) {
1121   auto res = detail::convertTo<typename detail::WrapperInfo<Tgt>::type>(&src);
1122   if (LIKELY(res.success())) {
1123     res.error = detail::enforceWhitespaceErr(src);
1124   }
1125   out = detail::wrap<Tgt>(res, [&] { return src; });
1126 }
1127
1128 /*******************************************************************************
1129  * Integral / Floating Point to integral / Floating Point
1130  ******************************************************************************/
1131
1132 /**
1133  * Unchecked conversion from arithmetic to boolean. This is different from the
1134  * other arithmetic conversions because we use the C convention of treating any
1135  * non-zero value as true, instead of range checking.
1136  */
1137 template <class Tgt, class Src>
1138 typename std::enable_if<
1139     std::is_arithmetic<Src>::value && !std::is_same<Tgt, Src>::value &&
1140         std::is_same<Tgt, bool>::value,
1141     Tgt>::type
1142 to(const Src& value) {
1143   return value != Src();
1144 }
1145
1146 namespace detail {
1147
1148 /**
1149  * Checked conversion from integral to integral. The checks are only
1150  * performed when meaningful, e.g. conversion from int to long goes
1151  * unchecked.
1152  */
1153 template <class Tgt, class Src>
1154 typename std::enable_if<
1155     std::is_integral<Src>::value && !std::is_same<Tgt, Src>::value &&
1156         !std::is_same<Tgt, bool>::value &&
1157         std::is_integral<Tgt>::value,
1158     ConversionResult<Tgt>>::type
1159 convertTo(const Src& value) {
1160   /* static */ if (
1161       std::numeric_limits<Tgt>::max() < std::numeric_limits<Src>::max()) {
1162     if (greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)) {
1163       return ConversionResult<Tgt>(ConversionError::ARITH_POSITIVE_OVERFLOW);
1164     }
1165   }
1166   /* static */ if (
1167       std::is_signed<Src>::value &&
1168       (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
1169     if (less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)) {
1170       return ConversionResult<Tgt>(ConversionError::ARITH_NEGATIVE_OVERFLOW);
1171     }
1172   }
1173   return ConversionResult<Tgt>(static_cast<Tgt>(value));
1174 }
1175
1176 /**
1177  * Checked conversion from floating to floating. The checks are only
1178  * performed when meaningful, e.g. conversion from float to double goes
1179  * unchecked.
1180  */
1181 template <class Tgt, class Src>
1182 typename std::enable_if<
1183     std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value &&
1184         !std::is_same<Tgt, Src>::value,
1185     ConversionResult<Tgt>>::type
1186 convertTo(const Src& value) {
1187   /* static */ if (
1188       std::numeric_limits<Tgt>::max() < std::numeric_limits<Src>::max()) {
1189     if (value > std::numeric_limits<Tgt>::max()) {
1190       return ConversionResult<Tgt>(ConversionError::ARITH_POSITIVE_OVERFLOW);
1191     }
1192     if (value < std::numeric_limits<Tgt>::lowest()) {
1193       return ConversionResult<Tgt>(ConversionError::ARITH_NEGATIVE_OVERFLOW);
1194     }
1195   }
1196   return ConversionResult<Tgt>(boost::implicit_cast<Tgt>(value));
1197 }
1198
1199 /**
1200  * Check if a floating point value can safely be converted to an
1201  * integer value without triggering undefined behaviour.
1202  */
1203 template <typename Tgt, typename Src>
1204 inline typename std::enable_if<
1205     std::is_floating_point<Src>::value && std::is_integral<Tgt>::value &&
1206         !std::is_same<Tgt, bool>::value,
1207     bool>::type
1208 checkConversion(const Src& value) {
1209   constexpr Src tgtMaxAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::max());
1210   constexpr Src tgtMinAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::min());
1211   if (value >= tgtMaxAsSrc) {
1212     if (value > tgtMaxAsSrc) {
1213       return false;
1214     }
1215     const Src mmax = folly::nextafter(tgtMaxAsSrc, Src());
1216     if (static_cast<Tgt>(value - mmax) >
1217         std::numeric_limits<Tgt>::max() - static_cast<Tgt>(mmax)) {
1218       return false;
1219     }
1220   } else if (std::is_signed<Tgt>::value && value <= tgtMinAsSrc) {
1221     if (value < tgtMinAsSrc) {
1222       return false;
1223     }
1224     const Src mmin = folly::nextafter(tgtMinAsSrc, Src());
1225     if (static_cast<Tgt>(value - mmin) <
1226         std::numeric_limits<Tgt>::min() - static_cast<Tgt>(mmin)) {
1227       return false;
1228     }
1229   }
1230   return true;
1231 }
1232
1233 // Integers can always safely be converted to floating point values
1234 template <typename Tgt, typename Src>
1235 constexpr typename std::enable_if<
1236     std::is_integral<Src>::value && std::is_floating_point<Tgt>::value,
1237     bool>::type
1238 checkConversion(const Src&) {
1239   return true;
1240 }
1241
1242 // Also, floating point values can always be safely converted to bool
1243 // Per the standard, any floating point value that is not zero will yield true
1244 template <typename Tgt, typename Src>
1245 constexpr typename std::enable_if<
1246     std::is_floating_point<Src>::value && std::is_same<Tgt, bool>::value,
1247     bool>::type
1248 checkConversion(const Src&) {
1249   return true;
1250 }
1251
1252 /**
1253  * Checked conversion from integral to floating point and back. The
1254  * result must be convertible back to the source type without loss of
1255  * precision. This seems Draconian but sometimes is what's needed, and
1256  * complements existing routines nicely. For various rounding
1257  * routines, see <math>.
1258  */
1259 template <typename Tgt, typename Src>
1260 typename std::enable_if<
1261     (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value) ||
1262         (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1263     ConversionResult<Tgt>>::type
1264 convertTo(const Src& value) {
1265   if (LIKELY(checkConversion<Tgt>(value))) {
1266     Tgt result = static_cast<Tgt>(value);
1267     if (LIKELY(checkConversion<Src>(result))) {
1268       Src witness = static_cast<Src>(result);
1269       if (LIKELY(value == witness)) {
1270         return ConversionResult<Tgt>(result);
1271       }
1272     }
1273   }
1274   return ConversionResult<Tgt>(ConversionError::ARITH_LOSS_OF_PRECISION);
1275 }
1276
1277 template <typename Tgt, typename Src>
1278 inline std::string errorValue(const Src& value) {
1279 #ifdef FOLLY_HAS_RTTI
1280   return to<std::string>("(", demangle(typeid(Tgt)), ") ", value);
1281 #else
1282   return to<std::string>(value);
1283 #endif
1284 }
1285
1286 template <typename Tgt, typename Src>
1287 using IsArithToArith = std::integral_constant<
1288     bool,
1289     !std::is_same<Tgt, Src>::value && !std::is_same<Tgt, bool>::value &&
1290         std::is_arithmetic<Src>::value &&
1291         std::is_arithmetic<Tgt>::value>;
1292
1293 } // namespace detail
1294
1295 template <typename Tgt, typename Src>
1296 typename std::enable_if<
1297     detail::IsArithToArith<
1298         typename detail::WrapperInfo<Tgt>::type, Src>::value, Tgt>::type
1299 to(const Src& value) {
1300   auto res = detail::convertTo<typename detail::WrapperInfo<Tgt>::type>(value);
1301   return detail::wrap<Tgt>(res, [&] {
1302     return detail::errorValue<typename detail::WrapperInfo<Tgt>::type>(value);
1303   });
1304 }
1305
1306 /*******************************************************************************
1307  * Custom Conversions
1308  *
1309  * Any type can be used with folly::to by implementing parseTo. The
1310  * implementation should be provided in the namespace of the type to facilitate
1311  * argument-dependent lookup:
1312  *
1313  * namespace other_namespace {
1314  * void parseTo(::folly::StringPiece, OtherType&);
1315  * }
1316  ******************************************************************************/
1317 template <class T>
1318 typename std::enable_if<std::is_enum<T>::value>::type
1319 parseTo(StringPiece in, T& out) {
1320   typename std::underlying_type<T>::type tmp;
1321   parseTo(in, tmp);
1322   out = static_cast<T>(tmp);
1323 }
1324
1325 inline void parseTo(StringPiece in, StringPiece& out) {
1326   out = in;
1327 }
1328
1329 inline void parseTo(StringPiece in, std::string& out) {
1330   out.clear();
1331   out.append(in.data(), in.size());
1332 }
1333
1334 inline void parseTo(StringPiece in, fbstring& out) {
1335   out.clear();
1336   out.append(in.data(), in.size());
1337 }
1338
1339 /**
1340  * String or StringPiece to target conversion. Accepts leading and trailing
1341  * whitespace, but no non-space trailing characters.
1342  */
1343
1344 template <class Tgt>
1345 typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
1346 to(StringPiece src) {
1347   Tgt result;
1348   parseTo(src, result);
1349   return result;
1350 }
1351
1352 template <class Tgt>
1353 Tgt to(StringPiece* src) {
1354   Tgt result;
1355   parseTo(src, result);
1356   return result;
1357 }
1358
1359 /*******************************************************************************
1360  * Enum to anything and back
1361  ******************************************************************************/
1362
1363 template <class Tgt, class Src>
1364 typename std::enable_if<
1365   std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1366 to(const Src & value) {
1367   return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1368 }
1369
1370 template <class Tgt, class Src>
1371 typename std::enable_if<
1372   std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1373 to(const Src & value) {
1374   return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1375 }
1376
1377 } // namespace folly