Commit 1675b895 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot 0

Fix folly::to<> under MSVC

Summary: MSVC didn't like the conversion to using `Expected`, and, after `Expected` was fixed to work under MSVC, conv still needs more changes. Specifically MSVC doesn't understand the single-instantiation form of getting the last element, so we have to switch to a tuple-backed version instead, which requires more template instantions, but produces the same performance at runtime.

Reviewed By: ericniebler

Differential Revision: D3744063

fbshipit-source-id: affcab1574c721d8b9529784d7ca2a46233d9935
parent 10ed79f7
...@@ -187,6 +187,33 @@ to(const Src& value) { ...@@ -187,6 +187,33 @@ to(const Src& value) {
namespace detail { namespace detail {
#ifdef _MSC_VER
// MSVC can't quite figure out the LastElementImpl::call() stuff
// in the base implementation, so we have to use tuples instead,
// which result in significantly more templates being compiled,
// though the runtime performance is the same.
template <typename... Ts>
auto getLastElement(Ts&&... ts) -> decltype(
std::get<sizeof...(Ts)-1>(std::forward_as_tuple(std::forward<Ts>(ts)...))) {
return std::get<sizeof...(Ts)-1>(
std::forward_as_tuple(std::forward<Ts>(ts)...));
}
inline void getLastElement() {}
template <size_t size, typename... Ts>
struct LastElementType : std::tuple_element<size - 1, std::tuple<Ts...>> {};
template <>
struct LastElementType<0> {
using type = void;
};
template <class... Ts>
struct LastElement
: std::decay<typename LastElementType<sizeof...(Ts), Ts...>::type> {};
#else
template <typename... Ts> template <typename... Ts>
struct LastElementImpl { struct LastElementImpl {
static void call(Ignored<Ts>...) {} static void call(Ignored<Ts>...) {}
...@@ -210,6 +237,7 @@ template <class... Ts> ...@@ -210,6 +237,7 @@ template <class... Ts>
struct LastElement : std::decay<decltype( struct LastElement : std::decay<decltype(
LastElementImpl<Ts...>::call(std::declval<Ts>()...))> { LastElementImpl<Ts...>::call(std::declval<Ts>()...))> {
}; };
#endif
} // namespace detail } // namespace detail
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment