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