From: Christopher Dykes Date: Sun, 21 Aug 2016 17:02:29 +0000 (-0700) Subject: Fix folly::to<> under MSVC X-Git-Tag: v2016.08.22.00~2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1675b8959037b2e0c038866c2e5fb60e0ef2e305;p=folly.git 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 --- 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