Chromium Code Reviews| 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_ |