allow fiber executor to override fiber options
[folly.git] / folly / Traits.h
index 58d507b17e2084543aa8c3132efc707b0cfaa6ac..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:
  *
@@ -174,9 +190,9 @@ using _t = typename T::type;
  */
 
 /**
- * There is a bug in gcc that causes it to ignore unused template parameter
- * arguments in template aliases and does not cause substitution failures.
- * This defect has been recorded here:
+ * There is a bug in libstdc++, libc++, and MSVC's STL that causes it to
+ * ignore unused template parameter arguments in template aliases and does not
+ * cause substitution failures. This defect has been recorded here:
  * http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558.
  *
  * This causes the implementation of std::void_t to be buggy, as it is likely
@@ -201,28 +217,19 @@ using _t = typename T::type;
  * The second foo() will be a redefinition because it conflicts with the first
  * one; void_t does not cause substitution failures - the template types are
  * just ignored.
- *
- * Till then only the non-buggy MSVC std::void_t can be used, and for the rest
- * folly::void_t will continue to be used because it does not use unnamed
- * template parameters for the top level implementation of void_t.
  */
-#if defined(_MSC_VER)
-
-/* using override */ using std::void_t;
-
-#else // defined(_MSC_VER)
 
 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...>>;
-
-#endif // defined(_MSC_VER)
+using void_t = type_t<void, Ts...>;
 
 /**
  * IsRelocatable<T>::value describes the ability of moving around
@@ -301,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; }
 };
@@ -322,7 +330,7 @@ struct IsEqualityComparable
           decltype(std::declval<T>() == std::declval<U>()),
           bool
       > {};
-}
+} // namespace traits_detail_IsEqualityComparable
 
 /* using override */ using traits_detail_IsEqualityComparable::
     IsEqualityComparable;
@@ -336,7 +344,7 @@ struct IsLessThanComparable
           decltype(std::declval<T>() < std::declval<U>()),
           bool
       > {};
-}
+} // namespace traits_detail_IsLessThanComparable
 
 /* using override */ using traits_detail_IsLessThanComparable::
     IsLessThanComparable;
@@ -364,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;