Index: base/type_traits.h |
diff --git a/base/type_traits.h b/base/type_traits.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..07abb177240547d641837780aaa0d533d385c8b3 |
--- /dev/null |
+++ b/base/type_traits.h |
@@ -0,0 +1,68 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_TYPE_TRAITS_H_ |
+#define BASE_TYPE_TRAITS_H_ |
+ |
+#include <type_traits> |
+ |
+namespace base { |
+ |
+// C++14 --------------------------------------------------------------------- |
+ |
+template <bool condition, typename T = void> |
+using enable_if_t = typename std::enable_if<condition, T>::type; |
+ |
+template <bool condition, typename T, typename U> |
+using condtional_t = typename std::conditional<condition, T, U>::type; |
+ |
+// C++17 ---------------------------------------------------------------------- |
+ |
+// Detection idiom. We use constexpr function is_detected_c() instead of a |
+// variable template. |
+ |
+template <typename...> |
+using void_t = void; |
+ |
+struct nonesuch { |
+ nonesuch() = delete; |
+ ~nonesuch() = delete; |
+ nonesuch(nonesuch const&) = delete; |
+ void operator=(nonesuch const&) = delete; |
+}; |
+ |
+namespace internal { |
+ |
+template <typename Default, |
+ typename AlwaysVoid, |
+ template <typename...> class Op, |
+ typename... Args> |
+struct detector { |
+ using value_t = std::false_type; |
+ using type = Default; |
+}; |
+ |
+template <typename Default, template <typename...> class Op, typename... Args> |
+struct detector<Default, void_t<Op<Args...>>, Op, Args...> { |
+ using value_t = std::true_type; |
+ using type = Op<Args...>; |
+}; |
+ |
+} // namespace internal |
+ |
+template <template <class...> class Op, typename... Args> |
+using is_detected = |
+ typename internal::detector<nonesuch, void, Op, Args...>::value_t; |
+ |
+template <typename Default, template <typename...> class Op, typename... Args> |
+using detected_or = internal::detector<Default, void, Op, Args...>; |
+ |
+template <template <typename...> class Op, typename... Args> |
+constexpr bool is_detected_c() { |
+ return is_detected<Op, Args...>::value; |
+} |
+ |
+} // namespace base |
+ |
+#endif // BASE_TYPE_TRAITS_H_ |