2 * Copyright 2014 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 // V8 JavaScript implementation
43 #include <double-conversion/double-conversion.h>
45 #define FOLLY_RANGE_CHECK(condition, message) \
46 ((condition) ? (void)0 : throw std::range_error( \
47 (__FILE__ "(" + std::to_string((long long int) __LINE__) + "): " \
48 + (message)).c_str()))
52 /*******************************************************************************
53 * Integral to integral
54 ******************************************************************************/
57 * Checked conversion from integral to integral. The checks are only
58 * performed when meaningful, e.g. conversion from int to long goes
61 template <class Tgt, class Src>
62 typename std::enable_if<
63 std::is_integral<Src>::value && std::is_integral<Tgt>::value,
65 to(const Src & value) {
66 /* static */ if (std::numeric_limits<Tgt>::max()
67 < std::numeric_limits<Src>::max()) {
69 (!greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)),
73 /* static */ if (std::is_signed<Src>::value &&
74 (!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
76 (!less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)),
80 return static_cast<Tgt>(value);
83 /*******************************************************************************
84 * Floating point to floating point
85 ******************************************************************************/
87 template <class Tgt, class Src>
88 typename std::enable_if<
89 std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value,
91 to(const Src & value) {
92 /* static */ if (std::numeric_limits<Tgt>::max() <
93 std::numeric_limits<Src>::max()) {
94 FOLLY_RANGE_CHECK(value <= std::numeric_limits<Tgt>::max(),
96 FOLLY_RANGE_CHECK(value >= -std::numeric_limits<Tgt>::max(),
99 return boost::implicit_cast<Tgt>(value);
102 /*******************************************************************************
104 ******************************************************************************/
109 const T& getLastElement(const T & v) {
113 template <class T, class... Ts>
114 typename std::tuple_element<
116 std::tuple<T, Ts...> >::type const&
117 getLastElement(const T& v, const Ts&... vs) {
118 return getLastElement(vs...);
121 // This class exists to specialize away std::tuple_element in the case where we
122 // have 0 template arguments. Without this, Clang/libc++ will blow a
123 // static_assert even if tuple_element is protected by an enable_if.
124 template <class... Ts>
125 struct last_element {
126 typedef typename std::enable_if<
128 typename std::tuple_element<
129 sizeof...(Ts) - 1, std::tuple<Ts...>
134 struct last_element<> {
138 } // namespace detail
140 /*******************************************************************************
141 * Conversions from integral types to string types.
142 ******************************************************************************/
144 #if FOLLY_HAVE_INT128_T
147 template <typename IntegerType>
148 constexpr unsigned int
150 return ceil((double(sizeof(IntegerType) * CHAR_BIT) * M_LN2) / M_LN10);
154 unsafeTelescope128(char * buffer, unsigned int room, unsigned __int128 x) {
155 typedef unsigned __int128 Usrc;
156 unsigned int p = room - 1;
158 while (x >= (Usrc(1) << 64)) { // Using 128-bit division while needed
159 const auto y = x / 10;
160 const auto digit = x % 10;
162 buffer[p--] = '0' + digit;
166 uint64_t xx = x; // Moving to faster 64-bit division thereafter
169 const auto y = xx / 10ULL;
170 const auto digit = xx % 10ULL;
172 buffer[p--] = '0' + digit;
176 buffer[p] = '0' + xx;
185 * Returns the number of digits in the base 10 representation of an
186 * uint64_t. Useful for preallocating buffers and such. It's also used
187 * internally, see below. Measurements suggest that defining a
188 * separate overload for 32-bit integers is not worthwhile.
191 inline uint32_t digits10(uint64_t v) {
194 if (LIKELY(v < 10)) return result;
195 if (LIKELY(v < 100)) return result + 1;
196 if (LIKELY(v < 1000)) return result + 2;
197 if (LIKELY(v < 10000)) return result + 3;
198 // Skip ahead by 4 orders of magnitude
205 * Copies the ASCII base 10 representation of v into buffer and
206 * returns the number of bytes written. Does NOT append a \0. Assumes
207 * the buffer points to digits10(v) bytes of valid memory. Note that
208 * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,
209 * uint16_t needs at most 5 bytes, and so on. Measurements suggest
210 * that defining a separate overload for 32-bit integers is not
213 * This primitive is unsafe because it makes the size assumption and
214 * because it does not add a terminating \0.
217 inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {
218 auto const result = digits10(v);
219 // WARNING: using size_t or pointer arithmetic for pos slows down
220 // the loop below 20x. This is because several 32-bit ops can be
221 // done in parallel, but only fewer 64-bit ones.
222 uint32_t pos = result - 1;
224 // Keep these together so a peephole optimization "sees" them and
225 // computes them in one shot.
226 auto const q = v / 10;
227 auto const r = static_cast<uint32_t>(v % 10);
228 buffer[pos--] = '0' + r;
231 // Last digit is trivial to handle
232 buffer[pos] = static_cast<uint32_t>(v) + '0';
237 * A single char gets appended.
240 void toAppend(char value, Tgt * result) {
245 * Ubiquitous helper template for writing string appenders
247 template <class T> struct IsSomeString {
248 enum { value = std::is_same<T, std::string>::value
249 || std::is_same<T, fbstring>::value };
253 * Everything implicitly convertible to const char* gets appended.
255 template <class Tgt, class Src>
256 typename std::enable_if<
257 std::is_convertible<Src, const char*>::value
258 && IsSomeString<Tgt>::value>::type
259 toAppend(Src value, Tgt * result) {
260 // Treat null pointers like an empty string, as in:
261 // operator<<(std::ostream&, const char*).
262 const char* c = value;
264 result->append(value);
269 * Strings get appended, too.
271 template <class Tgt, class Src>
272 typename std::enable_if<
273 IsSomeString<Src>::value && IsSomeString<Tgt>::value>::type
274 toAppend(const Src& value, Tgt * result) {
275 result->append(value);
279 * and StringPiece objects too
282 typename std::enable_if<
283 IsSomeString<Tgt>::value>::type
284 toAppend(StringPiece value, Tgt * result) {
285 result->append(value.data(), value.size());
289 * There's no implicit conversion from fbstring to other string types,
290 * so make a specialization.
293 typename std::enable_if<
294 IsSomeString<Tgt>::value>::type
295 toAppend(const fbstring& value, Tgt * result) {
296 result->append(value.data(), value.size());
299 #if FOLLY_HAVE_INT128_T
301 * Special handling for 128 bit integers.
306 toAppend(__int128 value, Tgt * result) {
307 typedef unsigned __int128 Usrc;
308 char buffer[detail::digitsEnough<unsigned __int128>() + 1];
312 p = detail::unsafeTelescope128(buffer, sizeof(buffer), Usrc(-value));
315 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
318 result->append(buffer + p, buffer + sizeof(buffer));
323 toAppend(unsigned __int128 value, Tgt * result) {
324 char buffer[detail::digitsEnough<unsigned __int128>()];
327 p = detail::unsafeTelescope128(buffer, sizeof(buffer), value);
329 result->append(buffer + p, buffer + sizeof(buffer));
335 * int32_t and int64_t to string (by appending) go through here. The
336 * result is APPENDED to a preexisting string passed as the second
337 * parameter. This should be efficient with fbstring because fbstring
338 * incurs no dynamic allocation below 23 bytes and no number has more
339 * than 22 bytes in its textual representation (20 for digits, one for
340 * sign, one for the terminating 0).
342 template <class Tgt, class Src>
343 typename std::enable_if<
344 std::is_integral<Src>::value && std::is_signed<Src>::value &&
345 IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
346 toAppend(Src value, Tgt * result) {
349 result->push_back('-');
350 result->append(buffer, uint64ToBufferUnsafe(-uint64_t(value), buffer));
352 result->append(buffer, uint64ToBufferUnsafe(value, buffer));
357 * As above, but for uint32_t and uint64_t.
359 template <class Tgt, class Src>
360 typename std::enable_if<
361 std::is_integral<Src>::value && !std::is_signed<Src>::value
362 && IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
363 toAppend(Src value, Tgt * result) {
365 result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
369 * All small signed and unsigned integers to string go through 32-bit
370 * types int32_t and uint32_t, respectively.
372 template <class Tgt, class Src>
373 typename std::enable_if<
374 std::is_integral<Src>::value
375 && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
376 toAppend(Src value, Tgt * result) {
378 std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
380 toAppend<Tgt>(static_cast<Intermediate>(value), result);
383 #if defined(__clang__) || __GNUC_PREREQ(4, 7)
384 // std::underlying_type became available by gcc 4.7.0
387 * Enumerated values get appended as integers.
389 template <class Tgt, class Src>
390 typename std::enable_if<
391 std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
392 toAppend(Src value, Tgt * result) {
394 static_cast<typename std::underlying_type<Src>::type>(value), result);
400 * Enumerated values get appended as integers.
402 template <class Tgt, class Src>
403 typename std::enable_if<
404 std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
405 toAppend(Src value, Tgt * result) {
406 /* static */ if (Src(-1) < 0) {
407 /* static */ if (sizeof(Src) <= sizeof(int)) {
408 toAppend(static_cast<int>(value), result);
410 toAppend(static_cast<long>(value), result);
413 /* static */ if (sizeof(Src) <= sizeof(int)) {
414 toAppend(static_cast<unsigned int>(value), result);
416 toAppend(static_cast<unsigned long>(value), result);
421 #endif // gcc 4.7 onwards
423 /*******************************************************************************
424 * Conversions from floating-point types to string types.
425 ******************************************************************************/
427 /** Wrapper around DoubleToStringConverter **/
428 template <class Tgt, class Src>
429 typename std::enable_if<
430 std::is_floating_point<Src>::value
431 && IsSomeString<Tgt>::value>::type
435 double_conversion::DoubleToStringConverter::DtoaMode mode,
436 unsigned int numDigits) {
437 using namespace double_conversion;
438 DoubleToStringConverter
439 conv(DoubleToStringConverter::NO_FLAGS,
440 "infinity", "NaN", 'E',
441 -6, // decimal in shortest low
442 21, // decimal in shortest high
443 6, // max leading padding zeros
444 1); // max trailing padding zeros
446 StringBuilder builder(buffer, sizeof(buffer));
448 case DoubleToStringConverter::SHORTEST:
449 conv.ToShortest(value, &builder);
451 case DoubleToStringConverter::FIXED:
452 conv.ToFixed(value, numDigits, &builder);
455 CHECK(mode == DoubleToStringConverter::PRECISION);
456 conv.ToPrecision(value, numDigits, &builder);
459 const size_t length = builder.position();
461 result->append(buffer, length);
465 * As above, but for floating point
467 template <class Tgt, class Src>
468 typename std::enable_if<
469 std::is_floating_point<Src>::value
470 && IsSomeString<Tgt>::value>::type
471 toAppend(Src value, Tgt * result) {
473 value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
477 * Variadic conversion to string. Appends each element in turn.
479 template <class T, class... Ts>
480 typename std::enable_if<sizeof...(Ts) >= 2
482 typename std::remove_pointer<
483 typename detail::last_element<Ts...>::type
484 >::type>::value>::type
485 toAppend(const T& v, const Ts&... vs) {
486 toAppend(v, detail::getLastElement(vs...));
491 * Variadic base case: do nothing.
494 typename std::enable_if<IsSomeString<Tgt>::value>::type
495 toAppend(Tgt* result) {
499 * Variadic base case: do nothing.
501 template <class Delimiter, class Tgt>
502 typename std::enable_if<IsSomeString<Tgt>::value>::type
503 toAppendDelim(const Delimiter& delim, Tgt* result) {
507 * 1 element: same as toAppend.
509 template <class Delimiter, class T, class Tgt>
510 typename std::enable_if<IsSomeString<Tgt>::value>::type
511 toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
516 * Append to string with a delimiter in between elements.
518 template <class Delimiter, class T, class... Ts>
519 typename std::enable_if<sizeof...(Ts) >= 2
521 typename std::remove_pointer<
522 typename detail::last_element<Ts...>::type
523 >::type>::value>::type
524 toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
525 toAppend(v, delim, detail::getLastElement(vs...));
526 toAppendDelim(delim, vs...);
530 * to<SomeString>(SomeString str) returns itself. As both std::string and
531 * folly::fbstring use Copy-on-Write, it's much more efficient by
532 * avoiding copying the underlying char array.
534 template <class Tgt, class Src>
535 typename std::enable_if<
536 IsSomeString<Tgt>::value && std::is_same<Tgt, Src>::value,
538 to(const Src & value) {
543 * to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
546 template <class Tgt, class... Ts>
547 typename std::enable_if<
548 IsSomeString<Tgt>::value && (
549 sizeof...(Ts) != 1 ||
550 !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
552 to(const Ts&... vs) {
554 toAppend(vs..., &result);
559 * toDelim<SomeString>(SomeString str) returns itself.
561 template <class Tgt, class Delim, class Src>
562 typename std::enable_if<
563 IsSomeString<Tgt>::value && std::is_same<Tgt, Src>::value,
565 toDelim(const Delim& delim, const Src & value) {
570 * toDelim<SomeString>(delim, v1, v2, ...) uses toAppendDelim() as
571 * back-end for all types.
573 template <class Tgt, class Delim, class... Ts>
574 typename std::enable_if<
575 IsSomeString<Tgt>::value && (
576 sizeof...(Ts) != 1 ||
577 !std::is_same<Tgt, typename detail::last_element<Ts...>::type>::value),
579 toDelim(const Delim& delim, const Ts&... vs) {
581 toAppendDelim(delim, vs..., &result);
585 /*******************************************************************************
586 * Conversions from string types to integral types.
587 ******************************************************************************/
592 * Finds the first non-digit in a string. The number of digits
593 * searched depends on the precision of the Tgt integral. Assumes the
594 * string starts with NO whitespace and NO sign.
596 * The semantics of the routine is:
598 * if (b >= e || !isdigit(*b)) return b;
601 * Complete unrolling marks bottom-line (i.e. entire conversion)
602 * improvements of 20%.
605 const char* findFirstNonDigit(const char* b, const char* e) {
607 auto const c = static_cast<unsigned>(*b) - '0';
613 // Maximum value of number when represented as a string
614 template <class T> struct MaxString {
615 static const char*const value;
620 * Lookup tables that converts from a decimal character value to an integral
621 * binary value, shifted by a decimal "shift" multiplier.
622 * For all character values in the range '0'..'9', the table at those
623 * index locations returns the actual decimal value shifted by the multiplier.
624 * For all other values, the lookup table returns an invalid OOR value.
626 // Out-of-range flag value, larger than the largest value that can fit in
627 // four decimal bytes (9999), but four of these added up together should
628 // still not overflow uint16_t.
629 constexpr int32_t OOR = 10000;
631 __attribute__((aligned(16))) constexpr uint16_t shift1[] = {
632 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
633 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
634 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
635 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
636 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
637 1, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,
638 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
639 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
640 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
641 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
642 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
643 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
644 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
645 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
646 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
647 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
648 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
649 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
650 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
651 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
652 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
653 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
654 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
655 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
656 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
657 OOR, OOR, OOR, OOR, OOR, OOR // 250
660 __attribute__((aligned(16))) constexpr uint16_t shift10[] = {
661 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
662 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
663 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
664 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
665 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
666 10, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,
667 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
668 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
669 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
670 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
671 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
672 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
673 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
674 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
675 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
676 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
677 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
678 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
679 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
680 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
681 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
682 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
683 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
684 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
685 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
686 OOR, OOR, OOR, OOR, OOR, OOR // 250
689 __attribute__((aligned(16))) constexpr uint16_t shift100[] = {
690 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
691 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
692 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
693 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
694 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
695 100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,
696 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
697 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
698 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
699 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
700 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
701 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
702 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
703 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
704 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
705 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
706 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
707 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
708 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
709 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
710 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
711 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
712 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
713 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
714 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
715 OOR, OOR, OOR, OOR, OOR, OOR // 250
718 __attribute__((aligned(16))) constexpr uint16_t shift1000[] = {
719 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 0-9
720 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 10
721 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 20
722 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 30
723 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0, // 40
724 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,
725 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 60
726 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 70
727 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 80
728 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 90
729 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 100
730 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 110
731 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 120
732 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 130
733 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 140
734 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 150
735 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 160
736 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 170
737 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 180
738 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 190
739 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 200
740 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 210
741 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 220
742 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 230
743 OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, // 240
744 OOR, OOR, OOR, OOR, OOR, OOR // 250
748 * String represented as a pair of pointers to char to unsigned
749 * integrals. Assumes NO whitespace before or after, and also that the
750 * string is composed entirely of digits. Tgt must be unsigned, and no
751 * sign is allowed in the string (even it's '+'). String may be empty,
752 * in which case digits_to throws.
755 Tgt digits_to(const char * b, const char * e) {
757 static_assert(!std::is_signed<Tgt>::value, "Unsigned type expected");
760 const size_t size = e - b;
762 /* Although the string is entirely made of digits, we still need to
763 * check for overflow.
765 if (size >= std::numeric_limits<Tgt>::digits10 + 1) {
766 // Leading zeros? If so, recurse to keep things simple
767 if (b < e && *b == '0') {
769 if (b == e) return 0; // just zeros, e.g. "0000"
770 if (*b != '0') return digits_to<Tgt>(b, e);
773 FOLLY_RANGE_CHECK(size == std::numeric_limits<Tgt>::digits10 + 1 &&
774 strncmp(b, detail::MaxString<Tgt>::value, size) <= 0,
775 "Numeric overflow upon conversion");
778 // Here we know that the number won't overflow when
779 // converted. Proceed without checks.
783 for (; e - b >= 4; b += 4) {
785 const int32_t r0 = shift1000[static_cast<size_t>(b[0])];
786 const int32_t r1 = shift100[static_cast<size_t>(b[1])];
787 const int32_t r2 = shift10[static_cast<size_t>(b[2])];
788 const int32_t r3 = shift1[static_cast<size_t>(b[3])];
789 const auto sum = r0 + r1 + r2 + r3;
790 assert(sum < OOR && "Assumption: string only has digits");
796 const int32_t r0 = shift100[static_cast<size_t>(b[0])];
797 const int32_t r1 = shift10[static_cast<size_t>(b[1])];
798 const int32_t r2 = shift1[static_cast<size_t>(b[2])];
799 const auto sum = r0 + r1 + r2;
800 assert(sum < OOR && "Assumption: string only has digits");
801 return result * 1000 + sum;
804 const int32_t r0 = shift10[static_cast<size_t>(b[0])];
805 const int32_t r1 = shift1[static_cast<size_t>(b[1])];
806 const auto sum = r0 + r1;
807 assert(sum < OOR && "Assumption: string only has digits");
808 return result * 100 + sum;
811 const int32_t sum = shift1[static_cast<size_t>(b[0])];
812 assert(sum < OOR && "Assumption: string only has digits");
813 return result * 10 + sum;
818 FOLLY_RANGE_CHECK(size > 0, "Found no digits to convert in input");
823 bool str_to_bool(StringPiece * src);
825 } // namespace detail
828 * String represented as a pair of pointers to char to unsigned
829 * integrals. Assumes NO whitespace before or after.
832 typename std::enable_if<
833 std::is_integral<Tgt>::value && !std::is_signed<Tgt>::value
834 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
836 to(const char * b, const char * e) {
837 return detail::digits_to<Tgt>(b, e);
841 * String represented as a pair of pointers to char to signed
842 * integrals. Assumes NO whitespace before or after. Allows an
843 * optional leading sign.
846 typename std::enable_if<
847 std::is_integral<Tgt>::value && std::is_signed<Tgt>::value,
849 to(const char * b, const char * e) {
850 FOLLY_RANGE_CHECK(b < e, "Empty input string in conversion to integral");
853 Tgt result = -to<typename std::make_unsigned<Tgt>::type>(b + 1, e);
854 FOLLY_RANGE_CHECK(result <= 0, "Negative overflow.");
857 FOLLY_RANGE_CHECK(*b == '+', "Invalid lead character");
860 Tgt result = to<typename std::make_unsigned<Tgt>::type>(b, e);
861 FOLLY_RANGE_CHECK(result >= 0, "Overflow.");
866 * Parsing strings to integrals. These routines differ from
867 * to<integral>(string) in that they take a POINTER TO a StringPiece
868 * and alter that StringPiece to reflect progress information.
872 * StringPiece to integrals, with progress information. Alters the
873 * StringPiece parameter to munch the already-parsed characters.
876 typename std::enable_if<
877 std::is_integral<Tgt>::value
878 && !std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
880 to(StringPiece * src) {
882 auto b = src->data(), past = src->data() + src->size();
884 FOLLY_RANGE_CHECK(b < past, "No digits found in input string");
885 if (!isspace(*b)) break;
890 // First digit is customized because we test for sign
891 bool negative = false;
892 /* static */ if (std::is_signed<Tgt>::value) {
897 FOLLY_RANGE_CHECK(*m == '+', "Invalid leading character in conversion"
904 FOLLY_RANGE_CHECK(m < past, "No digits found in input string");
905 FOLLY_RANGE_CHECK(isdigit(*m), "Non-digit character found");
906 m = detail::findFirstNonDigit<Tgt>(m + 1, past);
909 /* static */ if (!std::is_signed<Tgt>::value) {
910 result = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
912 auto t = detail::digits_to<typename std::make_unsigned<Tgt>::type>(b, m);
915 FOLLY_RANGE_CHECK(is_non_positive(result), "Negative overflow");
918 FOLLY_RANGE_CHECK(is_non_negative(result), "Overflow");
921 src->advance(m - src->data());
926 * StringPiece to bool, with progress information. Alters the
927 * StringPiece parameter to munch the already-parsed characters.
930 typename std::enable_if<
931 std::is_same<typename std::remove_cv<Tgt>::type, bool>::value,
933 to(StringPiece * src) {
934 return detail::str_to_bool(src);
940 * Enforce that the suffix following a number is made up only of whitespace.
942 inline void enforceWhitespace(const char* b, const char* e) {
943 for (; b != e; ++b) {
944 FOLLY_RANGE_CHECK(isspace(*b), to<std::string>("Non-whitespace: ", *b));
948 } // namespace detail
951 * String or StringPiece to integrals. Accepts leading and trailing
952 * whitespace, but no non-space trailing characters.
955 typename std::enable_if<
956 std::is_integral<Tgt>::value,
958 to(StringPiece src) {
959 Tgt result = to<Tgt>(&src);
960 detail::enforceWhitespace(src.data(), src.data() + src.size());
964 /*******************************************************************************
965 * Conversions from string types to floating-point types.
966 ******************************************************************************/
969 * StringPiece to double, with progress information. Alters the
970 * StringPiece parameter to munch the already-parsed characters.
973 inline typename std::enable_if<
974 std::is_floating_point<Tgt>::value,
976 to(StringPiece *const src) {
977 using namespace double_conversion;
978 static StringToDoubleConverter
979 conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
980 | StringToDoubleConverter::ALLOW_LEADING_SPACES,
982 // return this for junk input string
983 std::numeric_limits<double>::quiet_NaN(),
986 FOLLY_RANGE_CHECK(!src->empty(), "No digits found in input string");
989 auto result = conv.StringToDouble(src->data(), src->size(),
990 &length); // processed char count
992 if (!std::isnan(result)) {
993 src->advance(length);
997 for (;; src->advance(1)) {
999 throw std::range_error("Unable to convert an empty string"
1000 " to a floating point value.");
1002 if (!isspace(src->front())) {
1007 // Was that "inf[inity]"?
1008 if (src->size() >= 3 && toupper((*src)[0]) == 'I'
1009 && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
1010 if (src->size() >= 8 &&
1011 toupper((*src)[3]) == 'I' &&
1012 toupper((*src)[4]) == 'N' &&
1013 toupper((*src)[5]) == 'I' &&
1014 toupper((*src)[6]) == 'T' &&
1015 toupper((*src)[7]) == 'Y') {
1020 return std::numeric_limits<Tgt>::infinity();
1023 // Was that "-inf[inity]"?
1024 if (src->size() >= 4 && toupper((*src)[0]) == '-'
1025 && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
1026 && toupper((*src)[3]) == 'F') {
1027 if (src->size() >= 9 &&
1028 toupper((*src)[4]) == 'I' &&
1029 toupper((*src)[5]) == 'N' &&
1030 toupper((*src)[6]) == 'I' &&
1031 toupper((*src)[7]) == 'T' &&
1032 toupper((*src)[8]) == 'Y') {
1037 return -std::numeric_limits<Tgt>::infinity();
1041 if (src->size() >= 3 && toupper((*src)[0]) == 'N'
1042 && toupper((*src)[1]) == 'A' && toupper((*src)[2]) == 'N') {
1044 return std::numeric_limits<Tgt>::quiet_NaN();
1048 if (src->size() >= 4 &&
1049 toupper((*src)[0]) == '-' &&
1050 toupper((*src)[1]) == 'N' &&
1051 toupper((*src)[2]) == 'A' &&
1052 toupper((*src)[3]) == 'N') {
1054 return -std::numeric_limits<Tgt>::quiet_NaN();
1058 throw std::range_error("Unable to convert \"" + src->toString()
1059 + "\" to a floating point value.");
1063 * Any string, const char*, or StringPiece to double.
1065 template <class Tgt>
1066 typename std::enable_if<
1067 std::is_floating_point<Tgt>::value,
1069 to(StringPiece src) {
1070 Tgt result = to<double>(&src);
1071 detail::enforceWhitespace(src.data(), src.data() + src.size());
1075 /*******************************************************************************
1076 * Integral to floating point and back
1077 ******************************************************************************/
1080 * Checked conversion from integral to flating point and back. The
1081 * result must be convertible back to the source type without loss of
1082 * precision. This seems Draconian but sometimes is what's needed, and
1083 * complements existing routines nicely. For various rounding
1084 * routines, see <math>.
1086 template <class Tgt, class Src>
1087 typename std::enable_if<
1088 (std::is_integral<Src>::value && std::is_floating_point<Tgt>::value)
1090 (std::is_floating_point<Src>::value && std::is_integral<Tgt>::value),
1092 to(const Src & value) {
1094 auto witness = static_cast<Src>(result);
1095 if (value != witness) {
1096 throw std::range_error(
1097 to<std::string>("to<>: loss of precision when converting ", value,
1098 " to type ", typeid(Tgt).name()).c_str());
1103 /*******************************************************************************
1104 * Enum to anything and back
1105 ******************************************************************************/
1107 #if defined(__clang__) || __GNUC_PREREQ(4, 7)
1108 // std::underlying_type became available by gcc 4.7.0
1110 template <class Tgt, class Src>
1111 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1112 to(const Src & value) {
1113 return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
1116 template <class Tgt, class Src>
1117 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1118 to(const Src & value) {
1119 return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
1124 template <class Tgt, class Src>
1125 typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
1126 to(const Src & value) {
1127 /* static */ if (Src(-1) < 0) {
1128 /* static */ if (sizeof(Src) <= sizeof(int)) {
1129 return to<Tgt>(static_cast<int>(value));
1131 return to<Tgt>(static_cast<long>(value));
1134 /* static */ if (sizeof(Src) <= sizeof(int)) {
1135 return to<Tgt>(static_cast<unsigned int>(value));
1137 return to<Tgt>(static_cast<unsigned long>(value));
1142 template <class Tgt, class Src>
1143 typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
1144 to(const Src & value) {
1145 /* static */ if (Tgt(-1) < 0) {
1146 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1147 return static_cast<Tgt>(to<int>(value));
1149 return static_cast<Tgt>(to<long>(value));
1152 /* static */ if (sizeof(Tgt) <= sizeof(int)) {
1153 return static_cast<Tgt>(to<unsigned int>(value));
1155 return static_cast<Tgt>(to<unsigned long>(value));
1160 #endif // gcc 4.7 onwards
1162 } // namespace folly
1164 // FOLLY_CONV_INTERNAL is defined by Conv.cpp. Keep the FOLLY_RANGE_CHECK
1165 // macro for use in Conv.cpp, but #undefine it everywhere else we are included,
1166 // to avoid defining this global macro name in other files that include Conv.h.
1167 #ifndef FOLLY_CONV_INTERNAL
1168 #undef FOLLY_RANGE_CHECK
1171 #endif /* FOLLY_BASE_CONV_H_ */