From 1675b8959037b2e0c038866c2e5fb60e0ef2e305 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Sun, 21 Aug 2016 10:02:29 -0700 Subject: [PATCH] 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 --- folly/Conv.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/folly/Conv.h b/folly/Conv.h index 09f762bc..468d33cb 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -187,6 +187,33 @@ to(const Src& value) { 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 +auto getLastElement(Ts&&... ts) -> decltype( + std::get(std::forward_as_tuple(std::forward(ts)...))) { + return std::get( + std::forward_as_tuple(std::forward(ts)...)); +} + +inline void getLastElement() {} + +template +struct LastElementType : std::tuple_element> {}; + +template <> +struct LastElementType<0> { + using type = void; +}; + +template +struct LastElement + : std::decay::type> {}; +#else template struct LastElementImpl { static void call(Ignored...) {} @@ -210,6 +237,7 @@ template struct LastElement : std::decay::call(std::declval()...))> { }; +#endif } // namespace detail -- 2.34.1