Index: base/tuple.h |
diff --git a/base/tuple.h b/base/tuple.h |
index 16f51241392946b3c264687b77ef54998d86ac2c..885413f7570e980dbc4c4a2caa4108b2594b8f1a 100644 |
--- a/base/tuple.h |
+++ b/base/tuple.h |
@@ -2,20 +2,19 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-// A Tuple is a generic templatized container, similar in concept to std::pair. |
-// There are classes Tuple0 to Tuple6, cooresponding to the number of elements |
-// it contains. The convenient MakeTuple() function takes 0 to 6 arguments, |
-// and will construct and return the appropriate Tuple object. The functions |
-// DispatchToMethod and DispatchToFunction take a function pointer or instance |
-// and method pointer, and unpack a tuple into arguments to the call. |
+// A Tuple is a generic templatized container, similar in concept to std::pair |
+// and std::tuple. The convenient MakeTuple() function takes any number of |
+// arguments and will construct and return the appropriate Tuple object. The |
+// functions DispatchToMethod and DispatchToFunction take a function pointer or |
+// instance and method pointer, and unpack a tuple into arguments to the call. |
// |
// Tuple elements are copied by value, and stored in the tuple. See the unit |
// tests for more details of how/when the values are copied. |
// |
// Example usage: |
// // These two methods of creating a Tuple are identical. |
-// Tuple2<int, const char*> tuple_a(1, "wee"); |
-// Tuple2<int, const char*> tuple_b = MakeTuple(1, "wee"); |
+// Tuple<int, const char*> tuple_a(1, "wee"); |
+// Tuple<int, const char*> tuple_b = MakeTuple(1, "wee"); |
// |
// void SomeFunc(int a, const char* b) { } |
// DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") |
@@ -47,9 +46,8 @@ struct MakeIndexSequenceImpl<0, Ns...> { |
}; |
template <size_t N, size_t... Ns> |
-struct MakeIndexSequenceImpl<N, Ns...> { |
- using Type = typename MakeIndexSequenceImpl<N - 1, N - 1, Ns...>::Type; |
-}; |
+struct MakeIndexSequenceImpl<N, Ns...> |
+ : MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {}; |
template <size_t N> |
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; |
@@ -83,217 +81,77 @@ struct TupleTraits<P&> { |
// function objects that need to take an arbitrary number of parameters; see |
// RunnableMethod and IPC::MessageWithTuple. |
// |
-// Tuple0 is supplied to act as a 'void' type. It can be used, for example, |
+// Tuple<> is supplied to act as a 'void' type. It can be used, for example, |
// when dispatching to a function that accepts no arguments (see the |
// Dispatchers below). |
-// Tuple1<A> is rarely useful. One such use is when A is non-const ref that you |
+// Tuple<A> is rarely useful. One such use is when A is non-const ref that you |
// want filled by the dispatchee, and the tuple is merely a container for that |
// output (a "tier"). See MakeRefTuple and its usages. |
+template <typename IxSeq, typename... Ts> |
+struct TupleBaseImpl; |
template <typename... Ts> |
-struct Tuple; |
+using TupleBase = TupleBaseImpl<MakeIndexSequence<sizeof...(Ts)>, Ts...>; |
+template <size_t N, typename T> |
+struct TupleLeaf; |
+ |
+template <typename... Ts> |
+struct Tuple : TupleBase<Ts...> { |
+ Tuple() : TupleBase<Ts...>() {} |
+ explicit Tuple(typename TupleTraits<Ts>::ParamType... args) |
+ : TupleBase<Ts...>(args...) {} |
+}; |
+// Avoids ambiguity between Tuple's two constructors. |
template <> |
struct Tuple<> {}; |
-template <typename A> |
-struct Tuple<A> { |
- public: |
- typedef A TypeA; |
- |
- Tuple() {} |
- explicit Tuple(typename TupleTraits<A>::ParamType a) : a(a) {} |
- |
- A a; |
-}; |
- |
-template <typename A, typename B> |
-struct Tuple<A, B> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b) |
- : a(a), b(b) {} |
- |
- A a; |
- B b; |
+template <size_t... Ns, typename... Ts> |
+struct TupleBaseImpl<IndexSequence<Ns...>, Ts...> : TupleLeaf<Ns, Ts>... { |
+ TupleBaseImpl() : TupleLeaf<Ns, Ts>()... {} |
+ explicit TupleBaseImpl(typename TupleTraits<Ts>::ParamType... args) |
+ : TupleLeaf<Ns, Ts>(args)... {} |
}; |
-template <typename A, typename B, typename C> |
-struct Tuple<A, B, C> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c) |
- : a(a), b(b), c(c) {} |
- |
- A a; |
- B b; |
- C c; |
-}; |
+template <size_t N, typename T> |
+struct TupleLeaf { |
+ TupleLeaf() : x() {} |
+ explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {} |
-template <typename A, typename B, typename C, typename D> |
-struct Tuple<A, B, C, D> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- typedef D TypeD; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c, |
- typename TupleTraits<D>::ParamType d) |
- : a(a), b(b), c(c), d(d) {} |
- |
- A a; |
- B b; |
- C c; |
- D d; |
-}; |
+ T& get() { return x; } |
+ const T& get() const { return x; } |
-template <typename A, typename B, typename C, typename D, typename E> |
-struct Tuple<A, B, C, D, E> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- typedef D TypeD; |
- typedef E TypeE; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c, |
- typename TupleTraits<D>::ParamType d, |
- typename TupleTraits<E>::ParamType e) |
- : a(a), b(b), c(c), d(d), e(e) {} |
- |
- A a; |
- B b; |
- C c; |
- D d; |
- E e; |
+ T x; |
}; |
-template <typename A, |
- typename B, |
- typename C, |
- typename D, |
- typename E, |
- typename F> |
-struct Tuple<A, B, C, D, E, F> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- typedef D TypeD; |
- typedef E TypeE; |
- typedef F TypeF; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c, |
- typename TupleTraits<D>::ParamType d, |
- typename TupleTraits<E>::ParamType e, |
- typename TupleTraits<F>::ParamType f) |
- : a(a), b(b), c(c), d(d), e(e), f(f) {} |
- |
- A a; |
- B b; |
- C c; |
- D d; |
- E e; |
- F f; |
-}; |
- |
-template <typename A, |
- typename B, |
- typename C, |
- typename D, |
- typename E, |
- typename F, |
- typename G> |
-struct Tuple<A, B, C, D, E, F, G> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- typedef D TypeD; |
- typedef E TypeE; |
- typedef F TypeF; |
- typedef G TypeG; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c, |
- typename TupleTraits<D>::ParamType d, |
- typename TupleTraits<E>::ParamType e, |
- typename TupleTraits<F>::ParamType f, |
- typename TupleTraits<G>::ParamType g) |
- : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {} |
- |
- A a; |
- B b; |
- C c; |
- D d; |
- E e; |
- F f; |
- G g; |
-}; |
- |
-template <typename A, |
- typename B, |
- typename C, |
- typename D, |
- typename E, |
- typename F, |
- typename G, |
- typename H> |
-struct Tuple<A, B, C, D, E, F, G, H> { |
- public: |
- typedef A TypeA; |
- typedef B TypeB; |
- typedef C TypeC; |
- typedef D TypeD; |
- typedef E TypeE; |
- typedef F TypeF; |
- typedef G TypeG; |
- typedef H TypeH; |
- |
- Tuple() {} |
- Tuple(typename TupleTraits<A>::ParamType a, |
- typename TupleTraits<B>::ParamType b, |
- typename TupleTraits<C>::ParamType c, |
- typename TupleTraits<D>::ParamType d, |
- typename TupleTraits<E>::ParamType e, |
- typename TupleTraits<F>::ParamType f, |
- typename TupleTraits<G>::ParamType g, |
- typename TupleTraits<H>::ParamType h) |
- : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {} |
- |
- A a; |
- B b; |
- C c; |
- D d; |
- E e; |
- F f; |
- G g; |
- H h; |
-}; |
+// For legacy compatibility, we name the first 8 tuple elements "a", "b", ... |
+// TODO(mdempsky): Update users to use get<N>() (crbug.com/440675). |
+ |
+#define DEFINE_TUPLE_LEAF(N, x) \ |
+ template <typename T> \ |
+ struct TupleLeaf<N, T> { \ |
+ TupleLeaf() : x() {} \ |
+ explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {} \ |
+ \ |
+ T& get() { return x; } \ |
+ const T& get() const { return x; } \ |
+ \ |
+ T x; \ |
+ } |
+ |
+DEFINE_TUPLE_LEAF(0, a); |
+DEFINE_TUPLE_LEAF(1, b); |
+DEFINE_TUPLE_LEAF(2, c); |
+DEFINE_TUPLE_LEAF(3, d); |
+DEFINE_TUPLE_LEAF(4, e); |
+DEFINE_TUPLE_LEAF(5, f); |
+DEFINE_TUPLE_LEAF(6, g); |
+DEFINE_TUPLE_LEAF(7, h); |
+ |
+#undef DEFINE_TUPLE_LEAF |
// Deprecated compat aliases |
+// TODO(mdempsky): Update users to just use Tuple instead (crbug.com/440675). |
using Tuple0 = Tuple<>; |
template <typename A> |
@@ -331,91 +189,23 @@ template <typename A, |
typename H> |
using Tuple8 = Tuple<A, B, C, D, E, F, G, H>; |
-// Tuple element -------------------------------------------------------------- |
- |
-template <size_t N, typename T> |
-struct TupleElement; |
- |
-template <typename T, typename... Ts> |
-struct TupleElement<0, Tuple<T, Ts...>> { |
- using Type = T; |
-}; |
- |
-template <size_t N, typename T, typename... Ts> |
-struct TupleElement<N, Tuple<T, Ts...>> { |
- using Type = typename TupleElement<N - 1, Tuple<Ts...>>::Type; |
-}; |
- |
// Tuple getters -------------------------------------------------------------- |
+// |
+// Allows accessing an arbitrary tuple element by index. |
+// |
+// Example usage: |
+// Tuple<int, double> t2; |
+// get<0>(t2) = 42; |
+// get<1>(t2) = 3.14; |
-template <size_t, typename T> |
-struct TupleGetter; |
- |
-template <typename... Ts> |
-struct TupleGetter<0, Tuple<Ts...>> { |
- using Elem = typename TupleElement<0, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.a; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.a; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<1, Tuple<Ts...>> { |
- using Elem = typename TupleElement<1, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.b; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.b; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<2, Tuple<Ts...>> { |
- using Elem = typename TupleElement<2, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.c; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.c; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<3, Tuple<Ts...>> { |
- using Elem = typename TupleElement<3, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.d; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.d; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<4, Tuple<Ts...>> { |
- using Elem = typename TupleElement<4, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.e; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.e; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<5, Tuple<Ts...>> { |
- using Elem = typename TupleElement<5, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.f; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.f; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<6, Tuple<Ts...>> { |
- using Elem = typename TupleElement<6, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.g; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.g; } |
-}; |
- |
-template <typename... Ts> |
-struct TupleGetter<7, Tuple<Ts...>> { |
- using Elem = typename TupleElement<7, Tuple<Ts...>>::Type; |
- static Elem& Get(Tuple<Ts...>& t) { return t.h; } |
- static const Elem& Get(const Tuple<Ts...>& t) { return t.h; } |
-}; |
- |
-template <size_t I, typename... Ts> |
-typename TupleElement<I, Tuple<Ts...>>::Type& get(Tuple<Ts...>& tuple) { |
- return TupleGetter<I, Tuple<Ts...>>::Get(tuple); |
+template <size_t I, typename T> |
+T& get(TupleLeaf<I, T>& leaf) { |
+ return leaf.get(); |
} |
-template <size_t I, typename... Ts> |
-const typename TupleElement<I, Tuple<Ts...>>::Type& get( |
- const Tuple<Ts...>& tuple) { |
- return TupleGetter<I, Tuple<Ts...>>::Get(tuple); |
+template <size_t I, typename T> |
+const T& get(const TupleLeaf<I, T>& leaf) { |
+ return leaf.get(); |
} |
// Tuple types ---------------------------------------------------------------- |