folly: avoid compile warning/failure due to lvalue-to-rvalue conversion
[folly.git] / folly / Traits.h
index 45781cf5586701260dfa516ab119bf816cd60323..fb797f377bb72a7f860180c8ea511066c15ce0c5 100644 (file)
@@ -156,10 +156,26 @@ template <typename T>
 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:
  *
@@ -204,14 +220,16 @@ using _t = typename T::type;
  */
 
 namespace traits_detail {
-template <class...>
-struct void_t_ {
-  using type = void;
+template <class T, class...>
+struct type_t_ {
+  using type = T;
 };
 } // namespace traits_detail
 
+template <class T, class... Ts>
+using type_t = typename traits_detail::type_t_<T, Ts...>::type;
 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
@@ -290,11 +308,12 @@ struct is_trivially_copyable : std::is_trivial<T> {};
 template <class T>
 using is_trivially_copyable = std::is_trivially_copyable<T>;
 #endif
-}
+} // namespace traits_detail
 
 struct Ignore {
+  Ignore() = default;
   template <class T>
-  /* implicit */ Ignore(const T&) {}
+  constexpr /* implicit */ Ignore(const T&) {}
   template <class T>
   const Ignore& operator=(T const&) const { return *this; }
 };
@@ -311,7 +330,7 @@ struct IsEqualityComparable
           decltype(std::declval<T>() == std::declval<U>()),
           bool
       > {};
-}
+} // namespace traits_detail_IsEqualityComparable
 
 /* using override */ using traits_detail_IsEqualityComparable::
     IsEqualityComparable;
@@ -325,7 +344,7 @@ struct IsLessThanComparable
           decltype(std::declval<T>() < std::declval<U>()),
           bool
       > {};
-}
+} // namespace traits_detail_IsLessThanComparable
 
 /* using override */ using traits_detail_IsLessThanComparable::
     IsLessThanComparable;
@@ -353,7 +372,7 @@ struct IsNothrowSwappable
         noexcept(swap(std::declval<T&>(), std::declval<T&>()))
       > {};
 #endif
-}
+} // namespace traits_detail_IsNothrowSwappable
 
 /* using override */ using traits_detail_IsNothrowSwappable::IsNothrowSwappable;