From: Yedidya Feldblum <yfeldblum@fb.com> Date: Tue, 12 Dec 2017 04:19:06 +0000 (-0800) Subject: Assorted tweaks to folly/String.h X-Git-Tag: v2017.12.18.00~28 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c01c18b26eded07d11079a77d3df36a57fd4bf16;p=folly.git Assorted tweaks to folly/String.h Summary: [Folly] Assorted tweaks to `folly/String.h`. * Use `void_t` in the definition of `IsConvertible`. * Remove `AllConvertible`. Callers can use `StrictConjunction` instead. * Move the `static_assert`s from the header to the source file. Reviewed By: andrewjcg, ot Differential Revision: D6501515 fbshipit-source-id: 472ecf23bf7f06be211480b0aceea95f7e60dc21 --- diff --git a/folly/String-inl.h b/folly/String-inl.h index f6b5ba99..597897db 100644 --- a/folly/String-inl.h +++ b/folly/String-inl.h @@ -401,7 +401,8 @@ void splitTo(const Delim& delimiter, template <bool exact, class Delim, class... OutputTypes> typename std::enable_if< - AllConvertible<OutputTypes...>::value && sizeof...(OutputTypes) >= 1, + StrictConjunction<IsConvertible<OutputTypes>...>::value && + sizeof...(OutputTypes) >= 1, bool>::type split(const Delim& delimiter, StringPiece input, OutputTypes&... outputs) { return detail::splitFixed<exact>( diff --git a/folly/String.cpp b/folly/String.cpp index 097e5bbf..f4a92396 100644 --- a/folly/String.cpp +++ b/folly/String.cpp @@ -29,6 +29,12 @@ namespace folly { +static_assert(IsConvertible<float>::value, ""); +static_assert(IsConvertible<int>::value, ""); +static_assert(IsConvertible<bool>::value, ""); +static_assert(IsConvertible<int>::value, ""); +static_assert(!IsConvertible<std::vector<int>>::value, ""); + static inline bool is_oddspace(char c) { return c == '\n' || c == '\t' || c == '\r'; } diff --git a/folly/String.h b/folly/String.h index 750863b9..0251b987 100644 --- a/folly/String.h +++ b/folly/String.h @@ -34,6 +34,7 @@ #include <folly/Portability.h> #include <folly/Range.h> #include <folly/ScopeGuard.h> +#include <folly/Traits.h> // Compatibility function, to make sure toStdString(s) can be called // to convert a std::string or fbstring variable s into type std::string @@ -468,41 +469,22 @@ void splitTo(const Delim& delimiter, * Note that this will likely not work if the last field's target is of numeric * type, in which case folly::to<> will throw an exception. */ -template <class T, class Enable = void> -struct IsConvertible { - enum { value = false }; -}; +namespace detail { +template <typename Void, typename OutputType> +struct IsConvertible : std::false_type {}; -template <class T> +template <typename OutputType> struct IsConvertible< - T, - decltype(static_cast<void>( - parseTo(std::declval<folly::StringPiece>(), std::declval<T&>())))> { - enum { value = true }; -}; - -template <class... Types> -struct AllConvertible; - -template <class Head, class... Tail> -struct AllConvertible<Head, Tail...> { - enum { value = IsConvertible<Head>::value && AllConvertible<Tail...>::value }; -}; - -template <> -struct AllConvertible<> { - enum { value = true }; -}; - -static_assert(AllConvertible<float>::value, ""); -static_assert(AllConvertible<int>::value, ""); -static_assert(AllConvertible<bool>::value, ""); -static_assert(AllConvertible<int>::value, ""); -static_assert(!AllConvertible<std::vector<int>>::value, ""); + void_t<decltype(parseTo(StringPiece{}, std::declval<OutputType&>()))>, + OutputType> : std::true_type {}; +} // namespace detail +template <typename OutputType> +struct IsConvertible : detail::IsConvertible<void, OutputType> {}; template <bool exact = true, class Delim, class... OutputTypes> typename std::enable_if< - AllConvertible<OutputTypes...>::value && sizeof...(OutputTypes) >= 1, + StrictConjunction<IsConvertible<OutputTypes>...>::value && + sizeof...(OutputTypes) >= 1, bool>::type split(const Delim& delimiter, StringPiece input, OutputTypes&... outputs);