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) {
328 result->push_back('-');
329 result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
331 result->append(buffer, uint64ToBufferUnsafe(value, buffer));
336 * As above, but for uint32_t and uint64_t.
338 template <class Tgt, class Src>
339 typename std::enable_if<
340 std::is_integral<Src>::value && !std::is_signed<Src>::value
341 && detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
342 toAppend(Src value, Tgt * result) {
344 result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
348 * All small signed and unsigned integers to string go through 32-bit
349 * types int32_t and uint32_t, respectively.
351 template <class Tgt, class Src>
352 typename std::enable_if<
353 std::is_integral<Src>::value
354 && detail::IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
355 toAppend(Src value, Tgt * result) {
357 std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
359 toAppend<Tgt>(static_cast<Intermediate>(value), result);
362 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
363 // std::underlying_type became available by gcc 4.7.0
366 * Enumerated values get appended as integers.
368 template <class Tgt, class Src>
369 typename std::enable_if<
370 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
371 toAppend(Src value, Tgt * result) {
373 static_cast<typename std::underlying_type<Src>::type>(value), result);
379 * Enumerated values get appended as integers.
381 template <class Tgt, class Src>
382 typename std::enable_if<
383 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
384 toAppend(Src value, Tgt * result) {
385 /* static */ if (Src(-1) < 0) {
386 /* static */ if (sizeof(Src) <= sizeof(int)) {
387 toAppend(static_cast<int>(value), result);
389 toAppend(static_cast<long>(value), result);
392 /* static */ if (sizeof(Src) <= sizeof(int)) {
393 toAppend(static_cast<unsigned int>(value), result);
395 toAppend(static_cast<unsigned long>(value), result);
400 #endif // gcc 4.7 onwards
402 /*******************************************************************************
403 * Conversions from floating-point types to string types.
404 ******************************************************************************/
406 /** Wrapper around DoubleToStringConverter **/
407 template <class Tgt, class Src>
408 typename std::enable_if<
409 std::is_floating_point<Src>::value
410 && detail::IsSomeString<Tgt>::value>::type
414 double_conversion::DoubleToStringConverter::DtoaMode mode,
415 unsigned int numDigits) {
416 using namespace double_conversion;
417 DoubleToStringConverter
418 conv(DoubleToStringConverter::NO_FLAGS,
419 "infinity", "NaN", 'E',
420 -6, // decimal in shortest low
421 21, // decimal in shortest high
422 6, // max leading padding zeros
423 1); // max trailing padding zeros
425 StringBuilder builder(buffer, sizeof(buffer));
427 case DoubleToStringConverter::SHORTEST:
428 conv.ToShortest(value, &builder);
430 case DoubleToStringConverter::FIXED:
431 conv.ToFixed(value, numDigits, &builder);
434 CHECK(mode == DoubleToStringConverter::PRECISION);
435 conv.ToPrecision(value, numDigits, &builder);
438 const size_t length = builder.position();
440 result->append(buffer, length);
444 * As above, but for floating point
446 template <class Tgt, class Src>
447 typename std::enable_if<
448 std::is_floating_point<Src>::value
449 && detail::IsSomeString<Tgt>::value>::type
450 toAppend(Src value, Tgt * result) {
452 value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
456 * Variadic conversion to string. Appends each element in turn.
458 template <class T, class... Ts>
459 typename std::enable_if<sizeof...(Ts) >= 2
460 && detail::IsSomeString<
461 typename std::remove_pointer<
462 typename std::tuple_element<
463 sizeof...(Ts) - 1, std::tuple<Ts...>
464 >::type>::type>::value>::type
465 toAppend(const T& v, const Ts&... vs) {
466 toAppend(v, detail::getLastElement(vs...));
471 * Variadic base case: do nothing.
474 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
475 toAppend(Tgt* result) {
479 * Variadic base case: do nothing.
481 template <class Delimiter, class Tgt>
482 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
483 toAppendDelim(const Delimiter& delim, Tgt* result) {
487 * 1 element: same as toAppend.
489 template <class Delimiter, class T, class Tgt>
490 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
491 toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
496 * Append to string with a delimiter in between elements.
498 template <class Delimiter, class T, class... Ts>
499 typename std::enable_if<sizeof...(Ts) >= 2
500 && detail::IsSomeString<
501 typename std::remove_pointer<
502 typename std::tuple_element<
503 sizeof...(Ts) - 1, std::tuple<Ts...>
504 >::type>::type>::value>::type
505 toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
506 toAppend(v, delim, detail::getLastElement(vs...));
507 toAppendDelim(delim, vs...);
511 * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
514 template <class Tgt, class... Ts>
515 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
516 to(const Ts&... vs) {
518 toAppend(vs..., &result);
523 * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
524 * back-end for all types.
526 template <class Tgt, class Delim, class... Ts>
527 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
528 toDelim(const Delim& delim, const Ts&... vs) {
530 toAppendDelim(delim, vs..., &result);
534 /*******************************************************************************
535 * Conversions from string types to integral types.
536 ******************************************************************************/
541 * Finds the first non-digit in a string. The number of digits
542 * searched depends on the precision of the Tgt integral. Assumes the
543 * string starts with NO whitespace and NO sign.
545 * The semantics of the routine is:
547 * if (b >= e || !isdigit(*b)) return b;
550 * Complete unrolling marks bottom-line (i.e. entire conversion)
551 * improvements of 20%.
554 const char* findFirstNonDigit(const char* b, const char* e) {
556 auto const c = static_cast<unsigned>(*b) - '0';
562 // Maximum value of number when represented as a string
563 template <class T> struct MaxString {
564 static const char*const value;
569 * Lookup tables that converts from a decimal character value to an integral
570 * binary value, shifted by a decimal "shift" multiplier.
571 * For all character values in the range '0'..'9', the table at those
572 * index locations returns the actual decimal value shifted by the multiplier.
573 * For all other values, the lookup table returns an invalid OOR value.
575 // Out-of-range flag value, larger than the largest value that can fit in
576 // four decimal bytes (9999), but four of these added up together should
577 // still not overflow uint16_t.
578 constexpr int32_t OOR = 10000;
580 __attribute__((aligned(16))) constexpr uint16_t shift1[] = {
581 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
582 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
583 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
584 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
585 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
586 1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
587 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
588 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
589 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
590 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
591 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
592 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
593 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
594 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
595 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
596 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
597 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
598 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
599 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
600 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
601 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
602 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
603 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
604 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
605 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
606 OOR, OOR, OOR, OOR, OOR, OOR // 250
609 __attribute__((aligned(16))) constexpr uint16_t shift10[] = {
610 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
611 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
612 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
613 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
614 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
615 10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
616 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
617 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
618 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
619 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
620 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
621 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
622 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
623 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
624 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
625 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
626 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
627 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
628 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
629 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
630 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
631 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
632 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
633 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
634 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
635 OOR, OOR, OOR, OOR, OOR, OOR // 250
638 __attribute__((aligned(16))) constexpr uint16_t shift100[] = {
639 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
640 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
641 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
642 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
643 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
644 100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
645 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
646 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
647 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
648 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
649 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
650 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
651 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
652 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
653 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
654 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
655 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
656 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
657 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
658 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
659 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
660 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
661 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
662 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
663 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
664 OOR, OOR, OOR, OOR, OOR, OOR // 250
667 __attribute__((aligned(16))) constexpr uint16_t shift1000[] = {
668 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
669 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
670 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
671 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
672 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
673 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
674 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
675 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
676 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
677 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
678 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
679 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
680 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
681 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
682 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
683 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
684 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
685 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
686 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
687 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
688 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
689 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
690 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
691 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
692 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
693 OOR, OOR, OOR, OOR, OOR, OOR // 250
697 * String represented as a pair of pointers to char to unsigned
698 * integrals. Assumes NO whitespace before or after, and also that the
699 * string is composed entirely of digits. Tgt must be unsigned, and no
700 * sign is allowed in the string (even it's '+'). String may be empty,
701 * in which case digits_to throws.
704 Tgt digits_to(const char * b, const char * e) {
706 static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
709 const size_t size = e - b;
711 /* Although the string is entirely made of digits, we still need to
712 * check for overflow.
714 if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
715 // Leading zeros? If so, recurse to keep things simple
716 if (b < e && *b == '0') {
718 if (b == e) return 0; // just zeros, e.g. "0000"
719 if (*b != '0') return digits_to<Tgt>(b, e);
722 FOLLY_RANGE_CHECK(size == std::numeric_limits<Tgt>::digits10 + 1 &&
723 strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
724 "Numeric overflow upon conversion");
727 // Here we know that the number won't overflow when
728 // converted. Proceed without checks.
732 for (; e - b >= 4; b += 4) {
734 const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
735 const int32_t r1 = shift100[static_cast<size_t>(b[1])];
736 const int32_t r2 = shift10[static_cast<size_t>(b[2])];
737 const int32_t r3 = shift1[static_cast<size_t>(b[3])];
738 const auto sum = r0 + r1 + r2 + r3;
739 assert(sum < OOR && "Assumption: string only has digits");
745 const int32_t r0 = shift100[static_cast<size_t>(b[0])];
746 const int32_t r1 = shift10[static_cast<size_t>(b[1])];
747 const int32_t r2 = shift1[static_cast<size_t>(b[2])];
748 const auto sum = r0 + r1 + r2;
749 assert(sum < OOR && "Assumption: string only has digits");
750 return result * 1000 + sum;
753 const int32_t r0 = shift10[static_cast<size_t>(b[0])];
754 const int32_t r1 = shift1[static_cast<size_t>(b[1])];
755 const auto sum = r0 + r1;
756 assert(sum < OOR && "Assumption: string only has digits");
757 return result * 100 + sum;
760 const int32_t sum = shift1[static_cast<size_t>(b[0])];
761 assert(sum < OOR && "Assumption: string only has digits");
762 return result * 10 + sum;
767 FOLLY_RANGE_CHECK(size > 0, "Found no digits to convert in input");
772 bool str_to_bool(StringPiece * src);
774 } // namespace detail
777 * String represented as a pair of pointers to char to unsigned
778 * integrals. Assumes NO whitespace before or after.
781 typename std::enable_if<
782 std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
783 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
785 to(const char * b, const char * e) {
786 return detail::digits_to<Tgt>(b, e);
790 * String represented as a pair of pointers to char to signed
791 * integrals. Assumes NO whitespace before or after. Allows an
792 * optional leading sign.
795 typename std::enable_if<
796 std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
798 to(const char * b, const char * e) {
799 FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral");
802 Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
803 FOLLY_RANGE_CHECK(result <= 0, "Negative overflow.");
806 FOLLY_RANGE_CHECK(*b == '+', "Invalid lead character");
809 Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
810 FOLLY_RANGE_CHECK(result >= 0, "Overflow.");
815 * Parsing strings to integrals. These routines differ from
816 * to<integral>(string) in that they take a POINTER TO a StringPiece
817 * and alter that StringPiece to reflect progress information.
821 * StringPiece to integrals, with progress information. Alters the
822 * StringPiece parameter to munch the already-parsed characters.
825 typename std::enable_if<
826 std::is_integral<Tgt>::value
827 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
829 to(StringPiece * src) {
831 auto b = src->data(), past = src->data() + src->size();
833 FOLLY_RANGE_CHECK(b < past, "No digits found in input string");
834 if (!isspace(*b)) break;
839 // First digit is customized because we test for sign
840 bool negative = false;
841 /* static */ if (std::is_signed<Tgt>::value) {
846 FOLLY_RANGE_CHECK(*m == '+', "Invalid leading character in conversion"
853 FOLLY_RANGE_CHECK(m < past, "No digits found in input string");
854 FOLLY_RANGE_CHECK(isdigit(*m), "Non-digit character found");
855 m = detail::findFirstNonDigit<Tgt>(m + 1, past);
858 /* static */ if (!std::is_signed<Tgt>::value) {
859 result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
861 auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
864 FOLLY_RANGE_CHECK(is_non_positive(result), "Negative overflow");
867 FOLLY_RANGE_CHECK(is_non_negative(result), "Overflow");
870 src->advance(m - src->data());
875 * StringPiece to bool, with progress information. Alters the
876 * StringPiece parameter to munch the already-parsed characters.
879 typename std::enable_if<
880 std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
882 to(StringPiece * src) {
883 return detail::str_to_bool(src);
889 * Enforce that the suffix following a number is made up only of whitespace.
891 inline void enforceWhitespace(const char* b, const char* e) {
892 for (; b != e; ++b) {
893 FOLLY_RANGE_CHECK(isspace(*b), to<std::string>("Non-whitespace: ", *b));
897 } // namespace detail
900 * String or StringPiece to integrals. Accepts leading and trailing
901 * whitespace, but no non-space trailing characters.
904 typename std::enable_if<
905 std::is_integral<Tgt>::value,
907 to(StringPiece src) {
908 Tgt result = to<Tgt>(&src);
909 detail::enforceWhitespace(src.data(), src.data() + src.size());
913 /*******************************************************************************
914 * Conversions from string types to floating-point types.
915 ******************************************************************************/
918 * StringPiece to double, with progress information. Alters the
919 * StringPiece parameter to munch the already-parsed characters.
922 inline typename std::enable_if<
923 std::is_floating_point<Tgt>::value,
925 to(StringPiece *const src) {
926 using namespace double_conversion;
927 static StringToDoubleConverter
928 conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
929 | StringToDoubleConverter::ALLOW_LEADING_SPACES,
931 // return this for junk input string
932 std::numeric_limits<double>::quiet_NaN(),
935 FOLLY_RANGE_CHECK(!src->empty(), "No digits found in input string");
938 auto result = conv.StringToDouble(src->data(), src->size(),
939 &length); // processed char count
941 if (!std::isnan(result)) {
942 src->advance(length);
946 for (;; src->advance(1)) {
948 throw std::range_error("Unable to convert an empty string"
949 " to a floating point value.");
951 if (!isspace(src->front())) {
956 // Was that "inf[inity]"?
957 if (src->size() >= 3 && toupper((*src)[0]) == 'I'
958 && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
959 if (src->size() >= 8 &&
960 toupper((*src)[3]) == 'I' &&
961 toupper((*src)[4]) == 'N' &&
962 toupper((*src)[5]) == 'I' &&
963 toupper((*src)[6]) == 'T' &&
964 toupper((*src)[7]) == 'Y') {
969 return std::numeric_limits<Tgt>::infinity();
972 // Was that "-inf[inity]"?
973 if (src->size() >= 4 && toupper((*src)[0]) == '-'
974 && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
975 && toupper((*src)[3]) == 'F') {
976 if (src->size() >= 9 &&
977 toupper((*src)[4]) == 'I' &&
978 toupper((*src)[5]) == 'N' &&
979 toupper((*src)[6]) == 'I' &&
980 toupper((*src)[7]) == 'T' &&
981 toupper((*src)[8]) == 'Y') {
986 return -std::numeric_limits<Tgt>::infinity();
990 if (src->size() >= 3 && toupper((*src)[0]) == 'N'
991 && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
993 return std::numeric_limits<Tgt>::quiet_NaN();
997 if (src->size() >= 4 &&
998 toupper((*src)[0]) == '-' &&
999 toupper((*src)[1]) == 'N' &&
1000 toupper((*src)[2]) == 'A' &&
1001 toupper((*src)[3]) == 'N') {
1003 return -std::numeric_limits<Tgt>::quiet_NaN();
1007 throw std::range_error("Unable to convert \"" + src->toString()
1008 + "\" to a floating point value.");
1012 * Any string, const char*, or StringPiece to double.
1014 template <class Tgt>
1015 typename std::enable_if<
1016 std::is_floating_point<Tgt>::value,
1018 to(StringPiece src) {
1019 Tgt result = to<double>(&src);
1020 detail::enforceWhitespace(src.data(), src.data() + src.size());
1024 /*******************************************************************************
1025 * Integral to floating point and back
1026 ******************************************************************************/
1029 * Checked conversion from integral to flating point and back. The
1030 * result must be convertible back to the source type without loss of
1031 * precision. This seems Draconian but sometimes is what's needed, and
1032 * complements existing routines nicely. For various rounding
1033 * routines, see <math>.
1035 template <class Tgt, class Src>
1036 typename std::enable_if<
1037 (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1039 (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1041 to(const Src & value) {
1043 auto witness = static_cast<Src>(result);
1044 if (value != witness) {
1045 throw std::range_error(
1046 to<std::string>("to<>: loss of precision when converting ", value,
1047 " to type ", typeid(Tgt).name()).c_str());
1052 /*******************************************************************************
1053 * Enum to anything and back
1054 ******************************************************************************/
1056 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
1057 // std::underlying_type became available by gcc 4.7.0
1059 template <class Tgt, class Src>
1060 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1061 to(const Src & value) {
1062 return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1065 template <class Tgt, class Src>
1066 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1067 to(const Src & value) {
1068 return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1073 template <class Tgt, class Src>
1074 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1075 to(const Src & value) {
1076 /* static */ if (Src(-1) < 0) {
1077 /* static */ if (sizeof(Src) <= sizeof(int)) {
1078 return to<Tgt>(static_cast<int>(value));
1080 return to<Tgt>(static_cast<long>(value));
1083 /* static */ if (sizeof(Src) <= sizeof(int)) {
1084 return to<Tgt>(static_cast<unsigned int>(value));
1086 return to<Tgt>(static_cast<unsigned long>(value));
1091 template <class Tgt, class Src>
1092 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1093 to(const Src & value) {
1094 /* static */ if (Tgt(-1) < 0) {
1095 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1096 return static_cast<Tgt>(to<int>(value));
1098 return static_cast<Tgt>(to<long>(value));
1101 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1102 return static_cast<Tgt>(to<unsigned int>(value));
1104 return static_cast<Tgt>(to<unsigned long>(value));
1109 #endif // gcc 4.7 onwards
1111 } // namespace folly
1113 // FOLLY_CONV_INTERNAL is defined by Conv.cpp. Keep the FOLLY_RANGE_CHECK
1114 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1115 // to avoid defining this global macro name in other files that include Conv.h.
1116 #ifndef FOLLY_CONV_INTERNAL
1117 #undef FOLLY_RANGE_CHECK
1120 #endif /* FOLLY_BASE_CONV_H_ */