Index: components/scheduler/promises/template_helpers.h |
diff --git a/components/scheduler/promises/template_helpers.h b/components/scheduler/promises/template_helpers.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0d34fd80fed6fb4a9a942b8df902497d03a693d2 |
--- /dev/null |
+++ b/components/scheduler/promises/template_helpers.h |
@@ -0,0 +1,101 @@ |
+// Copyright 2016 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 COMPONENTS_SCHEDULER_PROMISES_TEMPLATE_HELPERS_H_ |
+#define COMPONENTS_SCHEDULER_PROMISES_TEMPLATE_HELPERS_H_ |
+ |
+#include <type_traits> |
+ |
+namespace promise { |
+namespace internal { |
+class PromiseBase; |
+ |
+template <typename R> |
+class Promise; |
+ |
+template <typename T, typename ReturnType> |
+using enable_if_void_t = |
+ typename std::enable_if<std::is_void<T>::value, ReturnType>::type; |
+ |
+template <typename T, typename ReturnType> |
+using enable_if_not_void_t = |
+ typename std::enable_if<!std::is_void<T>::value, ReturnType>::type; |
+ |
+// A paramater pack introspection template that can determine if the pack |
+// contains |TypeBeingChecked|. |
+template <typename TypeBeingChecked, typename Head, typename... Tail> |
+struct check_any_have_type { |
+ enum { |
+ value = std::is_same<TypeBeingChecked, Head>::value || |
+ check_any_have_type<TypeBeingChecked, Tail...>::value |
+ }; |
+}; |
+ |
+template <typename TypeBeingChecked, typename Head> |
+struct check_any_have_type<TypeBeingChecked, Head> { |
+ enum { value = std::is_same<TypeBeingChecked, Head>::value }; |
+}; |
+ |
+// A paramater pack introspection template that can determine if the pack |
+// only contains |RequiredType|. |
+template <typename RequiredType, typename Head, typename... Tail> |
+struct check_all_same_type { |
+ enum { |
+ value = std::is_same<RequiredType, Head>::value && |
+ check_all_same_type<RequiredType, Tail...>::value |
+ }; |
+}; |
+ |
+template <typename RequiredType, typename Head> |
+struct check_all_same_type<RequiredType, Head> { |
+ enum { value = std::is_same<RequiredType, Head>::value }; |
+}; |
+ |
+// This template is for returning the return type of the Nth promise in a |
+// parameter pack of scoped_ref_ptrs<Promise<R>> |
+template <std::size_t Index, typename T, typename... Ts> |
+struct nth_promise_impl { |
+ using Type = typename nth_promise_impl<Index - 1, Ts...>::Type; |
+}; |
+ |
+template <typename T, typename... Ts> |
+struct nth_promise_impl<0, T, Ts...> { |
+ using Type = typename T::ReturnType; |
+}; |
+ |
+// This template is for calling |GetResolved| on the Nth promise in a |
+// parameter pack of scoped_ref_ptrs<Promise<R>> where the actual promises are |
+// held in a std::vector<scoped_refptr<PromiseBase>>. |
+template <std::size_t Index, typename... Promises> |
+struct PromiseResolver { |
+ using ReturnType = typename nth_promise_impl<Index, Promises...>::Type; |
+ |
+ static ReturnType GetResolved( |
+ std::vector<scoped_refptr<PromiseBase>>& promises) { |
+ return std::move(static_cast<Promise<ReturnType>*>(promises[Index].get()) |
+ ->GetResolved()); |
+ } |
+}; |
+ |
+// This template is for generating a parameter pack of N indicies. |
+// When C++14 is allowed we can replace with std::integer_sequence. |
+template <size_t... Ns> |
+struct indices { |
+ typedef indices<Ns..., sizeof...(Ns)> next; |
+}; |
+ |
+template <size_t N> |
+struct make_indices { |
+ typedef typename make_indices<N - 1>::type::next type; |
+}; |
+ |
+template <> |
+struct make_indices<0> { |
+ typedef indices<> type; |
+}; |
+ |
+} // namespace internal |
+} // namespace promise |
+ |
+#endif // COMPONENTS_SCHEDULER_PROMISES_TEMPLATE_HELPERS_H_ |