throw makeConversionError(err, sp);
}
}
-}
+} // namespace detail
/**
* The identity conversion function.
return p;
}
-}
+} // namespace detail
#endif
/**
*result += value;
}
-template<class T>
+template <class T>
constexpr typename std::enable_if<
std::is_same<T, char>::value,
size_t>::type
return 1;
}
+template <size_t N>
+constexpr size_t estimateSpaceNeeded(const char (&)[N]) {
+ return N;
+}
+
/**
* Everything implicitly convertible to const char* gets appended.
*/
return 0;
}
-template<class Src>
+template <class Src>
+typename std::enable_if<IsSomeString<Src>::value, size_t>::type
+estimateSpaceNeeded(Src const& value) {
+ return value.size();
+}
+
+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
+ std::is_convertible<Src, folly::StringPiece>::value &&
+ !IsSomeString<Src>::value &&
+ !std::is_convertible<Src, const char*>::value,
+ size_t>::type
estimateSpaceNeeded(Src value) {
return folly::StringPiece(value).size();
}
return 0;
}
-template<class Src>
+template <class Src>
typename std::enable_if<
std::is_pointer<Src>::value &&
IsSomeString<std::remove_pointer<Src>>::value,
result->append(buffer + p, buffer + sizeof(buffer));
}
-template<class T>
+template <class T>
constexpr typename std::enable_if<
std::is_same<T, __int128>::value,
size_t>::type
return detail::digitsEnough<__int128>();
}
-template<class T>
+template <class T>
constexpr typename std::enable_if<
std::is_same<T, unsigned __int128>::value,
size_t>::type
namespace detail {
constexpr int kConvMaxDecimalInShortestLow = -6;
constexpr int kConvMaxDecimalInShortestHigh = 21;
-} // folly::detail
+} // namespace detail
/** Wrapper around DoubleToStringConverter **/
template <class Tgt, class Src>
* for estimateSpaceNeed for your type, so that we allocate
* as much as you need instead of the default
*/
-template<class Src>
+template <class Src>
struct HasLengthEstimator : std::false_type {};
template <class Src>
return estimateSpaceToReserve(sofar + estimateSpaceNeeded(v), vs...);
}
-template<class...Ts>
+template <class... Ts>
void reserveInTarget(const Ts&...vs) {
getLastElement(vs...)->reserve(estimateSpaceToReserve(0, vs...));
}
-template<class Delimiter, class...Ts>
+template <class Delimiter, class... Ts>
void reserveInTargetDelim(const Delimiter& d, const Ts&...vs) {
static_assert(sizeof...(vs) >= 2, "Needs at least 2 args");
size_t fordelim = (sizeof...(vs) - 2) *
toAppend(delim, detail::getLastElement(vs...));
toAppendDelimStrImpl(delim, vs...);
}
-} // folly::detail
-
+} // namespace detail
/**
* Variadic conversion to string. Appends each element in turn.
* toDelim<SomeString>(SomeString str) returns itself.
*/
template <class Tgt, class Delim, class Src>
-typename std::enable_if<IsSomeString<Tgt>::value &&
- std::is_same<Tgt, Src>::value,
- Tgt>::type
-toDelim(const Delim& /* delim */, const Src& value) {
- return value;
+typename std::enable_if<
+ IsSomeString<Tgt>::value &&
+ std::is_same<Tgt, typename std::decay<Src>::type>::value,
+ Tgt>::type
+toDelim(const Delim& /* delim */, Src&& value) {
+ return std::forward<Src>(value);
}
/**
struct CheckTrailingSpace {
Expected<Unit, ConversionCode> operator()(StringPiece sp) const {
auto e = enforceWhitespaceErr(sp);
- if (UNLIKELY(e != ConversionCode::SUCCESS))
+ if (UNLIKELY(e != ConversionCode::SUCCESS)) {
return makeUnexpected(e);
+ }
return unit;
}
};
});
}
+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) {
+ return to<Tgt>(StringPiece(src.data(), src.size()));
+}
+
template <class Tgt>
inline
typename std::enable_if<!std::is_same<StringPiece, Tgt>::value, Tgt>::type
template <class Tgt, class Src>
typename std::enable_if<
- std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value,
+ 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) {
using I = typename std::underlying_type<Src>::type;
template <class Tgt, class Src>
typename std::enable_if<
- std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value,
+ !std::is_convertible<Src, StringPiece>::valuea &&
+ std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value,
Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) {
using I = typename std::underlying_type<Tgt>::type;
template <class Tgt, class Src>
typename std::enable_if<
- std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value,
+ std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value &&
+ !std::is_convertible<Tgt, StringPiece>::value,
Tgt>::type
to(const Src& value) {
return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
template <class Tgt, class Src>
typename std::enable_if<
- std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
-to(const Src & value) {
+ !std::is_convertible<Src, StringPiece>::value && std::is_enum<Tgt>::value &&
+ !std::is_same<Src, Tgt>::value,
+ Tgt>::type
+to(const Src& value) {
return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
}