using _t = typename T::type;
/**
+ * type_t
+ *
+ * A type alias for the first template type argument. `type_t` is useful for
+ * controlling class-template and function-template partial specialization.
+ *
+ * Example:
+ *
+ * template <typename Value>
+ * class Container {
+ * public:
+ * template <typename... Args>
+ * Container(
+ * type_t<in_place_t, decltype(Value(std::declval<Args>()...))>,
+ * Args&&...);
+ * };
+ *
* void_t
*
* A type alias for `void`. `void_t` is useful for controling class-template
- * partial specialization.
+ * and function-template partial specialization.
*
* Example:
*
namespace traits_detail {
template <class...>
-struct void_t_ {
- using type = void;
+struct type_t_ {
+ template <class T>
+ using apply = T;
};
} // namespace traits_detail
+template <class T, class... Ts>
+using type_t = typename traits_detail::type_t_<Ts...>::template apply<T>;
template <class... Ts>
-using void_t = _t<traits_detail::void_t_<Ts...>>;
+using void_t = type_t<void, Ts...>;
/**
* IsRelocatable<T>::value describes the ability of moving around
template <class T>
struct has_value_type<T, folly::void_t<typename T::value_type>>
: std::true_type {};
+
+struct some_tag {};
+
+template <typename T>
+struct container {
+ template <class... Args>
+ container(
+ folly::type_t<some_tag, decltype(T(std::declval<Args>()...))>,
+ Args&&...) {}
+};
} // namespace
TEST(Traits, void_t) {
EXPECT_TRUE((::has_value_type<std::string>::value));
EXPECT_FALSE((::has_value_type<int>::value));
}
+
+TEST(Traits, type_t) {
+ EXPECT_TRUE((::std::is_same<folly::type_t<float>, float>::value));
+ EXPECT_TRUE((::std::is_same<folly::type_t<float, int>, float>::value));
+ EXPECT_TRUE((::std::is_same<folly::type_t<float, int, short>, float>::value));
+ EXPECT_TRUE(
+ (::std::is_same<folly::type_t<float, int, short, std::string>, float>::
+ value));
+ EXPECT_TRUE((
+ ::std::is_constructible<::container<std::string>, some_tag, std::string>::
+ value));
+ EXPECT_FALSE(
+ (::std::is_constructible<::container<std::string>, some_tag, float>::
+ value));
+}