X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FConv.h;h=61e50e3733b316a4254c6bac094962efe2e80e93;hp=be0d3d0dafa994695cc64ac43943a0a3e60a064d;hb=b35b5a98a37b889bd6748d8cc3a7d357b9143e42;hpb=d4aacd244f21e76dce685365acc281a9015897c1 diff --git a/folly/Conv.h b/folly/Conv.h index be0d3d0d..61e50e37 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 Facebook, Inc. + * Copyright 2011-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,6 @@ #include #include -#include #include // V8 JavaScript implementation #include @@ -133,7 +132,7 @@ inline void enforceWhitespace(StringPiece sp) { throw makeConversionError(err, sp); } } -} +} // namespace detail /** * The identity conversion function. @@ -283,7 +282,7 @@ unsafeTelescope128(char * buffer, size_t room, unsigned __int128 x) { return p; } -} +} // namespace detail #endif /** @@ -303,7 +302,7 @@ inline uint32_t digits10(uint64_t v) { // 10^i, defined for i 0 through 19. // This is 20 * 8 == 160 bytes, which fits neatly into 5 cache lines // (assuming a cache line size of 64). - static const uint64_t powersOf10[20] FOLLY_ALIGNED(64) = { + alignas(64) static const uint64_t powersOf10[20] = { 1, 10, 100, @@ -327,7 +326,7 @@ inline uint32_t digits10(uint64_t v) { }; // "count leading zeroes" operation not valid; for 0; special case this. - if UNLIKELY (! v) { + if (UNLIKELY(!v)) { return 1; } @@ -342,16 +341,24 @@ inline uint32_t digits10(uint64_t v) { // return that log_10 lower bound, plus adjust if input >= 10^(that bound) // in case there's a small error and we misjudged length. - return minLength + (uint32_t) (UNLIKELY (v >= powersOf10[minLength])); + return minLength + uint32_t(v >= powersOf10[minLength]); #else uint32_t result = 1; - for (;;) { - if (LIKELY(v < 10)) return result; - if (LIKELY(v < 100)) return result + 1; - if (LIKELY(v < 1000)) return result + 2; - if (LIKELY(v < 10000)) return result + 3; + while (true) { + if (LIKELY(v < 10)) { + return result; + } + if (LIKELY(v < 100)) { + return result + 1; + } + if (LIKELY(v < 1000)) { + return result + 2; + } + if (LIKELY(v < 10000)) { + return result + 3; + } // Skip ahead by 4 orders of magnitude v /= 10000U; result += 4; @@ -408,6 +415,11 @@ estimateSpaceNeeded(T) { return 1; } +template +constexpr size_t estimateSpaceNeeded(const char (&)[N]) { + return N; +} + /** * Everything implicitly convertible to const char* gets appended. */ @@ -435,12 +447,18 @@ typename std::enable_if::value, size_t>:: return 0; } +template +typename std::enable_if::value, size_t>::type +estimateSpaceNeeded(Src const& value) { + return value.size(); +} + template typename std::enable_if< - (std::is_convertible::value || - IsSomeString::value) && - !std::is_convertible::value, - size_t>::type + std::is_convertible::value && + !IsSomeString::value && + !std::is_convertible::value, + size_t>::type estimateSpaceNeeded(Src value) { return folly::StringPiece(value).size(); } @@ -1415,8 +1433,9 @@ using ParseToResult = decltype(parseTo(StringPiece{}, std::declval())); struct CheckTrailingSpace { Expected operator()(StringPiece sp) const { auto e = enforceWhitespaceErr(sp); - if (UNLIKELY(e != ConversionCode::SUCCESS)) + if (UNLIKELY(e != ConversionCode::SUCCESS)) { return makeUnexpected(e); + } return unit; } }; @@ -1475,6 +1494,14 @@ tryTo(StringPiece src) { }); } +template +inline typename std::enable_if< + IsSomeString::value && !std::is_same::value, + Tgt>::type +to(Src const& src) { + return to(StringPiece(src.data(), src.size())); +} + template inline typename std::enable_if::value, Tgt>::type @@ -1526,7 +1553,8 @@ Tgt to(StringPiece* src) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + std::is_enum::value && !std::is_same::value && + !std::is_convertible::value, Expected>::type tryTo(const Src& value) { using I = typename std::underlying_type::type; @@ -1535,7 +1563,8 @@ tryTo(const Src& value) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + !std::is_convertible::valuea && + std::is_enum::value && !std::is_same::value, Expected>::type tryTo(const Src& value) { using I = typename std::underlying_type::type; @@ -1544,7 +1573,8 @@ tryTo(const Src& value) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + std::is_enum::value && !std::is_same::value && + !std::is_convertible::value, Tgt>::type to(const Src& value) { return to(static_cast::type>(value)); @@ -1552,8 +1582,10 @@ to(const Src& value) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, Tgt>::type -to(const Src & value) { + !std::is_convertible::value && std::is_enum::value && + !std::is_same::value, + Tgt>::type +to(const Src& value) { return static_cast(to::type>(value)); }