From e39748150f912c52987d65a6636f75506c873e35 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Fri, 6 Jan 2017 18:32:01 -0800 Subject: [PATCH] add folly::void_t like C++17's std::void_t Summary: C++17 is adding std::void_t. It's handy for controlling class template partial specialization. Folly should have it too. See http://en.cppreference.com/w/cpp/types/void_t Reviewed By: yfeldblum Differential Revision: D4387302 fbshipit-source-id: 85f955f3d8cfacbd6c9e61fb3f5cf53c056459bb --- folly/Traits.h | 35 +++++++++++++++++++++++++++++++++++ folly/test/TraitsTest.cpp | 20 ++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/folly/Traits.h b/folly/Traits.h index 81f52d0a..88d46a58 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -149,6 +149,41 @@ namespace folly { template using _t = typename T::type; +/** + * void_t + * + * A type alias for `void`. `void_t` is useful for controling class-template + * partial specialization. + * + * Example: + * + * // has_value_type::value is true if T has a nested type `value_type` + * template + * struct has_value_type + * : std::false_type {}; + * + * template + * struct has_value_type> + * : std::true_type {}; + */ +#if defined(__cpp_lib_void_t) || defined(_MSC_VER) + +/* using override */ using std::void_t; + +#else // defined(__cpp_lib_void_t) || defined(_MSC_VER) + +namespace traits_detail { +template +struct void_t_ { + using type = void; +}; +} // namespace traits_detail + +template +using void_t = _t>; + +#endif // defined(__cpp_lib_void_t) || defined(_MSC_VER) + /** * IsRelocatable::value describes the ability of moving around * memory a value of type T by using memcpy (as opposed to the diff --git a/folly/test/TraitsTest.cpp b/folly/test/TraitsTest.cpp index d4926514..fa6b6637 100644 --- a/folly/test/TraitsTest.cpp +++ b/folly/test/TraitsTest.cpp @@ -216,3 +216,23 @@ TEST(Traits, actuallyRelocatable) { testIsRelocatable>(5, 'g'); } + +namespace { +// has_value_type::value is true if T has a nested type `value_type` +template +struct has_value_type : std::false_type {}; + +template +struct has_value_type> + : std::true_type {}; +} + +TEST(Traits, void_t) { + EXPECT_TRUE((::std::is_same, void>::value)); + EXPECT_TRUE((::std::is_same, void>::value)); + EXPECT_TRUE((::std::is_same, void>::value)); + EXPECT_TRUE( + (::std::is_same, void>::value)); + EXPECT_TRUE((::has_value_type::value)); + EXPECT_FALSE((::has_value_type::value)); +} -- 2.34.1