Index: base/callback_tuple.h |
diff --git a/base/callback_tuple.h b/base/callback_tuple.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bba652d860bb99639082708ae8c9e0c84639e4c1 |
--- /dev/null |
+++ b/base/callback_tuple.h |
@@ -0,0 +1,141 @@ |
+// 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. |
+ |
+// Helper template classes for Bind implementation. |
+ |
+#ifndef BASE_CALLBACK_TUPLE_H_ |
+#define BASE_CALLBACK_TUPLE_H_ |
+ |
+namespace base { |
+namespace internal { |
+ |
+// Packs a list of types to hold them in a single type. |
+template <typename... Types> |
+struct TypeList {}; |
+ |
+// Used for DropTypeListItem implementation. |
+template <size_t n, typename List> |
+struct DropTypeListItemImpl; |
+ |
+// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. |
+template <size_t n, typename T, typename... List> |
+struct DropTypeListItemImpl<n, TypeList<T, List...>> |
+ : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; |
+ |
+template <typename T, typename... List> |
+struct DropTypeListItemImpl<0, TypeList<T, List...>> { |
+ typedef TypeList<T, List...> Type; |
+}; |
+ |
+template <> |
+struct DropTypeListItemImpl<0, TypeList<>> { |
+ typedef TypeList<> Type; |
+}; |
+ |
+// A type-level function that drops |n| list item from given TypeList. |
+template <size_t n, typename List> |
+using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; |
+ |
+// Used for ConcatTypeLists implementation. |
+template <typename List1, typename List2> |
+struct ConcatTypeListsImpl; |
+ |
+template <typename... Types1, typename... Types2> |
+struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { |
+ typedef TypeList<Types1..., Types2...> Type; |
+}; |
+ |
+// A type-level function that concats two TypeLists. |
+template <typename List1, typename List2> |
+using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; |
+ |
+template <size_t n, typename List> |
+struct NthTypeImpl; |
+ |
+template <size_t n, typename T, typename... Types> |
+struct NthTypeImpl<n, TypeList<T, Types...> > |
+ : NthTypeImpl<n - 1, TypeList<Types...>> { |
Nico
2014/12/08 19:58:08
:-/
(I know that there's no better way)
|
+}; |
+ |
+template <typename T, typename... Types> |
+struct NthTypeImpl<0, TypeList<T, Types...> > { |
+ typedef T Type; |
+}; |
+ |
+// A type-level function that extracts |n|th type from a TypeList. |
+template <size_t n, typename List> |
+using NthType = typename NthTypeImpl<n, List>::Type; |
+ |
+// Used for MakeFunctionType implementation. |
+template <typename R, typename ArgList> |
+struct MakeFunctionTypeImpl; |
+ |
+template <typename R, typename... Args> |
+struct MakeFunctionTypeImpl<R, TypeList<Args...>> { |
+ typedef R(Type)(Args...); |
+}; |
+ |
+// A type-level function that constructs a function type that has |R| as its |
+// return type and has TypeLists items as its arguments. |
+template <typename R, typename ArgList> |
+using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; |
+ |
+// Holds a list of indexes as a single type. |
+template <size_t... indexes> |
+struct IndexSequence {}; |
+ |
+template <size_t n, size_t... sequence> |
+struct MakeIndexSequenceImpl |
+ : MakeIndexSequenceImpl<n - 1, n - 1, sequence...> {}; |
+ |
+template <size_t... sequence> |
+struct MakeIndexSequenceImpl<0, sequence...> { |
+ typedef IndexSequence<sequence...> Type; |
+}; |
+ |
+// A type-level function that makes IndexSequence<0, 1, .., n - 1>. |
+template <size_t n> |
+using MakeIndexSequence = typename MakeIndexSequenceImpl<n>::Type; |
+ |
+// Used for Tuple<> implementation. Holds |n|th item of a Tuple<>. |
+template <size_t n, typename T> |
+struct IndexedTupleItem { |
+ explicit IndexedTupleItem(const T& value) : value_(value) {} |
+ T value_; |
+}; |
+ |
+// |
+// Implementation note: Unspecialized definition handles the empty case. |
+template <size_t n, typename... Types> |
+struct TupleBody {}; |
+ |
+// Implementation note: Handles non-empty case of Tuple construction. |
+template <size_t n, typename T, typename... Types> |
+struct TupleBody<n, T, Types...> |
+ : IndexedTupleItem<n, T>, TupleBody<n + 1, Types...>{ |
+ explicit TupleBody(const T& head, const Types&... tail) |
+ : IndexedTupleItem<n, T>(head), TupleBody<n + 1, Types...>(tail...) {} |
+}; |
+ |
+template <typename... Types> |
+using Tuple = TupleBody<0, Types...>; |
+ |
+// Extracts |i|th item from a tuple. |
+// Example: |
+// Tuple<int, std::string, void*> tuple(1, "foo", nullptr); |
+// std::string tuple_item = *GetTupleItem<1>(&tuple); |
+template <size_t i, typename T> |
+T* GetTupleItem(IndexedTupleItem<i, T>* item) { |
+ return &item->value_; |
+} |
+ |
+template <size_t i, typename T> |
+const T* GetTupleItem(const IndexedTupleItem<i, T>* item) { |
+ return &item->value_; |
+} |
+ |
+} // namespace internal |
+} // namespace base |
+ |
+#endif // BASE_CALLBACK_TUPLE_H_ |