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 // This class exists to specialize away std::tuple_element in the case where we
126 // have 0 template arguments. Without this, Clang/libc++ will blow a
127 // static_assert even if tuple_element is protected by an enable_if.
128 template <class... Ts>
129 struct last_element {
130 typedef typename std::enable_if<
132 typename std::tuple_element<
133 sizeof...(Ts) - 1, std::tuple<Ts...>
138 struct last_element<> {
142 } // namespace detail
144 /*******************************************************************************
145 * Conversions from integral types to string types.
146 ******************************************************************************/
148 #if FOLLY_HAVE_INT128_T
151 template <typename IntegerType>
152 constexpr unsigned int
154 return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
158 unsafeTelescope128(char * buffer, unsigned int room, unsigned __int128 x) {
159 typedef unsigned __int128 Usrc;
160 unsigned int p = room - 1;
162 while (x >= (Usrc(1) << 64)) { // Using 128-bit division while needed
163 const auto y = x / 10;
164 const auto digit = x % 10;
166 buffer[p--] = '0' + digit;
170 uint64_t xx = x; // Moving to faster 64-bit division thereafter
173 const auto y = xx / 10ULL;
174 const auto digit = xx % 10ULL;
176 buffer[p--] = '0' + digit;
180 buffer[p] = '0' + xx;
189 * Returns the number of digits in the base 10 representation of an
190 * uint64_t. Useful for preallocating buffers and such. It's also used
191 * internally, see below. Measurements suggest that defining a
192 * separate overload for 32-bit integers is not worthwhile.
195 inline uint32_t digits10(uint64_t v) {
198 if (LIKELY(v < 10)) return result;
199 if (LIKELY(v < 100)) return result + 1;
200 if (LIKELY(v < 1000)) return result + 2;
201 if (LIKELY(v < 10000)) return result + 3;
202 // Skip ahead by 4 orders of magnitude
209 * Copies the ASCII base 10 representation of v into buffer and
210 * returns the number of bytes written. Does NOT append a \0. Assumes
211 * the buffer points to digits10(v) bytes of valid memory. Note that
212 * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
213 * uint16_t needs at most 5 bytes, and so on. Measurements suggest
214 * that defining a separate overload for 32-bit integers is not
217 * This primitive is unsafe because it makes the size assumption and
218 * because it does not add a terminating \0.
221 inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
222 auto const result = digits10(v);
223 // WARNING: using size_t or pointer arithmetic for pos slows down
224 // the loop below 20x. This is because several 32-bit ops can be
225 // done in parallel, but only fewer 64-bit ones.
226 uint32_t pos = result - 1;
228 // Keep these together so a peephole optimization "sees" them and
229 // computes them in one shot.
230 auto const q = v / 10;
231 auto const r = static_cast<uint32_t>(v % 10);
232 buffer[pos--] = '0' + r;
235 // Last digit is trivial to handle
236 buffer[pos] = static_cast<uint32_t>(v) + '0';
241 * A single char gets appended.
244 void toAppend(char value, Tgt * result) {
249 * Everything implicitly convertible to const char* gets appended.
251 template <class Tgt, class Src>
252 typename std::enable_if<
253 std::is_convertible<Src, const char*>::value
254 && detail::IsSomeString<Tgt>::value>::type
255 toAppend(Src value, Tgt * result) {
256 // Treat null pointers like an empty string, as in:
257 // operator<<(std::ostream&, const char*).
258 const char* c = value;
260 result->append(value);
265 * Strings get appended, too.
267 template <class Tgt, class Src>
268 typename std::enable_if<
269 detail::IsSomeString<Src>::value && detail::IsSomeString<Tgt>::value>::type
270 toAppend(const Src& value, Tgt * result) {
271 result->append(value);
275 * and StringPiece objects too
278 typename std::enable_if<
279 detail::IsSomeString<Tgt>::value>::type
280 toAppend(StringPiece value, Tgt * result) {
281 result->append(value.data(), value.size());
285 * There's no implicit conversion from fbstring to other string types,
286 * so make a specialization.
289 typename std::enable_if<
290 detail::IsSomeString<Tgt>::value>::type
291 toAppend(const fbstring& value, Tgt * result) {
292 result->append(value.data(), value.size());
295 #if FOLLY_HAVE_INT128_T
297 * Special handling for 128 bit integers.
302 toAppend(__int128 value, Tgt * result) {
303 typedef unsigned __int128 Usrc;
304 char buffer[detail::digitsEnough<unsigned __int128>() + 1];
308 p = detail::unsafeTelescope128(buffer, sizeof(buffer), Usrc(-value));
311 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
314 result->append(buffer + p, buffer + sizeof(buffer));
319 toAppend(unsigned __int128 value, Tgt * result) {
320 char buffer[detail::digitsEnough<unsigned __int128>()];
323 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
325 result->append(buffer + p, buffer + sizeof(buffer));
331 * int32_t and int64_t to string (by appending) go through here. The
332 * result is APPENDED to a preexisting string passed as the second
333 * parameter. This should be efficient with fbstring because fbstring
334 * incurs no dynamic allocation below 23 bytes and no number has more
335 * than 22 bytes in its textual representation (20 for digits, one for
336 * sign, one for the terminating 0).
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) {
345 result->push_back('-');
346 result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
348 result->append(buffer, uint64ToBufferUnsafe(value, buffer));
353 * As above, but for uint32_t and uint64_t.
355 template <class Tgt, class Src>
356 typename std::enable_if<
357 std::is_integral<Src>::value && !std::is_signed<Src>::value
358 && detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
359 toAppend(Src value, Tgt * result) {
361 result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
365 * All small signed and unsigned integers to string go through 32-bit
366 * types int32_t and uint32_t, respectively.
368 template <class Tgt, class Src>
369 typename std::enable_if<
370 std::is_integral<Src>::value
371 && detail::IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
372 toAppend(Src value, Tgt * result) {
374 std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
376 toAppend<Tgt>(static_cast<Intermediate>(value), result);
379 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
380 // std::underlying_type became available by gcc 4.7.0
383 * Enumerated values get appended as integers.
385 template <class Tgt, class Src>
386 typename std::enable_if<
387 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
388 toAppend(Src value, Tgt * result) {
390 static_cast<typename std::underlying_type<Src>::type>(value), result);
396 * Enumerated values get appended as integers.
398 template <class Tgt, class Src>
399 typename std::enable_if<
400 std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type
401 toAppend(Src value, Tgt * result) {
402 /* static */ if (Src(-1) < 0) {
403 /* static */ if (sizeof(Src) <= sizeof(int)) {
404 toAppend(static_cast<int>(value), result);
406 toAppend(static_cast<long>(value), result);
409 /* static */ if (sizeof(Src) <= sizeof(int)) {
410 toAppend(static_cast<unsigned int>(value), result);
412 toAppend(static_cast<unsigned long>(value), result);
417 #endif // gcc 4.7 onwards
419 /*******************************************************************************
420 * Conversions from floating-point types to string types.
421 ******************************************************************************/
423 /** Wrapper around DoubleToStringConverter **/
424 template <class Tgt, class Src>
425 typename std::enable_if<
426 std::is_floating_point<Src>::value
427 && detail::IsSomeString<Tgt>::value>::type
431 double_conversion::DoubleToStringConverter::DtoaMode mode,
432 unsigned int numDigits) {
433 using namespace double_conversion;
434 DoubleToStringConverter
435 conv(DoubleToStringConverter::NO_FLAGS,
436 "infinity", "NaN", 'E',
437 -6, // decimal in shortest low
438 21, // decimal in shortest high
439 6, // max leading padding zeros
440 1); // max trailing padding zeros
442 StringBuilder builder(buffer, sizeof(buffer));
444 case DoubleToStringConverter::SHORTEST:
445 conv.ToShortest(value, &builder);
447 case DoubleToStringConverter::FIXED:
448 conv.ToFixed(value, numDigits, &builder);
451 CHECK(mode == DoubleToStringConverter::PRECISION);
452 conv.ToPrecision(value, numDigits, &builder);
455 const size_t length = builder.position();
457 result->append(buffer, length);
461 * As above, but for floating point
463 template <class Tgt, class Src>
464 typename std::enable_if<
465 std::is_floating_point<Src>::value
466 && detail::IsSomeString<Tgt>::value>::type
467 toAppend(Src value, Tgt * result) {
469 value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
473 * Variadic conversion to string. Appends each element in turn.
475 template <class T, class... Ts>
476 typename std::enable_if<sizeof...(Ts) >= 2
477 && detail::IsSomeString<
478 typename std::remove_pointer<
479 typename detail::last_element<Ts...>::type
480 >::type>::value>::type
481 toAppend(const T& v, const Ts&... vs) {
482 toAppend(v, detail::getLastElement(vs...));
487 * Variadic base case: do nothing.
490 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
491 toAppend(Tgt* result) {
495 * Variadic base case: do nothing.
497 template <class Delimiter, class Tgt>
498 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
499 toAppendDelim(const Delimiter& delim, Tgt* result) {
503 * 1 element: same as toAppend.
505 template <class Delimiter, class T, class Tgt>
506 typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
507 toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
512 * Append to string with a delimiter in between elements.
514 template <class Delimiter, class T, class... Ts>
515 typename std::enable_if<sizeof...(Ts) >= 2
516 && detail::IsSomeString<
517 typename std::remove_pointer<
518 typename detail::last_element<Ts...>::type
519 >::type>::value>::type
520 toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
521 toAppend(v, delim, detail::getLastElement(vs...));
522 toAppendDelim(delim, vs...);
526 * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
529 template <class Tgt, class... Ts>
530 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
531 to(const Ts&... vs) {
533 toAppend(vs..., &result);
538 * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
539 * back-end for all types.
541 template <class Tgt, class Delim, class... Ts>
542 typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type
543 toDelim(const Delim& delim, const Ts&... vs) {
545 toAppendDelim(delim, vs..., &result);
549 /*******************************************************************************
550 * Conversions from string types to integral types.
551 ******************************************************************************/
556 * Finds the first non-digit in a string. The number of digits
557 * searched depends on the precision of the Tgt integral. Assumes the
558 * string starts with NO whitespace and NO sign.
560 * The semantics of the routine is:
562 * if (b >= e || !isdigit(*b)) return b;
565 * Complete unrolling marks bottom-line (i.e. entire conversion)
566 * improvements of 20%.
569 const char* findFirstNonDigit(const char* b, const char* e) {
571 auto const c = static_cast<unsigned>(*b) - '0';
577 // Maximum value of number when represented as a string
578 template <class T> struct MaxString {
579 static const char*const value;
584 * Lookup tables that converts from a decimal character value to an integral
585 * binary value, shifted by a decimal "shift" multiplier.
586 * For all character values in the range '0'..'9', the table at those
587 * index locations returns the actual decimal value shifted by the multiplier.
588 * For all other values, the lookup table returns an invalid OOR value.
590 // Out-of-range flag value, larger than the largest value that can fit in
591 // four decimal bytes (9999), but four of these added up together should
592 // still not overflow uint16_t.
593 constexpr int32_t OOR = 10000;
595 __attribute__((aligned(16))) constexpr uint16_t shift1[] = {
596 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
597 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
598 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
599 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
600 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
601 1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
602 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
603 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
604 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
605 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
606 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
607 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
608 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
609 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
610 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
611 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
612 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
613 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
614 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
615 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
616 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
617 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
618 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
619 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
620 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
621 OOR, OOR, OOR, OOR, OOR, OOR // 250
624 __attribute__((aligned(16))) constexpr uint16_t shift10[] = {
625 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
626 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
627 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
628 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
629 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
630 10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
631 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
632 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
633 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
634 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
635 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
636 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
637 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
638 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
639 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
640 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
641 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
642 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
643 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
644 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
645 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
646 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
647 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
648 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
649 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
650 OOR, OOR, OOR, OOR, OOR, OOR // 250
653 __attribute__((aligned(16))) constexpr uint16_t shift100[] = {
654 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
655 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
656 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
657 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
658 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
659 100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
660 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
661 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
662 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
663 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
664 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
665 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
666 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
667 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
668 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
669 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
670 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
671 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
672 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
673 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
674 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
675 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
676 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
677 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
678 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
679 OOR, OOR, OOR, OOR, OOR, OOR // 250
682 __attribute__((aligned(16))) constexpr uint16_t shift1000[] = {
683 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
684 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
685 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
686 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
687 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
688 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
689 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
690 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
691 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
692 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
693 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
694 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
695 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
696 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
697 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
698 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
699 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
700 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
701 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
702 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
703 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
704 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
705 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
706 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
707 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
708 OOR, OOR, OOR, OOR, OOR, OOR // 250
712 * String represented as a pair of pointers to char to unsigned
713 * integrals. Assumes NO whitespace before or after, and also that the
714 * string is composed entirely of digits. Tgt must be unsigned, and no
715 * sign is allowed in the string (even it's '+'). String may be empty,
716 * in which case digits_to throws.
719 Tgt digits_to(const char * b, const char * e) {
721 static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
724 const size_t size = e - b;
726 /* Although the string is entirely made of digits, we still need to
727 * check for overflow.
729 if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
730 // Leading zeros? If so, recurse to keep things simple
731 if (b < e && *b == '0') {
733 if (b == e) return 0; // just zeros, e.g. "0000"
734 if (*b != '0') return digits_to<Tgt>(b, e);
737 FOLLY_RANGE_CHECK(size == std::numeric_limits<Tgt>::digits10 + 1 &&
738 strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
739 "Numeric overflow upon conversion");
742 // Here we know that the number won't overflow when
743 // converted. Proceed without checks.
747 for (; e - b >= 4; b += 4) {
749 const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
750 const int32_t r1 = shift100[static_cast<size_t>(b[1])];
751 const int32_t r2 = shift10[static_cast<size_t>(b[2])];
752 const int32_t r3 = shift1[static_cast<size_t>(b[3])];
753 const auto sum = r0 + r1 + r2 + r3;
754 assert(sum < OOR && "Assumption: string only has digits");
760 const int32_t r0 = shift100[static_cast<size_t>(b[0])];
761 const int32_t r1 = shift10[static_cast<size_t>(b[1])];
762 const int32_t r2 = shift1[static_cast<size_t>(b[2])];
763 const auto sum = r0 + r1 + r2;
764 assert(sum < OOR && "Assumption: string only has digits");
765 return result * 1000 + sum;
768 const int32_t r0 = shift10[static_cast<size_t>(b[0])];
769 const int32_t r1 = shift1[static_cast<size_t>(b[1])];
770 const auto sum = r0 + r1;
771 assert(sum < OOR && "Assumption: string only has digits");
772 return result * 100 + sum;
775 const int32_t sum = shift1[static_cast<size_t>(b[0])];
776 assert(sum < OOR && "Assumption: string only has digits");
777 return result * 10 + sum;
782 FOLLY_RANGE_CHECK(size > 0, "Found no digits to convert in input");
787 bool str_to_bool(StringPiece * src);
789 } // namespace detail
792 * String represented as a pair of pointers to char to unsigned
793 * integrals. Assumes NO whitespace before or after.
796 typename std::enable_if<
797 std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
798 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
800 to(const char * b, const char * e) {
801 return detail::digits_to<Tgt>(b, e);
805 * String represented as a pair of pointers to char to signed
806 * integrals. Assumes NO whitespace before or after. Allows an
807 * optional leading sign.
810 typename std::enable_if<
811 std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
813 to(const char * b, const char * e) {
814 FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral");
817 Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
818 FOLLY_RANGE_CHECK(result <= 0, "Negative overflow.");
821 FOLLY_RANGE_CHECK(*b == '+', "Invalid lead character");
824 Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
825 FOLLY_RANGE_CHECK(result >= 0, "Overflow.");
830 * Parsing strings to integrals. These routines differ from
831 * to<integral>(string) in that they take a POINTER TO a StringPiece
832 * and alter that StringPiece to reflect progress information.
836 * StringPiece to integrals, with progress information. Alters the
837 * StringPiece parameter to munch the already-parsed characters.
840 typename std::enable_if<
841 std::is_integral<Tgt>::value
842 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
844 to(StringPiece * src) {
846 auto b = src->data(), past = src->data() + src->size();
848 FOLLY_RANGE_CHECK(b < past, "No digits found in input string");
849 if (!isspace(*b)) break;
854 // First digit is customized because we test for sign
855 bool negative = false;
856 /* static */ if (std::is_signed<Tgt>::value) {
861 FOLLY_RANGE_CHECK(*m == '+', "Invalid leading character in conversion"
868 FOLLY_RANGE_CHECK(m < past, "No digits found in input string");
869 FOLLY_RANGE_CHECK(isdigit(*m), "Non-digit character found");
870 m = detail::findFirstNonDigit<Tgt>(m + 1, past);
873 /* static */ if (!std::is_signed<Tgt>::value) {
874 result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
876 auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
879 FOLLY_RANGE_CHECK(is_non_positive(result), "Negative overflow");
882 FOLLY_RANGE_CHECK(is_non_negative(result), "Overflow");
885 src->advance(m - src->data());
890 * StringPiece to bool, with progress information. Alters the
891 * StringPiece parameter to munch the already-parsed characters.
894 typename std::enable_if<
895 std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
897 to(StringPiece * src) {
898 return detail::str_to_bool(src);
904 * Enforce that the suffix following a number is made up only of whitespace.
906 inline void enforceWhitespace(const char* b, const char* e) {
907 for (; b != e; ++b) {
908 FOLLY_RANGE_CHECK(isspace(*b), to<std::string>("Non-whitespace: ", *b));
912 } // namespace detail
915 * String or StringPiece to integrals. Accepts leading and trailing
916 * whitespace, but no non-space trailing characters.
919 typename std::enable_if<
920 std::is_integral<Tgt>::value,
922 to(StringPiece src) {
923 Tgt result = to<Tgt>(&src);
924 detail::enforceWhitespace(src.data(), src.data() + src.size());
928 /*******************************************************************************
929 * Conversions from string types to floating-point types.
930 ******************************************************************************/
933 * StringPiece to double, with progress information. Alters the
934 * StringPiece parameter to munch the already-parsed characters.
937 inline typename std::enable_if<
938 std::is_floating_point<Tgt>::value,
940 to(StringPiece *const src) {
941 using namespace double_conversion;
942 static StringToDoubleConverter
943 conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
944 | StringToDoubleConverter::ALLOW_LEADING_SPACES,
946 // return this for junk input string
947 std::numeric_limits<double>::quiet_NaN(),
950 FOLLY_RANGE_CHECK(!src->empty(), "No digits found in input string");
953 auto result = conv.StringToDouble(src->data(), src->size(),
954 &length); // processed char count
956 if (!std::isnan(result)) {
957 src->advance(length);
961 for (;; src->advance(1)) {
963 throw std::range_error("Unable to convert an empty string"
964 " to a floating point value.");
966 if (!isspace(src->front())) {
971 // Was that "inf[inity]"?
972 if (src->size() >= 3 && toupper((*src)[0]) == 'I'
973 && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
974 if (src->size() >= 8 &&
975 toupper((*src)[3]) == 'I' &&
976 toupper((*src)[4]) == 'N' &&
977 toupper((*src)[5]) == 'I' &&
978 toupper((*src)[6]) == 'T' &&
979 toupper((*src)[7]) == 'Y') {
984 return std::numeric_limits<Tgt>::infinity();
987 // Was that "-inf[inity]"?
988 if (src->size() >= 4 && toupper((*src)[0]) == '-'
989 && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
990 && toupper((*src)[3]) == 'F') {
991 if (src->size() >= 9 &&
992 toupper((*src)[4]) == 'I' &&
993 toupper((*src)[5]) == 'N' &&
994 toupper((*src)[6]) == 'I' &&
995 toupper((*src)[7]) == 'T' &&
996 toupper((*src)[8]) == 'Y') {
1001 return -std::numeric_limits<Tgt>::infinity();
1005 if (src->size() >= 3 && toupper((*src)[0]) == 'N'
1006 && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
1008 return std::numeric_limits<Tgt>::quiet_NaN();
1012 if (src->size() >= 4 &&
1013 toupper((*src)[0]) == '-' &&
1014 toupper((*src)[1]) == 'N' &&
1015 toupper((*src)[2]) == 'A' &&
1016 toupper((*src)[3]) == 'N') {
1018 return -std::numeric_limits<Tgt>::quiet_NaN();
1022 throw std::range_error("Unable to convert \"" + src->toString()
1023 + "\" to a floating point value.");
1027 * Any string, const char*, or StringPiece to double.
1029 template <class Tgt>
1030 typename std::enable_if<
1031 std::is_floating_point<Tgt>::value,
1033 to(StringPiece src) {
1034 Tgt result = to<double>(&src);
1035 detail::enforceWhitespace(src.data(), src.data() + src.size());
1039 /*******************************************************************************
1040 * Integral to floating point and back
1041 ******************************************************************************/
1044 * Checked conversion from integral to flating point and back. The
1045 * result must be convertible back to the source type without loss of
1046 * precision. This seems Draconian but sometimes is what's needed, and
1047 * complements existing routines nicely. For various rounding
1048 * routines, see <math>.
1050 template <class Tgt, class Src>
1051 typename std::enable_if<
1052 (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1054 (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1056 to(const Src & value) {
1058 auto witness = static_cast<Src>(result);
1059 if (value != witness) {
1060 throw std::range_error(
1061 to<std::string>("to<>: loss of precision when converting ", value,
1062 " to type ", typeid(Tgt).name()).c_str());
1067 /*******************************************************************************
1068 * Enum to anything and back
1069 ******************************************************************************/
1071 #if defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
1072 // std::underlying_type became available by gcc 4.7.0
1074 template <class Tgt, class Src>
1075 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1076 to(const Src & value) {
1077 return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1080 template <class Tgt, class Src>
1081 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1082 to(const Src & value) {
1083 return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1088 template <class Tgt, class Src>
1089 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1090 to(const Src & value) {
1091 /* static */ if (Src(-1) < 0) {
1092 /* static */ if (sizeof(Src) <= sizeof(int)) {
1093 return to<Tgt>(static_cast<int>(value));
1095 return to<Tgt>(static_cast<long>(value));
1098 /* static */ if (sizeof(Src) <= sizeof(int)) {
1099 return to<Tgt>(static_cast<unsigned int>(value));
1101 return to<Tgt>(static_cast<unsigned long>(value));
1106 template <class Tgt, class Src>
1107 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1108 to(const Src & value) {
1109 /* static */ if (Tgt(-1) < 0) {
1110 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1111 return static_cast<Tgt>(to<int>(value));
1113 return static_cast<Tgt>(to<long>(value));
1116 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1117 return static_cast<Tgt>(to<unsigned int>(value));
1119 return static_cast<Tgt>(to<unsigned long>(value));
1124 #endif // gcc 4.7 onwards
1126 } // namespace folly
1128 // FOLLY_CONV_INTERNAL is defined by Conv.cpp. Keep the FOLLY_RANGE_CHECK
1129 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1130 // to avoid defining this global macro name in other files that include Conv.h.
1131 #ifndef FOLLY_CONV_INTERNAL
1132 #undef FOLLY_RANGE_CHECK
1135 #endif /* FOLLY_BASE_CONV_H_ */