#pragma once
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstddef>
#include <limits>
#include <optional>
#include <stdexcept>
#include <string>
#include <system_error>
#include <tuple>
#include <type_traits>
#include <utility>
#if __has_include(<charconv>)
#include <charconv>
#endif
#include <double-conversion/double-conversion.h>
#include <folly/CPortability.h>
#include <folly/Demangle.h>
#include <folly/Expected.h>
#include <folly/FBString.h>
#include <folly/Likely.h>
#include <folly/Portability.h>
#include <folly/Range.h>
#include <folly/Traits.h>
#include <folly/Unit.h>
#include <folly/Utility.h>
#include <folly/lang/Exception.h>
#include <folly/lang/Pretty.h>
#include <folly/lang/ToAscii.h>
#include <folly/portability/Math.h>
#if (defined(__cpp_lib_to_chars) && __cpp_lib_to_chars >= 201611L)
#define FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT …
#elif defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) && \
defined(_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT)
#define FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT …
#elif defined(__APPLE__) && \
((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 130300) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 160300) || \
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 160300) || \
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 90300))
#define FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT …
#else
#define FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT …
#endif
#if defined(FOLLY_CONV_DTOA_TO_CHARS) && FOLLY_CONV_DTOA_TO_CHARS == 1 && \
defined(FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT) && \
FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT == 1
#define FOLLY_CONV_USE_TO_CHARS …
#else
#define FOLLY_CONV_USE_TO_CHARS …
#endif
namespace folly {
enum class ConversionCode : unsigned char { … };
struct FOLLY_EXPORT ConversionErrorBase : std::range_error { … };
class FOLLY_EXPORT ConversionError : public ConversionErrorBase { … };
ConversionError makeConversionError(ConversionCode code, StringPiece input);
namespace detail {
inline ConversionCode enforceWhitespaceErr(StringPiece sp) { … }
inline void enforceWhitespace(StringPiece sp) { … }
}
template <class Tgt, class Src>
typename std::enable_if<
std::is_same<Tgt, typename std::decay<Src>::type>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(Src&& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_same<Tgt, typename std::decay<Src>::type>::value,
Tgt>::type
to(Src&& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
is_arithmetic_v<Src> && !std::is_same<Tgt, Src>::value &&
std::is_same<Tgt, bool>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
is_arithmetic_v<Src> && !std::is_same<Tgt, Src>::value &&
std::is_same<Tgt, bool>::value,
Tgt>::type
to(const Src& value) { … }
namespace detail {
LastElement;
#ifdef _MSC_VER
template <typename... Ts, typename R = LastElement<Ts...>>
const R& getLastElement(const Ts&... ts) {
return std::get<sizeof...(Ts) - 1>(std::forward_as_tuple(ts...));
}
inline void getLastElement() {}
#else
template <typename...>
struct LastElementImpl;
template <>
struct LastElementImpl<> { … };
LastElementImpl<Ign, Igns...>;
template <typename... Ts, typename R = LastElement<Ts...>>
const R& getLastElement(const Ts&... ts) { … }
#endif
}
#if FOLLY_HAVE_INT128_T
namespace detail {
template <typename IntegerType>
constexpr unsigned int digitsEnough() {
auto const digits10 = std::numeric_limits<IntegerType>::digits10;
return static_cast<unsigned int>(digits10) + 1;
}
inline size_t unsafeTelescope128(char* outb, char* oute, unsigned __int128 x) {
using Usrc = unsigned __int128;
constexpr static auto kBase = UINT64_C(10'000'000'000'000'000'000);
constexpr static size_t kBaseDigits = 19;
size_t p = 0;
const auto leading = [&](Usrc v) {
assert(v >> 64 == 0);
p = detail::to_ascii_with_route<10, to_ascii_alphabet_lower>(
outb, oute, static_cast<uint64_t>(v));
};
const auto append = [&](uint64_t v) {
assert(v < kBase);
assert(outb + p + kBaseDigits <= oute);
auto v64 = static_cast<uint64_t>(v);
detail::to_ascii_with_route<10, to_ascii_alphabet_lower>(
outb + p, kBaseDigits, v64);
p += kBaseDigits;
};
if (x >> 64 > 0) {
const auto rem = static_cast<uint64_t>(x % kBase);
x /= kBase;
if (x >> 64 > 0) {
const auto rem2 = static_cast<uint64_t>(x % kBase);
x /= kBase;
leading(x);
append(rem2);
append(rem);
return p;
}
leading(x);
append(rem);
return p;
}
leading(x);
return p;
}
}
#endif
template <class Tgt>
void toAppend(char value, Tgt* result) { … }
template <class T>
constexpr typename std::enable_if<std::is_same<T, char>::value, size_t>::type
estimateSpaceNeeded(T) { … }
template <size_t N>
constexpr size_t estimateSpaceNeeded(const char (&)[N]) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_convertible<Src, const char*>::value &&
IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<std::is_convertible<Src, const char*>::value, size_t>::
type
estimateSpaceNeeded(Src value) { … }
template <class Src>
typename std::enable_if<IsSomeString<Src>::value, size_t>::type
estimateSpaceNeeded(Src const& value) { … }
template <class Src>
typename std::enable_if<
std::is_convertible<Src, folly::StringPiece>::value &&
!IsSomeString<Src>::value &&
!std::is_convertible<Src, const char*>::value,
size_t>::type
estimateSpaceNeeded(Src value) { … }
template <>
inline size_t estimateSpaceNeeded(std::nullptr_t ) { … }
template <class Src>
typename std::enable_if<
std::is_pointer<Src>::value &&
IsSomeString<std::remove_pointer<Src>>::value,
size_t>::type
estimateSpaceNeeded(Src value) { … }
template <class Tgt, class Src>
typename std::enable_if<
IsSomeString<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(const Src& value, Tgt* result) { … }
template <class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
StringPiece value, Tgt* result) { … }
template <class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
const fbstring& value, Tgt* result) { … }
#if FOLLY_HAVE_INT128_T
template <class Tgt>
void toAppend(__int128 value, Tgt* result) {
typedef unsigned __int128 Usrc;
char buffer[detail::digitsEnough<unsigned __int128>() + 1];
const auto oute = buffer + sizeof(buffer);
size_t p;
if (value < 0) {
buffer[0] = '-';
p = 1 + detail::unsafeTelescope128(buffer + 1, oute, -Usrc(value));
} else {
p = detail::unsafeTelescope128(buffer, oute, value);
}
result->append(buffer, p);
}
template <class Tgt>
void toAppend(unsigned __int128 value, Tgt* result) {
char buffer[detail::digitsEnough<unsigned __int128>()];
size_t p = detail::unsafeTelescope128(buffer, buffer + sizeof(buffer), value);
result->append(buffer, p);
}
template <class T>
constexpr
typename std::enable_if<std::is_same<T, __int128>::value, size_t>::type
estimateSpaceNeeded(T) {
return detail::digitsEnough<__int128>();
}
template <class T>
constexpr typename std::
enable_if<std::is_same<T, unsigned __int128>::value, size_t>::type
estimateSpaceNeeded(T) {
return detail::digitsEnough<unsigned __int128>();
}
#endif
template <class Tgt, class Src>
typename std::enable_if<
is_integral_v<Src> && is_signed_v<Src> && IsSomeString<Tgt>::value &&
sizeof(Src) >= 4>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<
is_integral_v<Src> && is_signed_v<Src> && sizeof(Src) >= 4 &&
sizeof(Src) < 16,
size_t>::type
estimateSpaceNeeded(Src value) { … }
template <class Tgt, class Src>
typename std::enable_if<
is_integral_v<Src> && !is_signed_v<Src> && IsSomeString<Tgt>::value &&
sizeof(Src) >= 4>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<
is_integral_v<Src> && !is_signed_v<Src> && sizeof(Src) >= 4 &&
sizeof(Src) < 16,
size_t>::type
estimateSpaceNeeded(Src value) { … }
template <class Tgt, class Src>
typename std::enable_if<
is_integral_v<Src> && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<
is_integral_v<Src> && sizeof(Src) < 4 && !std::is_same<Src, char>::value,
size_t>::type
estimateSpaceNeeded(Src value) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<std::is_enum<Src>::value, size_t>::type
estimateSpaceNeeded(Src value) { … }
enum class DtoaMode { … };
enum class DtoaFlags { … };
constexpr DtoaFlags operator|(DtoaFlags a, DtoaFlags b) { … }
constexpr DtoaFlags operator&(DtoaFlags a, DtoaFlags b) { … }
namespace detail {
constexpr int kConvMaxDecimalInShortestLow = …;
constexpr double kConvMaxDecimalInShortestLowValue = …;
constexpr int kConvMaxDecimalInShortestHigh = …;
constexpr double kConvMaxDecimalInShortestHighValue = …;
constexpr int kBase10MaximalLength = …;
enum class FloatToStringImpl { … };
#if defined(FOLLY_CONV_USE_TO_CHARS) && FOLLY_CONV_USE_TO_CHARS == 1
constexpr FloatToStringImpl kConvFloatToStringImpl =
FloatToStringImpl::StdToChars;
constexpr int kConvMaxFixedDigitsAfterPoint = 100;
constexpr int kConvMaxPrecisionDigits = 120;
#else
constexpr FloatToStringImpl kConvFloatToStringImpl = …;
constexpr int kConvMaxFixedDigitsAfterPoint = …;
constexpr int kConvMaxPrecisionDigits = …;
constexpr double_conversion::DoubleToStringConverter::DtoaMode convert(
DtoaMode mode) { … }
constexpr double_conversion::DoubleToStringConverter::Flags convert(
DtoaFlags flags) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value && IsSomeString<Tgt>::value>::type
toAppendDoubleConversion(
Src value,
Tgt* result,
DtoaMode mode,
unsigned int numDigits,
DtoaFlags flags = DtoaFlags::NO_FLAGS) { … }
#endif
#if defined(FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT) && \
FOLLY_CONV_AVALIABILITY_TO_CHARS_FLOATING_POINT == 1
struct DtoaFlagsSet { … };
class ParsedDecimal { … };
std::pair<char*, char*> formatAsDoubleConversion(
bool valueIsZero,
DtoaMode mode,
unsigned int numDigits,
DtoaFlags flags,
char* resultBegin,
char* resultEnd,
char* bufferEnd);
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value && IsSomeString<Tgt>::value>::type
toAppendStdToChars(
Src value,
Tgt* result,
DtoaMode mode,
unsigned int numDigits,
DtoaFlags flags = DtoaFlags::NO_FLAGS) { … }
#endif
}
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(
Src value,
Tgt* result,
DtoaMode mode,
unsigned int numDigits,
DtoaFlags flags = DtoaFlags::NO_FLAGS) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt* result) { … }
template <class Src>
typename std::enable_if<std::is_floating_point<Src>::value, size_t>::type
estimateSpaceNeeded(Src value) { … }
template <class Src>
constexpr typename std::enable_if<
!std::is_fundamental<Src>::value &&
#if FOLLY_HAVE_INT128_T
!std::is_same<__int128, Src>::value &&
!std::is_same<unsigned __int128, Src>::value &&
#endif
!IsSomeString<Src>::value &&
!std::is_convertible<Src, const char*>::value &&
!std::is_convertible<Src, StringPiece>::value &&
!std::is_enum<Src>::value,
size_t>::type
estimateSpaceNeeded(const Src&) { … }
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace detail {
FOLLY_ERASE constexpr size_t estimateSpaceToReserveOne(std::false_type, void*) { … }
template <typename T>
FOLLY_ERASE constexpr size_t estimateSpaceToReserveOne(
std::true_type, const T& v) { … }
template <typename>
struct EstimateSpaceToReserveAll;
EstimateSpaceToReserveAll<std::index_sequence<I...>>;
template <class O>
void reserveInTarget(const O& o) { … }
template <class T, class O>
void reserveInTarget(const T& v, const O& o) { … }
template <class T0, class T1, class... Ts>
void reserveInTarget(const T0& v0, const T1& v1, const Ts&... vs) { … }
template <class Delimiter, class... Ts>
void reserveInTargetDelim(const Delimiter& d, const Ts&... vs) { … }
template <class T>
FOLLY_ERASE constexpr int toAppendStrImplOne(
std::false_type, const T& v, void*) { … }
template <class T, class Tgt>
FOLLY_ERASE int toAppendStrImplOne(std::true_type, const T& v, Tgt result) { … }
template <typename>
struct ToAppendStrImplAll;
ToAppendStrImplAll<std::index_sequence<I...>>;
template <class Delimiter, class T>
FOLLY_ERASE constexpr int toAppendDelimStrImplOne(
index_constant<0>, const Delimiter& d, const T& v, void*) { … }
template <class Delimiter, class T, class Tgt>
FOLLY_ERASE int toAppendDelimStrImplOne(
index_constant<1>, const Delimiter& d, const T& v, Tgt result) { … }
template <class Delimiter, class T, class Tgt>
FOLLY_ERASE int toAppendDelimStrImplOne(
index_constant<2>, const Delimiter& d, const T& v, Tgt result) { … }
template <typename>
struct ToAppendDelimStrImplAll;
ToAppendDelimStrImplAll<std::index_sequence<I...>>;
template <
class Delimiter,
class T,
class... Ts,
std::enable_if_t<
sizeof...(Ts) >= 2 &&
IsSomeString<typename std::remove_pointer<
detail::LastElement<Ts...>>::type>::value,
int> = 0>
void toAppendDelimStrImpl(const Delimiter& delim, const T& v, const Ts&... vs) { … }
}
#endif
template <
class... Ts,
std::enable_if_t<
sizeof...(Ts) >= 3 &&
IsSomeString<typename std::remove_pointer<
detail::LastElement<Ts...>>::type>::value,
int> = 0>
void toAppend(const Ts&... vs) { … }
template <
class... Ts,
std::enable_if_t<
IsSomeString<typename std::remove_pointer<
detail::LastElement<Ts...>>::type>::value,
int> = 0>
void toAppendFit(const Ts&... vs) { … }
template <class Ts>
void toAppendFit(const Ts&) { … }
template <class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
Tgt* ) { … }
template <class Delimiter, class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
const Delimiter& , Tgt* ) { … }
template <class Delimiter, class T, class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppendDelim(
const Delimiter& , const T& v, Tgt* tgt) { … }
template <
class Delimiter,
class... Ts,
std::enable_if_t<
sizeof...(Ts) >= 3 &&
IsSomeString<typename std::remove_pointer<
detail::LastElement<Ts...>>::type>::value,
int> = 0>
void toAppendDelim(const Delimiter& delim, const Ts&... vs) { … }
template <
class Delimiter,
class... Ts,
std::enable_if_t<
IsSomeString<typename std::remove_pointer<
detail::LastElement<Ts...>>::type>::value,
int> = 0>
void toAppendDelimFit(const Delimiter& delim, const Ts&... vs) { … }
template <class De, class Ts>
void toAppendDelimFit(const De&, const Ts&) { … }
template <
class Tgt,
class... Ts,
std::enable_if_t<
IsSomeString<Tgt>::value &&
(sizeof...(Ts) != 1 ||
!std::is_same<Tgt, detail::LastElement<void, Ts...>>::value),
int> = 0>
Tgt to(const Ts&... vs) { … }
template <class Tgt, class Src>
typename std::enable_if<
IsSomeString<Tgt>::value && std::is_floating_point<Src>::value,
Tgt>::type
to(Src value) { … }
template <class Tgt, class Delim, class Src>
typename std::enable_if<
IsSomeString<Tgt>::value &&
std::is_same<Tgt, typename std::decay<Src>::type>::value,
Tgt>::type
toDelim(const Delim& , Src&& value) { … }
template <
class Tgt,
class Delim,
class... Ts,
std::enable_if_t<
IsSomeString<Tgt>::value &&
(sizeof...(Ts) != 1 ||
!std::is_same<Tgt, detail::LastElement<void, Ts...>>::value),
int> = 0>
Tgt toDelim(const Delim& delim, const Ts&... vs) { … }
namespace detail {
Expected<bool, ConversionCode> str_to_bool(StringPiece* src) noexcept;
template <typename T>
Expected<T, ConversionCode> str_to_floating(StringPiece* src) noexcept;
extern template Expected<float, ConversionCode> str_to_floating<float>(
StringPiece* src) noexcept;
extern template Expected<double, ConversionCode> str_to_floating<double>(
StringPiece* src) noexcept;
template <class Tgt>
Expected<Tgt, ConversionCode> digits_to(const char* b, const char* e) noexcept;
extern template Expected<char, ConversionCode> digits_to<char>(
const char*, const char*) noexcept;
extern template Expected<signed char, ConversionCode> digits_to<signed char>(
const char*, const char*) noexcept;
extern template Expected<unsigned char, ConversionCode>
digits_to<unsigned char>(const char*, const char*) noexcept;
extern template Expected<short, ConversionCode> digits_to<short>(
const char*, const char*) noexcept;
extern template Expected<unsigned short, ConversionCode>
digits_to<unsigned short>(const char*, const char*) noexcept;
extern template Expected<int, ConversionCode> digits_to<int>(
const char*, const char*) noexcept;
extern template Expected<unsigned int, ConversionCode> digits_to<unsigned int>(
const char*, const char*) noexcept;
extern template Expected<long, ConversionCode> digits_to<long>(
const char*, const char*) noexcept;
extern template Expected<unsigned long, ConversionCode>
digits_to<unsigned long>(const char*, const char*) noexcept;
extern template Expected<long long, ConversionCode> digits_to<long long>(
const char*, const char*) noexcept;
extern template Expected<unsigned long long, ConversionCode>
digits_to<unsigned long long>(const char*, const char*) noexcept;
#if FOLLY_HAVE_INT128_T
extern template Expected<__int128, ConversionCode> digits_to<__int128>(
const char*, const char*) noexcept;
extern template Expected<unsigned __int128, ConversionCode>
digits_to<unsigned __int128>(const char*, const char*) noexcept;
#endif
template <class T>
Expected<T, ConversionCode> str_to_integral(StringPiece* src) noexcept;
extern template Expected<char, ConversionCode> str_to_integral<char>(
StringPiece* src) noexcept;
extern template Expected<signed char, ConversionCode>
str_to_integral<signed char>(StringPiece* src) noexcept;
extern template Expected<unsigned char, ConversionCode>
str_to_integral<unsigned char>(StringPiece* src) noexcept;
extern template Expected<short, ConversionCode> str_to_integral<short>(
StringPiece* src) noexcept;
extern template Expected<unsigned short, ConversionCode>
str_to_integral<unsigned short>(StringPiece* src) noexcept;
extern template Expected<int, ConversionCode> str_to_integral<int>(
StringPiece* src) noexcept;
extern template Expected<unsigned int, ConversionCode>
str_to_integral<unsigned int>(StringPiece* src) noexcept;
extern template Expected<long, ConversionCode> str_to_integral<long>(
StringPiece* src) noexcept;
extern template Expected<unsigned long, ConversionCode>
str_to_integral<unsigned long>(StringPiece* src) noexcept;
extern template Expected<long long, ConversionCode> str_to_integral<long long>(
StringPiece* src) noexcept;
extern template Expected<unsigned long long, ConversionCode>
str_to_integral<unsigned long long>(StringPiece* src) noexcept;
#if FOLLY_HAVE_INT128_T
extern template Expected<__int128, ConversionCode> str_to_integral<__int128>(
StringPiece* src) noexcept;
extern template Expected<unsigned __int128, ConversionCode>
str_to_integral<unsigned __int128>(StringPiece* src) noexcept;
#endif
template <typename T>
typename std::
enable_if<std::is_same<T, bool>::value, Expected<T, ConversionCode>>::type
convertTo(StringPiece* src) noexcept { … }
template <typename T>
typename std::enable_if<
std::is_floating_point<T>::value,
Expected<T, ConversionCode>>::type
convertTo(StringPiece* src) noexcept { … }
template <typename T>
typename std::enable_if<
is_integral_v<T> && !std::is_same<T, bool>::value,
Expected<T, ConversionCode>>::type
convertTo(StringPiece* src) noexcept { … }
}
template <typename Tgt>
typename std::enable_if<
is_integral_v<Tgt> && !std::is_same<Tgt, bool>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const char* b, const char* e) { … }
template <typename Tgt>
typename std::enable_if<
is_integral_v<Tgt> && !std::is_same<Tgt, bool>::value,
Tgt>::type
to(const char* b, const char* e) { … }
template <typename Tgt>
FOLLY_NODISCARD inline typename std::enable_if<
is_arithmetic_v<Tgt>,
Expected<StringPiece, ConversionCode>>::type
parseTo(StringPiece src, Tgt& out) { … }
namespace detail {
template <class Tgt>
typename std::enable_if<
!std::is_same<Tgt, bool>::value &&
(is_integral_v<Tgt> || std::is_floating_point<Tgt>::value),
Expected<Tgt, ConversionCode>>::type
convertTo(const bool& value) noexcept { … }
template <class Tgt, class Src>
typename std::enable_if<
is_integral_v<Src> && !std::is_same<Tgt, Src>::value &&
!std::is_same<Tgt, bool>::value && is_integral_v<Tgt>,
Expected<Tgt, ConversionCode>>::type
convertTo(const Src& value) noexcept { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value &&
!std::is_same<Tgt, Src>::value,
Expected<Tgt, ConversionCode>>::type
convertTo(const Src& value) noexcept { … }
template <typename Tgt, typename Src>
inline typename std::enable_if<
std::is_floating_point<Src>::value && is_integral_v<Tgt> &&
!std::is_same<Tgt, bool>::value,
bool>::type
checkConversion(const Src& value) { … }
template <typename Tgt, typename Src>
constexpr typename std::enable_if<
is_integral_v<Src> && std::is_floating_point<Tgt>::value,
bool>::type
checkConversion(const Src&) { … }
template <typename Tgt, typename Src>
constexpr typename std::enable_if<
std::is_floating_point<Src>::value && std::is_same<Tgt, bool>::value,
bool>::type
checkConversion(const Src&) { … }
template <typename Tgt, typename Src>
typename std::enable_if<
(is_integral_v<Src> && std::is_floating_point<Tgt>::value) ||
(std::is_floating_point<Src>::value && is_integral_v<Tgt>),
Expected<Tgt, ConversionCode>>::type
convertTo(const Src& value) noexcept { … }
template <typename Tgt, typename Src>
inline std::string errorValue(const Src& value) { … }
IsArithToArith;
}
template <typename Tgt, typename Src>
typename std::enable_if<
detail::IsArithToArith<Tgt, Src>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) noexcept { … }
template <typename Tgt, typename Src>
typename std::enable_if<detail::IsArithToArith<Tgt, Src>::value, Tgt>::type to(
const Src& value) { … }
template <class T>
FOLLY_NODISCARD typename std::enable_if<
std::is_enum<T>::value,
Expected<StringPiece, ConversionCode>>::type
parseTo(StringPiece in, T& out) noexcept { … }
FOLLY_NODISCARD
inline Expected<StringPiece, ConversionCode> parseTo(
StringPiece in, StringPiece& out) noexcept { … }
namespace detail {
template <class Str>
FOLLY_ERASE Expected<StringPiece, ConversionCode> parseToStr(
StringPiece in, Str& out) { … }
}
FOLLY_NODISCARD
inline Expected<StringPiece, ConversionCode> parseTo(
StringPiece in, std::string& out) { … }
FOLLY_NODISCARD
inline Expected<StringPiece, ConversionCode> parseTo(
StringPiece in, std::string_view& out) { … }
FOLLY_NODISCARD
inline Expected<StringPiece, ConversionCode> parseTo(
StringPiece in, fbstring& out) { … }
template <class Str>
FOLLY_NODISCARD inline typename std::enable_if<
IsSomeString<Str>::value,
Expected<StringPiece, ConversionCode>>::type
parseTo(StringPiece in, Str& out) { … }
namespace detail {
ParseToResult;
struct CheckTrailingSpace { … };
template <class Error>
struct ReturnUnit { … };
template <class Tgt>
inline typename std::enable_if<
std::is_void<ParseToResult<Tgt>>::value,
Expected<StringPiece, ConversionCode>>::type
parseToWrap(StringPiece sp, Tgt& out) { … }
template <class Tgt>
inline typename std::enable_if<
!std::is_void<ParseToResult<Tgt>>::value,
ParseToResult<Tgt>>::type
parseToWrap(StringPiece sp, Tgt& out) { … }
ParseToError;
}
template <class Tgt>
inline typename std::enable_if<
!std::is_same<StringPiece, Tgt>::value,
Expected<Tgt, detail::ParseToError<Tgt>>>::type
tryTo(StringPiece src) { … }
template <class Tgt, class Src>
inline typename std::enable_if<
IsSomeString<Src>::value && !std::is_same<StringPiece, Tgt>::value,
Tgt>::type
to(Src const& src) { … }
template <class Tgt>
inline
typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
to(StringPiece src) { … }
template <class Tgt>
Expected<Tgt, detail::ParseToError<Tgt>> tryTo(StringPiece* src) { … }
template <class Tgt>
Tgt to(StringPiece* src) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value &&
!std::is_convertible<Tgt, StringPiece>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
!std::is_convertible<Src, StringPiece>::value && std::is_enum<Tgt>::value &&
!std::is_same<Src, Tgt>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value &&
!std::is_convertible<Tgt, StringPiece>::value,
Tgt>::type
to(const Src& value) { … }
template <class Tgt, class Src>
typename std::enable_if<
!std::is_convertible<Src, StringPiece>::value && std::is_enum<Tgt>::value &&
!std::is_same<Src, Tgt>::value,
Tgt>::type
to(const Src& value) { … }
}