2 * Copyright 2013 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Converts anything to anything, with an emphasis on performance and
21 * @author Andrei Alexandrescu (andrei.alexandrescu@fb.com)
24 #ifndef FOLLY_BASE_CONV_H_
25 #define FOLLY_BASE_CONV_H_
27 #include "folly/FBString.h"
28 #include "folly/Likely.h"
29 #include "folly/Preprocessor.h"
30 #include "folly/Range.h"
32 #include <boost/implicit_cast.hpp>
33 #include <type_traits>
42 #include "double-conversion.h" // V8 JavaScript implementation
44 #define FOLLY_RANGE_CHECK(condition, message) \
45 ((condition) ? (void)0 : throw std::range_error( \
46 (__FILE__ "(" + std::to_string((long long int) __LINE__) + "): " \
47 + (message)).c_str()))
51 /*******************************************************************************
52 * Integral to integral
53 ******************************************************************************/
56 * Checked conversion from integral to integral. The checks are only
57 * performed when meaningful, e.g. conversion from int to long goes
60 template <class Tgt, class Src>
61 typename std::enable_if<
62 std::is_integral<Src>::value && std::is_integral<Tgt>::value,
64 to(const Src & value) {
65 /* static */ if (std::numeric_limits<Tgt>::max()
66 < std::numeric_limits<Src>::max()) {
68 (!greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)),
72 /* static */ if (std::is_signed<Src>::value &&
73 (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
75 (!less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)),
79 return static_cast<Tgt>(value);
82 /*******************************************************************************
83 * Floating point to floating point
84 ******************************************************************************/
86 template <class Tgt, class Src>
87 typename std::enable_if<
88 std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value,
90 to(const Src & value) {
91 /* static */ if (std::numeric_limits<Tgt>::max() <
92 std::numeric_limits<Src>::max()) {
93 FOLLY_RANGE_CHECK(value <= std::numeric_limits<Tgt>::max(),
95 FOLLY_RANGE_CHECK(value >= -std::numeric_limits<Tgt>::max(),
98 return boost::implicit_cast<Tgt>(value);
101 /*******************************************************************************
103 ******************************************************************************/
107 template <class T> struct IsSomeString {
108 enum { value = std::is_same<T, std::string>::value
109 || std::is_same<T, fbstring>::value };
113 const T& getLastElement(const T & v) {
117 template <class T, class... Ts>
118 typename std::tuple_element<
120 std::tuple<T, Ts...> >::type const&
121 getLastElement(const T& v, const Ts&... vs) {
122 return getLastElement(vs...);
125 } // namespace detail
127 /*******************************************************************************
128 * Conversions from integral types to string types.
129 ******************************************************************************/
131 #if FOLLY_HAVE_INT128_T
134 template <typename IntegerType>
135 constexpr unsigned int
137 return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
141 unsafeTelescope128(char * buffer, unsigned int room, unsigned __int128 x) {
142 typedef unsigned __int128 Usrc;
143 unsigned int p = room - 1;
145 while (x >= (Usrc(1) << 64)) { // Using 128-bit division while needed
146 const auto y = x / 10;
147 const auto digit = x % 10;
149 buffer[p--] = '0' + digit;
153 uint64_t xx = x; // Moving to faster 64-bit division thereafter
156 const auto y = xx / 10ULL;
157 const auto digit = xx % 10ULL;
159 buffer[p--] = '0' + digit;
163 buffer[p] = '0' + xx;
172 * Returns the number of digits in the base 10 representation of an
173 * uint64_t. Useful for preallocating buffers and such. It's also used
174 * internally, see below. Measurements suggest that defining a
175 * separate overload for 32-bit integers is not worthwhile.
178 inline uint32_t digits10(uint64_t v) {
181 if (LIKELY(v < 10)) return result;
182 if (LIKELY(v < 100)) return result + 1;
183 if (LIKELY(v < 1000)) return result + 2;
184 if (LIKELY(v < 10000)) return result + 3;
185 // Skip ahead by 4 orders of magnitude
192 * Copies the ASCII base 10 representation of v into buffer and
193 * returns the number of bytes written. Does NOT append a \0. Assumes
194 * the buffer points to digits10(v) bytes of valid memory. Note that
195 * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
196 * uint16_t needs at most 5 bytes, and so on. Measurements suggest
197 * that defining a separate overload for 32-bit integers is not
200 * This primitive is unsafe because it makes the size assumption and
201 * because it does not add a terminating \0.
204 inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
205 auto const result = digits10(v);
206 // WARNING: using size_t or pointer arithmetic for pos slows down
207 // the loop below 20x. This is because several 32-bit ops can be
208 // done in parallel, but only fewer 64-bit ones.
209 uint32_t pos = result - 1;
211 // Keep these together so a peephole optimization "sees" them and
212 // computes them in one shot.
213 auto const q = v / 10;
214 auto const r = static_cast<uint32_t>(v % 10);
215 buffer[pos--] = '0' + r;
218 // Last digit is trivial to handle
219 buffer[pos] = static_cast<uint32_t>(v) + '0';
224 * A single char gets appended.
227 void toAppend(char value, Tgt * result) {
232 * Everything implicitly convertible to const char* gets appended.
234 template <class Tgt, class Src>
235 typename std::enable_if<
236 std::is_convertible<Src, const char*>::value
237 && detail::IsSomeString<Tgt>::value>::type
238 toAppend(Src value, Tgt * result) {
239 // Treat null pointers like an empty string, as in:
240 // operator<<(std::ostream&, const char*).
241 const char* c = value;
243 result->append(value);
248 * Strings get appended, too.
250 template <class Tgt, class Src>
251 typename std::enable_if<
252 detail::IsSomeString<Src>::value && detail::IsSomeString<Tgt>::value>::type
253 toAppend(const Src& value, Tgt * result) {
254 result->append(value);
258 * and StringPiece objects too
261 typename std::enable_if<
262 detail::IsSomeString<Tgt>::value>::type
263 toAppend(StringPiece value, Tgt * result) {
264 result->append(value.data(), value.size());
268 * There's no implicit conversion from fbstring to other string types,
269 * so make a specialization.
272 typename std::enable_if<
273 detail::IsSomeString<Tgt>::value>::type
274 toAppend(const fbstring& value, Tgt * result) {
275 result->append(value.data(), value.size());
278 #if FOLLY_HAVE_INT128_T
280 * Special handling for 128 bit integers.
285 toAppend(__int128 value, Tgt * result) {
286 typedef unsigned __int128 Usrc;
287 char buffer[detail::digitsEnough<unsigned __int128>() + 1];
291 p = detail::unsafeTelescope128(buffer, sizeof(buffer), Usrc(-value));
294 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
297 result->append(buffer + p, buffer + sizeof(buffer));
302 toAppend(unsigned __int128 value, Tgt * result) {
303 char buffer[detail::digitsEnough<unsigned __int128>()];
306 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
308 result->append(buffer + p, buffer + sizeof(buffer));
314 * int32_t and int64_t to string (by appending) go through here. The
315 * result is APPENDED to a preexisting string passed as the second
316 * parameter. This should be efficient with fbstring because fbstring
317 * incurs no dynamic allocation below 23 bytes and no number has more
318 * than 22 bytes in its textual representation (20 for digits, one for
319 * sign, one for the terminating 0).
321 template <class Tgt, class Src>
322 typename std::enable_if<
323 std::is_integral<Src>::value && std::is_signed<Src>::value &&
324 detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
325 toAppend(Src value, Tgt * result) {
326 typedef typename std::make_unsigned<Src>::type Usrc;
329 result->push_back('-');
330 result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
332 result->append(buffer, uint64ToBufferUnsafe(value, buffer));
337 * As above, but for uint32_t and uint64_t.
339 template <class Tgt, class Src>
340 typename std::enable_if<
341 std::is_integral<Src>::value && !std::is_signed<Src>::value
342 && detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
343 toAppend(Src value, Tgt * result) {
345 result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
349 * All small signed and unsigned integers to string go through 32-bit
350 * types int32_t and uint32_t, respectively.
352 template <class Tgt, class Src>
353 typename std::enable_if<
354 std::is_integral<Src>::value
355 && detail::IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
356 toAppend(Src value, Tgt * result) {
358 std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
360 toAppend<Tgt>(static_cast<Intermediate>(value), result);
363 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
364 // std::underlying_type became available by gcc 4.7.0
367 * Enumerated values get appended as integers.
369 template <class Tgt, class Src>
370 typename std::enable_if<
371 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
372 toAppend(Src value, Tgt * result) {
374 static_cast<typename std::underlying_type<Src>::type>(value), result);
380 * Enumerated values get appended as integers.
382 template <class Tgt, class Src>
383 typename std::enable_if<
384 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
385 toAppend(Src value, Tgt * result) {
386 /* static */ if (Src(-1) < 0) {
387 /* static */ if (sizeof(Src) <= sizeof(int)) {
388 toAppend(static_cast<int>(value), result);
390 toAppend(static_cast<long>(value), result);
393 /* static */ if (sizeof(Src) <= sizeof(int)) {
394 toAppend(static_cast<unsigned int>(value), result);
396 toAppend(static_cast<unsigned long>(value), result);
401 #endif // gcc 4.7 onwards
403 /*******************************************************************************
404 * Conversions from floating-point types to string types.
405 ******************************************************************************/
407 /** Wrapper around DoubleToStringConverter **/
408 template <class Tgt, class Src>
409 typename std::enable_if<
410 std::is_floating_point<Src>::value
411 && detail::IsSomeString<Tgt>::value>::type
415 double_conversion::DoubleToStringConverter::DtoaMode mode,
416 unsigned int numDigits) {
417 using namespace double_conversion;
418 DoubleToStringConverter
419 conv(DoubleToStringConverter::NO_FLAGS,
420 "infinity", "NaN", 'E',
421 -6, // decimal in shortest low
422 21, // decimal in shortest high
423 6, // max leading padding zeros
424 1); // max trailing padding zeros
426 StringBuilder builder(buffer, sizeof(buffer));
428 case DoubleToStringConverter::SHORTEST:
429 conv.ToShortest(value, &builder);
431 case DoubleToStringConverter::FIXED:
432 conv.ToFixed(value, numDigits, &builder);
435 CHECK(mode == DoubleToStringConverter::PRECISION);
436 conv.ToPrecision(value, numDigits, &builder);
439 const size_t length = builder.position();
441 result->append(buffer, length);
445 * As above, but for floating point
447 template <class Tgt, class Src>
448 typename std::enable_if<
449 std::is_floating_point<Src>::value
450 && detail::IsSomeString<Tgt>::value>::type
451 toAppend(Src value, Tgt * result) {
453 value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
457 * Variadic conversion to string. Appends each element in turn.
459 template <class T, class... Ts>
460 typename std::enable_if<sizeof...(Ts) >= 2
461 && detail::IsSomeString<
462 typename std::remove_pointer<
463 typename std::tuple_element<
464 sizeof...(Ts) - 1, std::tuple<Ts...>
465 >::type>::type>::value>::type
466 toAppend(const T& v, const Ts&... vs) {
467 toAppend(v, detail::getLastElement(vs...));
472 * Variadic base case: do nothing.
475 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
476 toAppend(Tgt* result) {
480 * Variadic base case: do nothing.
482 template <class Delimiter, class Tgt>
483 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
484 toAppendDelim(const Delimiter& delim, Tgt* result) {
488 * 1 element: same as toAppend.
490 template <class Delimiter, class T, class Tgt>
491 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
492 toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
497 * Append to string with a delimiter in between elements.
499 template <class Delimiter, class T, class... Ts>
500 typename std::enable_if<sizeof...(Ts) >= 2
501 && detail::IsSomeString<
502 typename std::remove_pointer<
503 typename std::tuple_element<
504 sizeof...(Ts) - 1, std::tuple<Ts...>
505 >::type>::type>::value>::type
506 toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
507 toAppend(v, delim, detail::getLastElement(vs...));
508 toAppendDelim(delim, vs...);
512 * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
515 template <class Tgt, class... Ts>
516 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
517 to(const Ts&... vs) {
519 toAppend(vs..., &result);
524 * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
525 * back-end for all types.
527 template <class Tgt, class Delim, class... Ts>
528 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
529 toDelim(const Delim& delim, const Ts&... vs) {
531 toAppendDelim(delim, vs..., &result);
535 /*******************************************************************************
536 * Conversions from string types to integral types.
537 ******************************************************************************/
542 * Finds the first non-digit in a string. The number of digits
543 * searched depends on the precision of the Tgt integral. Assumes the
544 * string starts with NO whitespace and NO sign.
546 * The semantics of the routine is:
548 * if (b >= e || !isdigit(*b)) return b;
551 * Complete unrolling marks bottom-line (i.e. entire conversion)
552 * improvements of 20%.
555 const char* findFirstNonDigit(const char* b, const char* e) {
557 auto const c = static_cast<unsigned>(*b) - '0';
563 // Maximum value of number when represented as a string
564 template <class T> struct MaxString {
565 static const char*const value;
570 * Lookup tables that converts from a decimal character value to an integral
571 * binary value, shifted by a decimal "shift" multiplier.
572 * For all character values in the range '0'..'9', the table at those
573 * index locations returns the actual decimal value shifted by the multiplier.
574 * For all other values, the lookup table returns an invalid OOR value.
576 // Out-of-range flag value, larger than the largest value that can fit in
577 // four decimal bytes (9999), but four of these added up together should
578 // still not overflow uint16_t.
579 constexpr int32_t OOR = 10000;
581 __attribute__((aligned(16))) constexpr uint16_t shift1[] = {
582 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
583 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
584 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
585 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
586 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
587 1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
588 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
589 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
590 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
591 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
592 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
593 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
594 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
595 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
596 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
597 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
598 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
599 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
600 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
601 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
602 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
603 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
604 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
605 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
606 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
607 OOR, OOR, OOR, OOR, OOR, OOR // 250
610 __attribute__((aligned(16))) constexpr uint16_t shift10[] = {
611 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
612 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
613 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
614 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
615 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
616 10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
617 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
618 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
619 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
620 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
621 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
622 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
623 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
624 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
625 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
626 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
627 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
628 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
629 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
630 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
631 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
632 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
633 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
634 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
635 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
636 OOR, OOR, OOR, OOR, OOR, OOR // 250
639 __attribute__((aligned(16))) constexpr uint16_t shift100[] = {
640 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
641 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
642 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
643 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
644 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
645 100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
646 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
647 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
648 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
649 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
650 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
651 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
652 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
653 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
654 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
655 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
656 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
657 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
658 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
659 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
660 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
661 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
662 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
663 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
664 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
665 OOR, OOR, OOR, OOR, OOR, OOR // 250
668 __attribute__((aligned(16))) constexpr uint16_t shift1000[] = {
669 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
670 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
671 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
672 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
673 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
674 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
675 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
676 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
677 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
678 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
679 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
680 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
681 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
682 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
683 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
684 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
685 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
686 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
687 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
688 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
689 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
690 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
691 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
692 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
693 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
694 OOR, OOR, OOR, OOR, OOR, OOR // 250
698 * String represented as a pair of pointers to char to unsigned
699 * integrals. Assumes NO whitespace before or after, and also that the
700 * string is composed entirely of digits. Tgt must be unsigned, and no
701 * sign is allowed in the string (even it's '+'). String may be empty,
702 * in which case digits_to throws.
705 Tgt digits_to(const char * b, const char * e) {
707 static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
710 const size_t size = e - b;
712 /* Although the string is entirely made of digits, we still need to
713 * check for overflow.
715 if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
716 // Leading zeros? If so, recurse to keep things simple
717 if (b < e && *b == '0') {
719 if (b == e) return 0; // just zeros, e.g. "0000"
720 if (*b != '0') return digits_to<Tgt>(b, e);
723 FOLLY_RANGE_CHECK(size == std::numeric_limits<Tgt>::digits10 + 1 &&
724 strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
725 "Numeric overflow upon conversion");
728 // Here we know that the number won't overflow when
729 // converted. Proceed without checks.
733 for (; e - b >= 4; b += 4) {
735 const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
736 const int32_t r1 = shift100[static_cast<size_t>(b[1])];
737 const int32_t r2 = shift10[static_cast<size_t>(b[2])];
738 const int32_t r3 = shift1[static_cast<size_t>(b[3])];
739 const auto sum = r0 + r1 + r2 + r3;
740 assert(sum < OOR && "Assumption: string only has digits");
746 const int32_t r0 = shift100[static_cast<size_t>(b[0])];
747 const int32_t r1 = shift10[static_cast<size_t>(b[1])];
748 const int32_t r2 = shift1[static_cast<size_t>(b[2])];
749 const auto sum = r0 + r1 + r2;
750 assert(sum < OOR && "Assumption: string only has digits");
751 return result * 1000 + sum;
754 const int32_t r0 = shift10[static_cast<size_t>(b[0])];
755 const int32_t r1 = shift1[static_cast<size_t>(b[1])];
756 const auto sum = r0 + r1;
757 assert(sum < OOR && "Assumption: string only has digits");
758 return result * 100 + sum;
761 const int32_t sum = shift1[static_cast<size_t>(b[0])];
762 assert(sum < OOR && "Assumption: string only has digits");
763 return result * 10 + sum;
768 FOLLY_RANGE_CHECK(size > 0, "Found no digits to convert in input");
773 bool str_to_bool(StringPiece * src);
775 } // namespace detail
778 * String represented as a pair of pointers to char to unsigned
779 * integrals. Assumes NO whitespace before or after.
782 typename std::enable_if<
783 std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
784 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
786 to(const char * b, const char * e) {
787 return detail::digits_to<Tgt>(b, e);
791 * String represented as a pair of pointers to char to signed
792 * integrals. Assumes NO whitespace before or after. Allows an
793 * optional leading sign.
796 typename std::enable_if<
797 std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
799 to(const char * b, const char * e) {
800 FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral");
803 Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
804 FOLLY_RANGE_CHECK(result <= 0, "Negative overflow.");
807 FOLLY_RANGE_CHECK(*b == '+', "Invalid lead character");
810 Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
811 FOLLY_RANGE_CHECK(result >= 0, "Overflow.");
816 * Parsing strings to integrals. These routines differ from
817 * to<integral>(string) in that they take a POINTER TO a StringPiece
818 * and alter that StringPiece to reflect progress information.
822 * StringPiece to integrals, with progress information. Alters the
823 * StringPiece parameter to munch the already-parsed characters.
826 typename std::enable_if<
827 std::is_integral<Tgt>::value
828 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
830 to(StringPiece * src) {
832 auto b = src->data(), past = src->data() + src->size();
834 FOLLY_RANGE_CHECK(b < past, "No digits found in input string");
835 if (!isspace(*b)) break;
840 // First digit is customized because we test for sign
841 bool negative = false;
842 /* static */ if (std::is_signed<Tgt>::value) {
847 FOLLY_RANGE_CHECK(*m == '+', "Invalid leading character in conversion"
854 FOLLY_RANGE_CHECK(m < past, "No digits found in input string");
855 FOLLY_RANGE_CHECK(isdigit(*m), "Non-digit character found");
856 m = detail::findFirstNonDigit<Tgt>(m + 1, past);
859 /* static */ if (!std::is_signed<Tgt>::value) {
860 result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
862 auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
865 FOLLY_RANGE_CHECK(result <= 0, "Negative overflow");
868 FOLLY_RANGE_CHECK(result >= 0, "Overflow");
871 src->advance(m - src->data());
876 * StringPiece to bool, with progress information. Alters the
877 * StringPiece parameter to munch the already-parsed characters.
880 typename std::enable_if<
881 std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
883 to(StringPiece * src) {
884 return detail::str_to_bool(src);
890 * Enforce that the suffix following a number is made up only of whitespace.
892 inline void enforceWhitespace(const char* b, const char* e) {
893 for (; b != e; ++b) {
894 FOLLY_RANGE_CHECK(isspace(*b), to<std::string>("Non-whitespace: ", *b));
898 } // namespace detail
901 * String or StringPiece to integrals. Accepts leading and trailing
902 * whitespace, but no non-space trailing characters.
905 typename std::enable_if<
906 std::is_integral<Tgt>::value,
908 to(StringPiece src) {
909 Tgt result = to<Tgt>(&src);
910 detail::enforceWhitespace(src.data(), src.data() + src.size());
914 /*******************************************************************************
915 * Conversions from string types to floating-point types.
916 ******************************************************************************/
919 * StringPiece to double, with progress information. Alters the
920 * StringPiece parameter to munch the already-parsed characters.
923 inline typename std::enable_if<
924 std::is_floating_point<Tgt>::value,
926 to(StringPiece *const src) {
927 using namespace double_conversion;
928 static StringToDoubleConverter
929 conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
930 | StringToDoubleConverter::ALLOW_LEADING_SPACES,
932 // return this for junk input string
933 std::numeric_limits<double>::quiet_NaN(),
936 FOLLY_RANGE_CHECK(!src->empty(), "No digits found in input string");
939 auto result = conv.StringToDouble(src->data(), src->size(),
940 &length); // processed char count
942 if (!std::isnan(result)) {
943 src->advance(length);
947 for (;; src->advance(1)) {
949 throw std::range_error("Unable to convert an empty string"
950 " to a floating point value.");
952 if (!isspace(src->front())) {
957 // Was that "inf[inity]"?
958 if (src->size() >= 3 && toupper((*src)[0]) == 'I'
959 && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
960 if (src->size() >= 8 &&
961 toupper((*src)[3]) == 'I' &&
962 toupper((*src)[4]) == 'N' &&
963 toupper((*src)[5]) == 'I' &&
964 toupper((*src)[6]) == 'T' &&
965 toupper((*src)[7]) == 'Y') {
970 return std::numeric_limits<Tgt>::infinity();
973 // Was that "-inf[inity]"?
974 if (src->size() >= 4 && toupper((*src)[0]) == '-'
975 && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
976 && toupper((*src)[3]) == 'F') {
977 if (src->size() >= 9 &&
978 toupper((*src)[4]) == 'I' &&
979 toupper((*src)[5]) == 'N' &&
980 toupper((*src)[6]) == 'I' &&
981 toupper((*src)[7]) == 'T' &&
982 toupper((*src)[8]) == 'Y') {
987 return -std::numeric_limits<Tgt>::infinity();
991 if (src->size() >= 3 && toupper((*src)[0]) == 'N'
992 && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
994 return std::numeric_limits<Tgt>::quiet_NaN();
998 if (src->size() >= 4 &&
999 toupper((*src)[0]) == '-' &&
1000 toupper((*src)[1]) == 'N' &&
1001 toupper((*src)[2]) == 'A' &&
1002 toupper((*src)[3]) == 'N') {
1004 return -std::numeric_limits<Tgt>::quiet_NaN();
1008 throw std::range_error("Unable to convert \"" + src->toString()
1009 + "\" to a floating point value.");
1013 * Any string, const char*, or StringPiece to double.
1015 template <class Tgt>
1016 typename std::enable_if<
1017 std::is_floating_point<Tgt>::value,
1019 to(StringPiece src) {
1020 Tgt result = to<double>(&src);
1021 detail::enforceWhitespace(src.data(), src.data() + src.size());
1025 /*******************************************************************************
1026 * Integral to floating point and back
1027 ******************************************************************************/
1030 * Checked conversion from integral to flating point and back. The
1031 * result must be convertible back to the source type without loss of
1032 * precision. This seems Draconian but sometimes is what's needed, and
1033 * complements existing routines nicely. For various rounding
1034 * routines, see <math>.
1036 template <class Tgt, class Src>
1037 typename std::enable_if<
1038 (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1040 (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1042 to(const Src & value) {
1044 auto witness = static_cast<Src>(result);
1045 if (value != witness) {
1046 throw std::range_error(
1047 to<std::string>("to<>: loss of precision when converting ", value,
1048 " to type ", typeid(Tgt).name()).c_str());
1053 /*******************************************************************************
1054 * Enum to anything and back
1055 ******************************************************************************/
1057 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
1058 // std::underlying_type became available by gcc 4.7.0
1060 template <class Tgt, class Src>
1061 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1062 to(const Src & value) {
1063 return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1066 template <class Tgt, class Src>
1067 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1068 to(const Src & value) {
1069 return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1074 template <class Tgt, class Src>
1075 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1076 to(const Src & value) {
1077 /* static */ if (Src(-1) < 0) {
1078 /* static */ if (sizeof(Src) <= sizeof(int)) {
1079 return to<Tgt>(static_cast<int>(value));
1081 return to<Tgt>(static_cast<long>(value));
1084 /* static */ if (sizeof(Src) <= sizeof(int)) {
1085 return to<Tgt>(static_cast<unsigned int>(value));
1087 return to<Tgt>(static_cast<unsigned long>(value));
1092 template <class Tgt, class Src>
1093 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1094 to(const Src & value) {
1095 /* static */ if (Tgt(-1) < 0) {
1096 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1097 return static_cast<Tgt>(to<int>(value));
1099 return static_cast<Tgt>(to<long>(value));
1102 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1103 return static_cast<Tgt>(to<unsigned int>(value));
1105 return static_cast<Tgt>(to<unsigned long>(value));
1110 #endif // gcc 4.7 onwards
1112 } // namespace folly
1114 // FOLLY_CONV_INTERNAL is defined by Conv.cpp. Keep the FOLLY_RANGE_CHECK
1115 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1116 // to avoid defining this global macro name in other files that include Conv.h.
1117 #ifndef FOLLY_CONV_INTERNAL
1118 #undef FOLLY_RANGE_CHECK
1121 #endif /* FOLLY_BASE_CONV_H_ */