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