Index: base/callback_tuple.h |
diff --git a/base/callback_tuple.h b/base/callback_tuple.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..90937808e66d00a62d8c1150e8f2f59b4a57492a |
--- /dev/null |
+++ b/base/callback_tuple.h |
@@ -0,0 +1,119 @@ |
+// Copyright 2014 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_CALLBACK_TUPLE_H_ |
+#define BASE_CALLBACK_TUPLE_H_ |
+ |
+#include "base/callback_internal.h" |
+ |
+namespace base { |
+namespace internal { |
+ |
+template <typename... Types> |
+struct TypeList {}; |
+ |
+template <bool IsWeakCall, typename ReturnType, typename Runnable, |
+ typename ArgsType> |
+struct InvokeHelper; |
+ |
+class BindStateBase; |
+ |
+template <int index, typename... Args> |
+struct TupleImpl {}; |
+ |
+template <int index, typename T, typename... Rest> |
+struct TupleImpl<index, T, Rest...> : TupleImpl<index + 1, Rest...> { |
+ TupleImpl(const T& value, const Rest&... rest) |
+ : TupleImpl<index + 1, Rest...>(rest...), |
+ value_(value) {} |
+ T value_; |
+}; |
+ |
+template <typename... Args> |
+struct Tuple : TupleImpl<0, Args...> { |
+ Tuple(const Args&... args) : TupleImpl<0, Args...>(args...) {} |
+}; |
+ |
+template <int i, typename... Types> |
+struct NthType; |
+ |
+template <typename T, typename... Rest> |
+struct NthType<0, T, Rest...> { |
+ typedef T Result; |
+}; |
+ |
+template <int i, typename T, typename... Rest> |
+struct NthType<i, T, Rest...> : NthType<i-1, Rest...> { |
+}; |
+ |
+template <int i, typename TupleType> |
+struct NthTupleType; |
+ |
+template <int i, typename... Args> |
+struct NthTupleType<i, Tuple<Args...> > : NthType<i, Args...> { |
+}; |
+ |
+template <int i, typename T, typename... Rest> |
+T* GetNth(TupleImpl<i, T, Rest...>* tuple) { |
+ return &tuple->value_; |
+} |
+ |
+template <int n, typename R, typename... Args> |
+struct RunTypeHelper; |
+ |
+template <typename R, typename... Args> |
+struct RunTypeHelper<0, R, Args...> { |
+ typedef R(RunType)( |
+ BindStateBase*, |
+ typename CallbackParamTraits<Args>::ForwardType...); |
+ typedef R(UnboundRunType)(Args...); |
+}; |
+ |
+template <typename R, typename T, typename... Args> |
+struct RunTypeHelper<0, R, T, Args...> { |
+ typedef R(RunType)( |
+ BindStateBase*, |
+ typename CallbackParamTraits<T>::ForwardType, |
+ typename CallbackParamTraits<Args>::ForwardType...); |
+ typedef R(UnboundRunType)(T, Args...); |
+}; |
+ |
+template <int n, typename R, typename T, typename... Args> |
+struct RunTypeHelper<n, R, T, Args...> |
+ : public RunTypeHelper<n-1, R, Args...> { |
+}; |
+ |
+template <int i, typename StorageType, typename R, typename... Args> |
+struct ExtractHelper { |
+ static R Invoke(StorageType* storage, Args... args) { |
+ typedef typename NthTupleType< |
+ i-1, typename StorageType::BoundType>::Result T; |
+ typedef UnwrapTraits<T> Unwrapper; |
+ typename Unwrapper::ForwardType forwarding = |
+ Unwrapper::Unwrap(*GetNth<i-1>(&storage->bound_args_)); |
+ |
+ return ExtractHelper<i-1, StorageType, R, |
+ typename Unwrapper::ForwardType, |
+ Args...>::Invoke( |
+ storage, |
+ CallbackForward(forwarding), |
+ CallbackForward(args)...); |
+ } |
+}; |
+ |
+template <typename StorageType, typename R, typename... Args> |
+struct ExtractHelper<0, StorageType, R, Args...> { |
+ static R Invoke(StorageType* storage, Args... args) { |
+ return InvokeHelper< |
+ StorageType::IsWeakCall::value, R, |
+ typename StorageType::RunnableType, |
+ TypeList<typename CallbackParamTraits<Args>::ForwardType...>> |
+ ::MakeItSo(storage->runnable_, CallbackForward(args)...); |
+ } |
+}; |
+ |
+} // namespace internal |
+} // namespace base |
+ |
+#endif // BASE_CALLBACK_TUPLE_H_ |