Fix code for anything-to-string space estimation
[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
45 #define FOLLY_RANGE_CHECK_STRINGIZE(x) #x
46 #define FOLLY_RANGE_CHECK_STRINGIZE2(x) FOLLY_RANGE_CHECK_STRINGIZE(x)
47
48 // Android doesn't support std::to_string so just use a placeholder there.
49 #ifdef __ANDROID__
50 #define FOLLY_RANGE_CHECK_TO_STRING(x) std::string("N/A")
51 #else
52 #define FOLLY_RANGE_CHECK_TO_STRING(x) std::to_string(x)
53 #endif
54
55 #define FOLLY_RANGE_CHECK(condition, message, src)                          \
56   ((condition) ? (void)0 : throw std::range_error(                          \
57     (std::string(__FILE__ "(" FOLLY_RANGE_CHECK_STRINGIZE2(__LINE__) "): ") \
58      + (message) + ": '" + (src) + "'").c_str()))
59
60 #define FOLLY_RANGE_CHECK_BEGIN_END(condition, message, b, e)    \
61   FOLLY_RANGE_CHECK(condition, message, std::string((b), (e) - (b)))
62
63 #define FOLLY_RANGE_CHECK_STRINGPIECE(condition, message, sp)    \
64   FOLLY_RANGE_CHECK(condition, message, std::string((sp).data(), (sp).size()))
65
66 namespace folly {
67
68 /**
69  * The identity conversion function.
70  * to<T>(T) returns itself for all types T.
71  */
72 template <class Tgt, class Src>
73 typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
74 to(const Src & value) {
75   return value;
76 }
77
78 template <class Tgt, class Src>
79 typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
80 to(Src && value) {
81   return std::forward<Src>(value);
82 }
83
84 /*******************************************************************************
85  * Integral to integral
86  ******************************************************************************/
87
88 /**
89  * Unchecked conversion from integral to boolean. This is different from the
90  * other integral conversions because we use the C convention of treating any
91  * non-zero value as true, instead of range checking.
92  */
93 template <class Tgt, class Src>
94 typename std::enable_if<
95   std::is_integral<Src>::value
96   && !std::is_same<Tgt, Src>::value
97   && std::is_same<Tgt, bool>::value,
98   Tgt>::type
99 to(const Src & value) {
100   return value != 0;
101 }
102
103 /**
104  * Checked conversion from integral to integral. The checks are only
105  * performed when meaningful, e.g. conversion from int to long goes
106  * unchecked.
107  */
108 template <class Tgt, class Src>
109 typename std::enable_if<
110   std::is_integral<Src>::value
111   && !std::is_same<Tgt, Src>::value
112   && !std::is_same<Tgt, bool>::value
113   && std::is_integral<Tgt>::value,
114   Tgt>::type
115 to(const Src & value) {
116   /* static */ if (std::numeric_limits<Tgt>::max()
117                    < std::numeric_limits<Src>::max()) {
118     FOLLY_RANGE_CHECK(
119       (!greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)),
120       "Overflow",
121       FOLLY_RANGE_CHECK_TO_STRING(value));
122   }
123   /* static */ if (std::is_signed<Src>::value &&
124                    (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
125     FOLLY_RANGE_CHECK(
126       (!less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)),
127       "Negative overflow",
128       FOLLY_RANGE_CHECK_TO_STRING(value));
129   }
130   return static_cast<Tgt>(value);
131 }
132
133 /*******************************************************************************
134  * Floating point to floating point
135  ******************************************************************************/
136
137 template <class Tgt, class Src>
138 typename std::enable_if<
139   std::is_floating_point<Tgt>::value
140   && std::is_floating_point<Src>::value
141   && !std::is_same<Tgt, Src>::value,
142   Tgt>::type
143 to(const Src & value) {
144   /* static */ if (std::numeric_limits<Tgt>::max() <
145                    std::numeric_limits<Src>::max()) {
146     FOLLY_RANGE_CHECK(value <= std::numeric_limits<Tgt>::max(),
147                       "Overflow",
148                       FOLLY_RANGE_CHECK_TO_STRING(value));
149     FOLLY_RANGE_CHECK(value >= -std::numeric_limits<Tgt>::max(),
150                       "Negative overflow",
151                       FOLLY_RANGE_CHECK_TO_STRING(value));
152   }
153   return boost::implicit_cast<Tgt>(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 #ifdef 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 /**
961  * Finds the first non-digit in a string. The number of digits
962  * searched depends on the precision of the Tgt integral. Assumes the
963  * string starts with NO whitespace and NO sign.
964  *
965  * The semantics of the routine is:
966  *   for (;; ++b) {
967  *     if (b >= e || !isdigit(*b)) return b;
968  *   }
969  *
970  *  Complete unrolling marks bottom-line (i.e. entire conversion)
971  *  improvements of 20%.
972  */
973   template <class Tgt>
974   const char* findFirstNonDigit(const char* b, const char* e) {
975     for (; b < e; ++b) {
976       auto const c = static_cast<unsigned>(*b) - '0';
977       if (c >= 10) break;
978     }
979     return b;
980   }
981
982
983   bool str_to_bool(StringPiece* src);
984   float str_to_float(StringPiece* src);
985   double str_to_double(StringPiece* src);
986
987   template <class Tgt>
988   Tgt digits_to(const char* b, const char* e);
989
990   extern template unsigned char digits_to<unsigned char>(const char* b,
991       const char* e);
992   extern template unsigned short digits_to<unsigned short>(const char* b,
993       const char* e);
994   extern template unsigned int digits_to<unsigned int>(const char* b,
995       const char* e);
996   extern template unsigned long digits_to<unsigned long>(const char* b,
997       const char* e);
998   extern template unsigned long long digits_to<unsigned long long>(
999       const char* b, const char* e);
1000 #if FOLLY_HAVE_INT128_T
1001   extern template unsigned __int128 digits_to<unsigned __int128>(const char* b,
1002       const char* e);
1003 #endif
1004
1005 }                                 // namespace detail
1006
1007 /**
1008  * String represented as a pair of pointers to char to unsigned
1009  * integrals. Assumes NO whitespace before or after.
1010  */
1011 template <class Tgt>
1012 typename std::enable_if<
1013   std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
1014   && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
1015   Tgt>::type
1016 to(const char * b, const char * e) {
1017   return detail::digits_to<Tgt>(b, e);
1018 }
1019
1020 /**
1021  * String represented as a pair of pointers to char to signed
1022  * integrals. Assumes NO whitespace before or after. Allows an
1023  * optional leading sign.
1024  */
1025 template <class Tgt>
1026 typename std::enable_if<
1027   std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
1028   Tgt>::type
1029 to(const char * b, const char * e) {
1030   FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral",
1031                     to<std::string>("b: ", intptr_t(b), " e: ", intptr_t(e)));
1032   if (!isdigit(*b)) {
1033     if (*b == '-') {
1034       Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
1035       FOLLY_RANGE_CHECK_BEGIN_END(result <= 0, "Negative overflow.", b, e);
1036       return result;
1037     }
1038     FOLLY_RANGE_CHECK_BEGIN_END(*b == '+', "Invalid lead character", b, e);
1039     ++b;
1040   }
1041   Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
1042   FOLLY_RANGE_CHECK_BEGIN_END(result >= 0, "Overflow", b, e);
1043   return result;
1044 }
1045
1046 namespace detail {
1047 /**
1048  * StringPiece to integrals, with progress information. Alters the
1049  * StringPiece parameter to munch the already-parsed characters.
1050  */
1051 template <class Tgt>
1052 Tgt str_to_integral(StringPiece* src) {
1053   auto b = src->data(), past = src->data() + src->size();
1054   for (;; ++b) {
1055     FOLLY_RANGE_CHECK_STRINGPIECE(b < past,
1056                                   "No digits found in input string", *src);
1057     if (!isspace(*b)) break;
1058   }
1059
1060   auto m = b;
1061
1062   // First digit is customized because we test for sign
1063   bool negative = false;
1064   /* static */ if (std::is_signed<Tgt>::value) {
1065     if (!isdigit(*m)) {
1066       if (*m == '-') {
1067         negative = true;
1068       } else {
1069         FOLLY_RANGE_CHECK_STRINGPIECE(*m == '+', "Invalid leading character in "
1070                                       "conversion to integral", *src);
1071       }
1072       ++b;
1073       ++m;
1074     }
1075   }
1076   FOLLY_RANGE_CHECK_STRINGPIECE(m < past, "No digits found in input string",
1077                                 *src);
1078   FOLLY_RANGE_CHECK_STRINGPIECE(isdigit(*m), "Non-digit character found", *src);
1079   m = detail::findFirstNonDigit<Tgt>(m + 1, past);
1080
1081   Tgt result;
1082   /* static */ if (!std::is_signed<Tgt>::value) {
1083     result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
1084   } else {
1085     auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
1086     if (negative) {
1087       result = -t;
1088       FOLLY_RANGE_CHECK_STRINGPIECE(is_non_positive(result),
1089                                     "Negative overflow", *src);
1090     } else {
1091       result = t;
1092       FOLLY_RANGE_CHECK_STRINGPIECE(is_non_negative(result), "Overflow", *src);
1093     }
1094   }
1095   src->advance(m - src->data());
1096   return result;
1097 }
1098
1099 /**
1100  * Enforce that the suffix following a number is made up only of whitespace.
1101  */
1102 inline void enforceWhitespace(StringPiece sp) {
1103   for (char ch : sp) {
1104     FOLLY_RANGE_CHECK_STRINGPIECE(
1105         isspace(ch), to<std::string>("Non-whitespace: ", ch), sp);
1106   }
1107 }
1108
1109 /*******************************************************************************
1110  * Conversions from string types to floating-point types.
1111  ******************************************************************************/
1112
1113
1114 } // namespace detail
1115
1116 /**
1117  * StringPiece to bool, with progress information. Alters the
1118  * StringPiece parameter to munch the already-parsed characters.
1119  */
1120 inline void parseTo(StringPiece* src, bool& out) {
1121   out = detail::str_to_bool(src);
1122 }
1123
1124 /**
1125  * Parsing strings to numeric types. These routines differ from
1126  * parseTo(str, numeric) routines in that they take a POINTER TO a StringPiece
1127  * and alter that StringPiece to reflect progress information.
1128  */
1129 template <class Tgt>
1130 typename std::enable_if<
1131     std::is_integral<typename std::remove_cv<Tgt>::type>::value>::type
1132 parseTo(StringPiece* src, Tgt& out) {
1133   out = detail::str_to_integral<Tgt>(src);
1134 }
1135
1136 inline void parseTo(StringPiece* src, float& out) {
1137   out = detail::str_to_float(src);
1138 }
1139
1140 inline void parseTo(StringPiece* src, double& out) {
1141   out = detail::str_to_double(src);
1142 }
1143
1144 template <class Tgt>
1145 typename std::enable_if<
1146     std::is_floating_point<Tgt>::value ||
1147     std::is_integral<typename std::remove_cv<Tgt>::type>::value>::type
1148 parseTo(StringPiece src, Tgt& out) {
1149   parseTo(&src, out);
1150   detail::enforceWhitespace(src);
1151 }
1152
1153 /*******************************************************************************
1154  * Integral to floating point and back
1155  ******************************************************************************/
1156
1157 namespace detail {
1158
1159 /**
1160  * Check if a floating point value can safely be converted to an
1161  * integer value without triggering undefined behaviour.
1162  */
1163 template <typename Tgt, typename Src>
1164 inline typename std::enable_if<
1165     std::is_floating_point<Src>::value && std::is_integral<Tgt>::value &&
1166         !std::is_same<Tgt, bool>::value,
1167     bool>::type
1168 checkConversion(const Src& value) {
1169   constexpr Src tgtMaxAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::max());
1170   constexpr Src tgtMinAsSrc = static_cast<Src>(std::numeric_limits<Tgt>::min());
1171   if (value >= tgtMaxAsSrc) {
1172     if (value > tgtMaxAsSrc) {
1173       return false;
1174     }
1175     const Src mmax = std::nextafter(tgtMaxAsSrc, Src());
1176     if (static_cast<Tgt>(value - mmax) >
1177         std::numeric_limits<Tgt>::max() - static_cast<Tgt>(mmax)) {
1178       return false;
1179     }
1180   } else if (std::is_signed<Tgt>::value && value <= tgtMinAsSrc) {
1181     if (value < tgtMinAsSrc) {
1182       return false;
1183     }
1184     const Src mmin = std::nextafter(tgtMinAsSrc, Src());
1185     if (static_cast<Tgt>(value - mmin) <
1186         std::numeric_limits<Tgt>::min() - static_cast<Tgt>(mmin)) {
1187       return false;
1188     }
1189   }
1190   return true;
1191 }
1192
1193 // Integers can always safely be converted to floating point values
1194 template <typename Tgt, typename Src>
1195 constexpr typename std::enable_if<
1196     std::is_integral<Src>::value && std::is_floating_point<Tgt>::value,
1197     bool>::type
1198 checkConversion(const Src&) {
1199   return true;
1200 }
1201
1202 // Also, floating point values can always be safely converted to bool
1203 // Per the standard, any floating point value that is not zero will yield true
1204 template <typename Tgt, typename Src>
1205 constexpr typename std::enable_if<
1206     std::is_floating_point<Src>::value && std::is_same<Tgt, bool>::value,
1207     bool>::type
1208 checkConversion(const Src&) {
1209   return true;
1210 }
1211 }
1212
1213 /**
1214  * Checked conversion from integral to floating point and back. The
1215  * result must be convertible back to the source type without loss of
1216  * precision. This seems Draconian but sometimes is what's needed, and
1217  * complements existing routines nicely. For various rounding
1218  * routines, see <math>.
1219  */
1220 template <class Tgt, class Src>
1221 typename std::enable_if<
1222   (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1223   ||
1224   (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1225   Tgt>::type
1226 to(const Src & value) {
1227   if (detail::checkConversion<Tgt>(value)) {
1228     Tgt result = Tgt(value);
1229     if (detail::checkConversion<Src>(result)) {
1230       auto witness = static_cast<Src>(result);
1231       if (value == witness) {
1232         return result;
1233       }
1234     }
1235   }
1236   throw std::range_error(
1237     to<std::string>("to<>: loss of precision when converting ", value,
1238 #ifdef FOLLY_HAS_RTTI
1239                     " to type ", typeid(Tgt).name()
1240 #else
1241                     " to other type"
1242 #endif
1243                     ).c_str());
1244 }
1245
1246 /*******************************************************************************
1247  * Custom Conversions
1248  *
1249  * Any type can be used with folly::to by implementing parseTo. The
1250  * implementation should be provided in the namespace of the type to facilitate
1251  * argument-dependent lookup:
1252  *
1253  * namespace other_namespace {
1254  * void parseTo(::folly::StringPiece, OtherType&);
1255  * }
1256  ******************************************************************************/
1257 template <class T>
1258 typename std::enable_if<std::is_enum<T>::value>::type
1259 parseTo(StringPiece in, T& out) {
1260   typename std::underlying_type<T>::type tmp;
1261   parseTo(in, tmp);
1262   out = static_cast<T>(tmp);
1263 }
1264
1265 inline void parseTo(StringPiece in, StringPiece& out) {
1266   out = in;
1267 }
1268
1269 inline void parseTo(StringPiece in, std::string& out) {
1270   out.clear();
1271   out.append(in.data(), in.size());
1272 }
1273
1274 inline void parseTo(StringPiece in, fbstring& out) {
1275   out.clear();
1276   out.append(in.data(), in.size());
1277 }
1278
1279 /**
1280  * String or StringPiece to target conversion. Accepts leading and trailing
1281  * whitespace, but no non-space trailing characters.
1282  */
1283
1284 template <class Tgt>
1285 typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
1286 to(StringPiece src) {
1287   Tgt result;
1288   parseTo(src, result);
1289   return result;
1290 }
1291
1292 template <class Tgt>
1293 Tgt to(StringPiece* src) {
1294   Tgt result;
1295   parseTo(src, result);
1296   return result;
1297 }
1298
1299 /*******************************************************************************
1300  * Enum to anything and back
1301  ******************************************************************************/
1302
1303 template <class Tgt, class Src>
1304 typename std::enable_if<
1305   std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1306 to(const Src & value) {
1307   return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1308 }
1309
1310 template <class Tgt, class Src>
1311 typename std::enable_if<
1312   std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
1313 to(const Src & value) {
1314   return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1315 }
1316
1317 } // namespace folly
1318
1319 // FOLLY_CONV_INTERNAL is defined by Conv.cpp.  Keep the FOLLY_RANGE_CHECK
1320 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1321 // to avoid defining this global macro name in other files that include Conv.h.
1322 #ifndef FOLLY_CONV_INTERNAL
1323 #undef FOLLY_RANGE_CHECK
1324 #undef FOLLY_RANGE_CHECK_BEGIN_END
1325 #undef FOLLY_RANGE_CHECK_STRINGPIECE
1326 #undef FOLLY_RANGE_CHECK_STRINGIZE
1327 #undef FOLLY_RANGE_CHECK_STRINGIZE2
1328 #endif