folly在Facebook内部广泛使用的一个c++库,是开源的,github地址:
https://github.com/facebook/folly

之前的boost库给我们带来了很多方便,比如智能指针之类的。
从c++11开始,对std标准库有了很大的补充,大大方便了c++程序员。

folly是Facebook open source library的缩写,其中用到了大量的C++11新标准,代码也是极其的规范,所以即使我们没必要使用folly这个库,我们也可以偶尔读一段它的源码,体验一下C++11带来的变化。

Conv.cpp
先贴一段代码,

/** Copyright 2016 Facebook, Inc.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**   http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
#include <folly/Conv.h>
#include <array>namespace folly {
namespace detail {namespace {/*** Finds the first non-digit in a string. The number of digits* searched depends on the precision of the Tgt integral. Assumes the* string starts with NO whitespace and NO sign.** The semantics of the routine is:*   for (;; ++b) {*     if (b >= e || !isdigit(*b)) return b;*   }**  Complete unrolling marks bottom-line (i.e. entire conversion)*  improvements of 20%.*/
inline const char* findFirstNonDigit(const char* b, const char* e) {for (; b < e; ++b) {auto const c = static_cast<unsigned>(*b) - '0';if (c >= 10) {break;}}return b;
}// Maximum value of number when represented as a string
template <class T>
struct MaxString {static const char* const value;
};template <> const char *const MaxString<uint8_t>::value = "255";
template <> const char *const MaxString<uint16_t>::value = "65535";
template <> const char *const MaxString<uint32_t>::value = "4294967295";
#if __SIZEOF_LONG__ == 4
template <> const char *const MaxString<unsigned long>::value ="4294967295";
#else
template <> const char *const MaxString<unsigned long>::value ="18446744073709551615";
#endif
static_assert(sizeof(unsigned long) >= 4,"Wrong value for MaxString<unsigned long>::value,"" please update.");
template <> const char *const MaxString<unsigned long long>::value ="18446744073709551615";
static_assert(sizeof(unsigned long long) >= 8,"Wrong value for MaxString<unsigned long long>::value"", please update.");#if FOLLY_HAVE_INT128_T
template <> const char *const MaxString<__uint128_t>::value ="340282366920938463463374607431768211455";
#endif/** Lookup tables that converts from a decimal character value to an integral* binary value, shifted by a decimal "shift" multiplier.* For all character values in the range '0'..'9', the table at those* index locations returns the actual decimal value shifted by the multiplier.* For all other values, the lookup table returns an invalid OOR value.*/
// Out-of-range flag value, larger than the largest value that can fit in
// four decimal bytes (9999), but four of these added up together should
// still not overflow uint16_t.
constexpr int32_t OOR = 10000;FOLLY_ALIGNED(16) constexpr uint16_t shift1[] = {OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  401, 2, 3, 4, 5, 6, 7, 8, 9, OOR, OOR,OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240OOR, OOR, OOR, OOR, OOR, OOR                       // 250
};FOLLY_ALIGNED(16) constexpr uint16_t shift10[] = {OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  4010, 20, 30, 40, 50, 60, 70, 80, 90, OOR, OOR,OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240OOR, OOR, OOR, OOR, OOR, OOR                       // 250
};FOLLY_ALIGNED(16) constexpr uint16_t shift100[] = {OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  40100, 200, 300, 400, 500, 600, 700, 800, 900, OOR, OOR,OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240OOR, OOR, OOR, OOR, OOR, OOR                       // 250
};FOLLY_ALIGNED(16) constexpr uint16_t shift1000[] = {OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 0-9OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  10OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  20OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  30OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, 0,         //  401000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, OOR, OOR,OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  60OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  70OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  80OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  //  90OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 100OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 110OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 120OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 130OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 140OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 150OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 160OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 170OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 180OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 190OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 200OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 210OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 220OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 230OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR, OOR,  // 240OOR, OOR, OOR, OOR, OOR, OOR                       // 250
};struct ErrorString {const char* string;bool quote;
};// Keep this in sync with ConversionCode in Conv.h
constexpr const std::array<ErrorString,static_cast<std::size_t>(ConversionCode::NUM_ERROR_CODES)>kErrorStrings{{{"Success", true},{"Empty input string", true},{"No digits found in input string", true},{"Integer overflow when parsing bool (must be 0 or 1)", true},{"Invalid value for bool", true},{"Non-digit character found", true},{"Invalid leading character", true},{"Overflow during conversion", true},{"Negative overflow during conversion", true},{"Unable to convert string to floating point value", true},{"Non-whitespace character found after end of conversion", true},{"Overflow during arithmetic conversion", false},{"Negative overflow during arithmetic conversion", false},{"Loss of precision during arithmetic conversion", false},}};// Check if ASCII is really ASCII
using IsAscii = std::integral_constant<bool, 'A' == 65 && 'Z' == 90 && 'a' == 97 && 'z' == 122>;// The code in this file that uses tolower() really only cares about
// 7-bit ASCII characters, so we can take a nice shortcut here.
inline char tolower_ascii(char in) {return IsAscii::value ? in | 0x20 : std::tolower(in);
}inline bool bool_str_cmp(const char** b, size_t len, const char* value) {// Can't use strncasecmp, since we want to ensure that the full value matchesconst char* p = *b;const char* e = *b + len;const char* v = value;while (*v != '\0') {if (p == e || tolower_ascii(*p) != *v) { // value is already lowercasereturn false;}++p;++v;}*b = p;return true;
}} // anonymous namespaceExpected<bool, ConversionCode> str_to_bool(StringPiece* src) noexcept {auto b = src->begin(), e = src->end();for (;; ++b) {if (b >= e) {return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);}if (!std::isspace(*b)) {break;}}bool result;size_t len = e - b;switch (*b) {case '0':case '1': {result = false;for (; b < e && isdigit(*b); ++b) {if (result || (*b != '0' && *b != '1')) {return makeUnexpected(ConversionCode::BOOL_OVERFLOW);}result = (*b == '1');}break;}case 'y':case 'Y':result = true;if (!bool_str_cmp(&b, len, "yes")) {++b;  // accept the single 'y' character}break;case 'n':case 'N':result = false;if (!bool_str_cmp(&b, len, "no")) {++b;}break;case 't':case 'T':result = true;if (!bool_str_cmp(&b, len, "true")) {++b;}break;case 'f':case 'F':result = false;if (!bool_str_cmp(&b, len, "false")) {++b;}break;case 'o':case 'O':if (bool_str_cmp(&b, len, "on")) {result = true;} else if (bool_str_cmp(&b, len, "off")) {result = false;} else {return makeUnexpected(ConversionCode::BOOL_INVALID_VALUE);}break;default:return makeUnexpected(ConversionCode::BOOL_INVALID_VALUE);}src->assign(b, e);return result;
}/*** StringPiece to double, with progress information. Alters the* StringPiece parameter to munch the already-parsed characters.*/
template <class Tgt>
Expected<Tgt, ConversionCode> str_to_floating(StringPiece* src) noexcept {using namespace double_conversion;static StringToDoubleConverterconv(StringToDoubleConverter::ALLOW_TRAILING_JUNK| StringToDoubleConverter::ALLOW_LEADING_SPACES,0.0,// return this for junk input stringstd::numeric_limits<double>::quiet_NaN(),nullptr, nullptr);if (src->empty()) {return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);}int length;auto result = conv.StringToDouble(src->data(),static_cast<int>(src->size()),&length); // processed char countif (!std::isnan(result)) {// If we get here with length = 0, the input string is empty.// If we get here with result = 0.0, it's either because the string// contained only whitespace, or because we had an actual zero value// (with potential trailing junk). If it was only whitespace, we// want to raise an error; length will point past the last character// that was processed, so we need to check if that character was// whitespace or not.if (length == 0 || (result == 0.0 && std::isspace((*src)[length - 1]))) {return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);}src->advance(length);return result;}auto* e = src->end();auto* b =std::find_if_not(src->begin(), e, [](char c) { return std::isspace(c); });// There must be non-whitespace, otherwise we would have caught this aboveassert(b < e);size_t size = e - b;bool negative = false;if (*b == '-') {negative = true;++b;--size;}result = 0.0;switch (tolower_ascii(*b)) {case 'i':if (size >= 3 && tolower_ascii(b[1]) == 'n' &&tolower_ascii(b[2]) == 'f') {if (size >= 8 && tolower_ascii(b[3]) == 'i' &&tolower_ascii(b[4]) == 'n' && tolower_ascii(b[5]) == 'i' &&tolower_ascii(b[6]) == 't' && tolower_ascii(b[7]) == 'y') {b += 8;} else {b += 3;}result = std::numeric_limits<Tgt>::infinity();}break;case 'n':if (size >= 3 && tolower_ascii(b[1]) == 'a' &&tolower_ascii(b[2]) == 'n') {b += 3;result = std::numeric_limits<Tgt>::quiet_NaN();}break;default:break;}if (result == 0.0) {// All bets are offreturn makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);}if (negative) {result = -result;}src->assign(b, e);return result;
}template Expected<float, ConversionCode> str_to_floating<float>(StringPiece* src) noexcept;
template Expected<double, ConversionCode> str_to_floating<double>(StringPiece* src) noexcept;/*** This class takes care of additional processing needed for signed values,* like leading sign character and overflow checks.*/
template <typename T, bool IsSigned = std::is_signed<T>::value>
class SignedValueHandler;template <typename T>
class SignedValueHandler<T, true> {public:ConversionCode init(const char*& b) {negative_ = false;if (!std::isdigit(*b)) {if (*b == '-') {negative_ = true;} else if (UNLIKELY(*b != '+')) {return ConversionCode::INVALID_LEADING_CHAR;}++b;}return ConversionCode::SUCCESS;}ConversionCode overflow() {return negative_ ? ConversionCode::NEGATIVE_OVERFLOW: ConversionCode::POSITIVE_OVERFLOW;}template <typename U>Expected<T, ConversionCode> finalize(U value) {T rv;if (negative_) {rv = -value;if (UNLIKELY(rv > 0)) {return makeUnexpected(ConversionCode::NEGATIVE_OVERFLOW);}} else {rv = value;if (UNLIKELY(rv < 0)) {return makeUnexpected(ConversionCode::POSITIVE_OVERFLOW);}}return rv;}private:bool negative_;
};// For unsigned types, we don't need any extra processing
template <typename T>
class SignedValueHandler<T, false> {public:ConversionCode init(const char*&) {return ConversionCode::SUCCESS;}ConversionCode overflow() {return ConversionCode::POSITIVE_OVERFLOW;}Expected<T, ConversionCode> finalize(T value) {return value;}
};/*** String represented as a pair of pointers to char to signed/unsigned* integrals. Assumes NO whitespace before or after, and also that the* string is composed entirely of digits (and an optional sign only for* signed types). String may be empty, in which case digits_to returns* an appropriate error.*/
template <class Tgt>
inline Expected<Tgt, ConversionCode> digits_to(const char* b,const char* const e) noexcept {using UT = typename std::make_unsigned<Tgt>::type;assert(b <= e);SignedValueHandler<Tgt> sgn;auto err = sgn.init(b);if (UNLIKELY(err != ConversionCode::SUCCESS)) {return makeUnexpected(err);}size_t size = e - b;/* Although the string is entirely made of digits, we still need to* check for overflow.*/if (size > std::numeric_limits<UT>::digits10) {// Leading zeros?if (b < e && *b == '0') {for (++b;; ++b) {if (b == e) {return Tgt(0); // just zeros, e.g. "0000"}if (*b != '0') {size = e - b;break;}}}if (size > std::numeric_limits<UT>::digits10 &&(size != std::numeric_limits<UT>::digits10 + 1 ||strncmp(b, MaxString<UT>::value, size) > 0)) {return makeUnexpected(sgn.overflow());}}// Here we know that the number won't overflow when// converted. Proceed without checks.UT result = 0;for (; e - b >= 4; b += 4) {result *= 10000;const int32_t r0 = shift1000[static_cast<size_t>(b[0])];const int32_t r1 = shift100[static_cast<size_t>(b[1])];const int32_t r2 = shift10[static_cast<size_t>(b[2])];const int32_t r3 = shift1[static_cast<size_t>(b[3])];const auto sum = r0 + r1 + r2 + r3;if (sum >= OOR) {goto outOfRange;}result += sum;}switch (e - b) {case 3: {const int32_t r0 = shift100[static_cast<size_t>(b[0])];const int32_t r1 = shift10[static_cast<size_t>(b[1])];const int32_t r2 = shift1[static_cast<size_t>(b[2])];const auto sum = r0 + r1 + r2;if (sum >= OOR) {goto outOfRange;}result = 1000 * result + sum;break;}case 2: {const int32_t r0 = shift10[static_cast<size_t>(b[0])];const int32_t r1 = shift1[static_cast<size_t>(b[1])];const auto sum = r0 + r1;if (sum >= OOR) {goto outOfRange;}result = 100 * result + sum;break;}case 1: {const int32_t sum = shift1[static_cast<size_t>(b[0])];if (sum >= OOR) {goto outOfRange;}result = 10 * result + sum;break;}default:assert(b == e);if (size == 0) {return makeUnexpected(ConversionCode::NO_DIGITS);}break;}return sgn.finalize(result);outOfRange:return makeUnexpected(ConversionCode::NON_DIGIT_CHAR);
}template Expected<char, ConversionCode> digits_to<char>(const char*,const char*) noexcept;
template Expected<signed char, ConversionCode> digits_to<signed char>(const char*,const char*) noexcept;
template Expected<unsigned char, ConversionCode> digits_to<unsigned char>(const char*,const char*) noexcept;template Expected<short, ConversionCode> digits_to<short>(const char*,const char*) noexcept;
template Expected<unsigned short, ConversionCode> digits_to<unsigned short>(const char*,const char*) noexcept;template Expected<int, ConversionCode> digits_to<int>(const char*,const char*) noexcept;
template Expected<unsigned int, ConversionCode> digits_to<unsigned int>(const char*,const char*) noexcept;template Expected<long, ConversionCode> digits_to<long>(const char*,const char*) noexcept;
template Expected<unsigned long, ConversionCode> digits_to<unsigned long>(const char*,const char*) noexcept;template Expected<long long, ConversionCode> digits_to<long long>(const char*,const char*) noexcept;
template Expected<unsigned long long, ConversionCode>
digits_to<unsigned long long>(const char*, const char*) noexcept;#if FOLLY_HAVE_INT128_T
template Expected<__int128, ConversionCode> digits_to<__int128>(const char*,const char*) noexcept;
template Expected<unsigned __int128, ConversionCode>
digits_to<unsigned __int128>(const char*, const char*) noexcept;
#endif/*** StringPiece to integrals, with progress information. Alters the* StringPiece parameter to munch the already-parsed characters.*/
template <class Tgt>
Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept {using UT = typename std::make_unsigned<Tgt>::type;auto b = src->data(), past = src->data() + src->size();for (;; ++b) {if (UNLIKELY(b >= past)) {return makeUnexpected(ConversionCode::EMPTY_INPUT_STRING);}if (!std::isspace(*b)) {break;}}SignedValueHandler<Tgt> sgn;auto err = sgn.init(b);if (UNLIKELY(err != ConversionCode::SUCCESS)) {return makeUnexpected(err);}if (std::is_signed<Tgt>::value && UNLIKELY(b >= past)) {return makeUnexpected(ConversionCode::NO_DIGITS);}if (UNLIKELY(!isdigit(*b))) {return makeUnexpected(ConversionCode::NON_DIGIT_CHAR);}auto m = findFirstNonDigit(b + 1, past);auto tmp = digits_to<UT>(b, m);if (UNLIKELY(!tmp.hasValue())) {return makeUnexpected(tmp.error() == ConversionCode::POSITIVE_OVERFLOW ? sgn.overflow(): tmp.error());}auto res = sgn.finalize(tmp.value());if (res.hasValue()) {src->advance(m - src->data());}return res;
}template Expected<char, ConversionCode> str_to_integral<char>(StringPiece* src) noexcept;
template Expected<signed char, ConversionCode> str_to_integral<signed char>(StringPiece* src) noexcept;
template Expected<unsigned char, ConversionCode> str_to_integral<unsigned char>(StringPiece* src) noexcept;template Expected<short, ConversionCode> str_to_integral<short>(StringPiece* src) noexcept;
template Expected<unsigned short, ConversionCode>
str_to_integral<unsigned short>(StringPiece* src) noexcept;template Expected<int, ConversionCode> str_to_integral<int>(StringPiece* src) noexcept;
template Expected<unsigned int, ConversionCode> str_to_integral<unsigned int>(StringPiece* src) noexcept;template Expected<long, ConversionCode> str_to_integral<long>(StringPiece* src) noexcept;
template Expected<unsigned long, ConversionCode> str_to_integral<unsigned long>(StringPiece* src) noexcept;template Expected<long long, ConversionCode> str_to_integral<long long>(StringPiece* src) noexcept;
template Expected<unsigned long long, ConversionCode>
str_to_integral<unsigned long long>(StringPiece* src) noexcept;#if FOLLY_HAVE_INT128_T
template Expected<__int128, ConversionCode> str_to_integral<__int128>(StringPiece* src) noexcept;
template Expected<unsigned __int128, ConversionCode>
str_to_integral<unsigned __int128>(StringPiece* src) noexcept;
#endif} // namespace detailConversionError makeConversionError(ConversionCode code, StringPiece input) {using namespace detail;static_assert(std::is_unsigned<std::underlying_type<ConversionCode>::type>::value,"ConversionCode should be unsigned");assert((std::size_t)code < kErrorStrings.size());const ErrorString& err = kErrorStrings[(std::size_t)code];if (code == ConversionCode::EMPTY_INPUT_STRING && input.empty()) {return {err.string, code};}std::string tmp(err.string);tmp.append(": ");if (err.quote) {tmp.append(1, '"');}if (input.size() > 0) {tmp.append(input.data(), input.size());}if (err.quote) {tmp.append(1, '"');}return {tmp, code};
}} // namespace folly

我们看看上面的代码中使用了哪些c++11特性:
auto
static_assert
nullptr
initializer list

当然还有很多,闲着的时候可以看看。

Facebook的c++开源库folly介绍相关推荐

  1. [转]Facebook的c++开源库folly介绍

    揭秘Facebook官方底层C++函数Folly Facebook近日公布了其官方底层C++函数Folly,Folly(该缩略语表示Facebook开源代码库)其实是C++11组件库,这些组件在设计时 ...

  2. 软件经验|GDAL空间数据开源库开发介绍

    GDAL(Geospatial Data Abstraction Library)是使用C/C++语言编写的用于读写空间数据的一套跨平台开源库.GDAL库可以读取.写入.转换.处理各种栅格数据格式,它 ...

  3. C++开源库详细介绍

    C++在"商业应用"方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又 ...

  4. ubuntu18 安装 Facebook 开源库 folly

    官网 1.安装依赖 folly 要求 gcc 5.1+ 版本,以及c++14 编译支持的boost版本 . folly 的测试代码需要 googletest  库,可以用以下命令下载安装: wget ...

  5. Go开源库Excelize介绍,电子Excel表格操作强大的库

    Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准. 项目作者是续 日,现任阿里巴巴软件工程师,曾就职百 ...

  6. 开源库BearSSL介绍及使用

    BearSSL是用C语言实现的SSL/TLS协议,它的源码可直接通过git clone https://www.bearssl.org/git/BearSSL 下载,它的license是MIT,最新版 ...

  7. 鲲鹏数据开源库python_google_translator介绍

    2019独角兽企业重金招聘Python工程师标准>>> 原文作者:西安鲲之鹏 原文链接:http://www.site-digger.com/html/articles/201308 ...

  8. 【OMNET++】开源库CoRE4INET介绍

    1.前言 OMNET++是一个可扩展的.模块化的.基于组件的C++仿真库和框架,主要用于构建网络模拟器.CoRE4INET是对INET框架的扩展,用于在OMNeT++仿真系统中基于事件的实时以太网仿真 ...

  9. 关于App的一些迷思以及一些动画效果开源库的推荐

    文/Robert_Chen(简书作者) 原文链接:http://www.jianshu.com/p/69449e6bdc14 著作权归作者所有,转载请联系作者获得授权,并标注"简书作者&qu ...

最新文章

  1. [LeetCode] 130. Surrounded Regions Java
  2. 7-26 单词长度 (C语言)
  3. [Spring MVC起步]我的第一个MVC
  4. 企业 SOA 设计(1)–ESB 设计
  5. [整理]ADB命令行学习笔记
  6. uvm_comps.svh
  7. DCASE 2013任务1(声学场景分类)参赛作品相关信息
  8. SEO 搜索引擎优化技巧
  9. android 5.1.1 sd卡权限,android - 适用于Android 5.1.1及更高版本的Cordova的外部存储路径(SD卡) - 堆栈内存溢出...
  10. WinDbg、Symbol Packages、SRVINSTW、DebugView下载地址
  11. 计算机专业学不学画法几何,给新手们学CAD的建议
  12. python爬虫二:网易博客的图片
  13. BZOJ4567 [SCOI2016]背单词
  14. MyBatis-plus从入门到精通(全)
  15. C盘数据丢失恢复详解和注意事项
  16. 量化投资 -- 技术篇(6)投资组合策略性能评价(上)
  17. 站上风口,文心一言任重道远
  18. linux系列(七):shell编程、shell概念、ssh协议概念、执行shell文件的三种方式
  19. 妹子尚且如此! 少年努力吧
  20. ahk2exe提示编译成功,但是没有文件输出,需要解决这个问题

热门文章

  1. nginx-http-1
  2. 时钟插件-CSS动画+jQuery
  3. 分享人民日报文章《自律的程度,决定了一个人的人生高度》
  4. 电子商务大赛历年获奖作品_武汉商贸职业学院师生在第九届海洋文化创意设计大赛中喜获佳绩! —湖北站—中国教育在线...
  5. 【数学建模笔记】2.整数规划
  6. 色彩立体模型软件的编写
  7. JFrame窗格、设置背景图片
  8. 一加6android p上手,一加6推送Android P系统,上手体验操作更流畅
  9. Word中常用快捷键Ctrl+字母的常快捷键
  10. js 查询字符串中字符数量 字符位数