diff options
author | mdempsky <mdempsky@chromium.org> | 2014-12-09 19:10:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-10 03:11:21 +0000 |
commit | 6e7f615f49056439312aad3fcdd2284e2bd69647 (patch) | |
tree | 820a6ce25759e808f8580c0c42e8faf0d27bb0dd | |
parent | c0344cbb2a4d93eadcc04d1c53f30b488bffe03f (diff) | |
download | chromium_src-6e7f615f49056439312aad3fcdd2284e2bd69647.zip chromium_src-6e7f615f49056439312aad3fcdd2284e2bd69647.tar.gz chromium_src-6e7f615f49056439312aad3fcdd2284e2bd69647.tar.bz2 |
tuple: update to make use of C++11
This CL adds a generic variadic Tuple class that generalizes
Tuple1, Tuple2, etc. It also adds the C++11-style get<N>(tuple)
method for accessing tuple members. As a demonstration, the
DispatchToFunction() and DispatchToMethod() functions have been
updated to make use of these and became substantially shorter.
However, to remain compatible with existing code that accesses
Tuple fields by name, the Tuple class is actually implemented via
multiple specializations that match the TupleN classes that used
to exist. Once all access to foo.a, bar->b, ... have been updated
to get<0>(foo), get<1>(*bar), ... then we can simplify Tuple
further and eventually replace it with std::tuple.
Review URL: https://codereview.chromium.org/693693005
Cr-Commit-Position: refs/heads/master@{#307629}
-rw-r--r-- | base/tuple.h | 1336 |
1 files changed, 300 insertions, 1036 deletions
diff --git a/base/tuple.h b/base/tuple.h index 12f7f84..16f5124 100644 --- a/base/tuple.h +++ b/base/tuple.h @@ -31,6 +31,29 @@ #include "base/bind_helpers.h" +// Index sequences +// +// Minimal clone of the similarly-named C++14 functionality. + +template <size_t...> +struct IndexSequence {}; + +template <size_t... Ns> +struct MakeIndexSequenceImpl; + +template <size_t... Ns> +struct MakeIndexSequenceImpl<0, Ns...> { + using Type = IndexSequence<Ns...>; +}; + +template <size_t N, size_t... Ns> +struct MakeIndexSequenceImpl<N, Ns...> { + using Type = typename MakeIndexSequenceImpl<N - 1, N - 1, Ns...>::Type; +}; + +template <size_t N> +using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; + // Traits ---------------------------------------------------------------------- // // A simple traits class for tuple arguments. @@ -53,9 +76,6 @@ struct TupleTraits<P&> { typedef P& ParamType; }; -template <class P> -struct TupleTypes { }; - // Tuple ----------------------------------------------------------------------- // // This set of classes is useful for bundling 0 or more heterogeneous data types @@ -70,73 +90,70 @@ struct TupleTypes { }; // want filled by the dispatchee, and the tuple is merely a container for that // output (a "tier"). See MakeRefTuple and its usages. -struct Tuple0 { - typedef Tuple0 ValueTuple; - typedef Tuple0 RefTuple; - typedef Tuple0 ParamTuple; -}; +template <typename... Ts> +struct Tuple; -template <class A> -struct Tuple1 { +template <> +struct Tuple<> {}; + +template <typename A> +struct Tuple<A> { public: typedef A TypeA; - Tuple1() {} - explicit Tuple1(typename TupleTraits<A>::ParamType a) : a(a) {} + Tuple() {} + explicit Tuple(typename TupleTraits<A>::ParamType a) : a(a) {} A a; }; -template <class A, class B> -struct Tuple2 { +template <typename A, typename B> +struct Tuple<A, B> { public: typedef A TypeA; typedef B TypeB; - Tuple2() {} - Tuple2(typename TupleTraits<A>::ParamType a, - typename TupleTraits<B>::ParamType b) - : a(a), b(b) { - } + Tuple() {} + Tuple(typename TupleTraits<A>::ParamType a, + typename TupleTraits<B>::ParamType b) + : a(a), b(b) {} A a; B b; }; -template <class A, class B, class C> -struct Tuple3 { +template <typename A, typename B, typename C> +struct Tuple<A, B, C> { public: typedef A TypeA; typedef B TypeB; typedef C TypeC; - Tuple3() {} - Tuple3(typename TupleTraits<A>::ParamType a, - typename TupleTraits<B>::ParamType b, - typename TupleTraits<C>::ParamType c) - : a(a), b(b), c(c){ - } + 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 <class A, class B, class C, class D> -struct Tuple4 { +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; - Tuple4() {} - Tuple4(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) { - } + 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; @@ -144,8 +161,8 @@ struct Tuple4 { D d; }; -template <class A, class B, class C, class D, class E> -struct Tuple5 { +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; @@ -153,14 +170,13 @@ struct Tuple5 { typedef D TypeD; typedef E TypeE; - Tuple5() {} - Tuple5(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) { - } + 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; @@ -169,8 +185,13 @@ struct Tuple5 { E e; }; -template <class A, class B, class C, class D, class E, class F> -struct Tuple6 { +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; @@ -179,15 +200,14 @@ struct Tuple6 { typedef E TypeE; typedef F TypeF; - Tuple6() {} - Tuple6(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) { - } + 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; @@ -197,8 +217,14 @@ struct Tuple6 { F f; }; -template <class A, class B, class C, class D, class E, class F, class G> -struct Tuple7 { +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; @@ -208,16 +234,15 @@ struct Tuple7 { typedef F TypeF; typedef G TypeG; - Tuple7() {} - Tuple7(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) { - } + 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; @@ -228,9 +253,15 @@ struct Tuple7 { G g; }; -template <class A, class B, class C, class D, class E, class F, class G, - class H> -struct Tuple8 { +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; @@ -241,17 +272,16 @@ struct Tuple8 { typedef G TypeG; typedef H TypeH; - Tuple8() {} - Tuple8(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) { - } + 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; @@ -263,263 +293,162 @@ struct Tuple8 { H h; }; -// Tuple types ---------------------------------------------------------------- -// -// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the -// definitions of class types the tuple takes as parameters. - -template <> -struct TupleTypes< Tuple0 > { - typedef Tuple0 ValueTuple; - typedef Tuple0 RefTuple; - typedef Tuple0 ParamTuple; +// Deprecated compat aliases + +using Tuple0 = Tuple<>; +template <typename A> +using Tuple1 = Tuple<A>; +template <typename A, typename B> +using Tuple2 = Tuple<A, B>; +template <typename A, typename B, typename C> +using Tuple3 = Tuple<A, B, C>; +template <typename A, typename B, typename C, typename D> +using Tuple4 = Tuple<A, B, C, D>; +template <typename A, typename B, typename C, typename D, typename E> +using Tuple5 = Tuple<A, B, C, D, E>; +template <typename A, + typename B, + typename C, + typename D, + typename E, + typename F> +using Tuple6 = Tuple<A, B, C, D, E, F>; +template <typename A, + typename B, + typename C, + typename D, + typename E, + typename F, + typename G> +using Tuple7 = Tuple<A, B, C, D, E, F, G>; +template <typename A, + typename B, + typename C, + typename D, + typename E, + typename F, + typename G, + 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 <class A> -struct TupleTypes< Tuple1<A> > { - typedef Tuple1<typename TupleTraits<A>::ValueType> ValueTuple; - typedef Tuple1<typename TupleTraits<A>::RefType> RefTuple; - typedef Tuple1<typename TupleTraits<A>::ParamType> ParamTuple; +template <size_t N, typename T, typename... Ts> +struct TupleElement<N, Tuple<T, Ts...>> { + using Type = typename TupleElement<N - 1, Tuple<Ts...>>::Type; }; -template <class A, class B> -struct TupleTypes< Tuple2<A, B> > { - typedef Tuple2<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType> ValueTuple; -typedef Tuple2<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType> RefTuple; - typedef Tuple2<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType> ParamTuple; -}; +// Tuple getters -------------------------------------------------------------- -template <class A, class B, class C> -struct TupleTypes< Tuple3<A, B, C> > { - typedef Tuple3<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType> ValueTuple; -typedef Tuple3<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType> RefTuple; - typedef Tuple3<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType> ParamTuple; -}; +template <size_t, typename T> +struct TupleGetter; -template <class A, class B, class C, class D> -struct TupleTypes< Tuple4<A, B, C, D> > { - typedef Tuple4<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType, - typename TupleTraits<D>::ValueType> ValueTuple; -typedef Tuple4<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType, - typename TupleTraits<D>::RefType> RefTuple; - typedef Tuple4<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType, - typename TupleTraits<D>::ParamType> ParamTuple; +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 <class A, class B, class C, class D, class E> -struct TupleTypes< Tuple5<A, B, C, D, E> > { - typedef Tuple5<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType, - typename TupleTraits<D>::ValueType, - typename TupleTraits<E>::ValueType> ValueTuple; -typedef Tuple5<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType, - typename TupleTraits<D>::RefType, - typename TupleTraits<E>::RefType> RefTuple; - typedef Tuple5<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType, - typename TupleTraits<D>::ParamType, - typename TupleTraits<E>::ParamType> ParamTuple; +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 <class A, class B, class C, class D, class E, class F> -struct TupleTypes< Tuple6<A, B, C, D, E, F> > { - typedef Tuple6<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType, - typename TupleTraits<D>::ValueType, - typename TupleTraits<E>::ValueType, - typename TupleTraits<F>::ValueType> ValueTuple; -typedef Tuple6<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType, - typename TupleTraits<D>::RefType, - typename TupleTraits<E>::RefType, - typename TupleTraits<F>::RefType> RefTuple; - typedef Tuple6<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType, - typename TupleTraits<D>::ParamType, - typename TupleTraits<E>::ParamType, - typename TupleTraits<F>::ParamType> ParamTuple; +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 <class A, class B, class C, class D, class E, class F, class G> -struct TupleTypes< Tuple7<A, B, C, D, E, F, G> > { - typedef Tuple7<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType, - typename TupleTraits<D>::ValueType, - typename TupleTraits<E>::ValueType, - typename TupleTraits<F>::ValueType, - typename TupleTraits<G>::ValueType> ValueTuple; -typedef Tuple7<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType, - typename TupleTraits<D>::RefType, - typename TupleTraits<E>::RefType, - typename TupleTraits<F>::RefType, - typename TupleTraits<G>::RefType> RefTuple; - typedef Tuple7<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType, - typename TupleTraits<D>::ParamType, - typename TupleTraits<E>::ParamType, - typename TupleTraits<F>::ParamType, - typename TupleTraits<G>::ParamType> ParamTuple; +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 <class A, class B, class C, class D, class E, class F, class G, - class H> -struct TupleTypes< Tuple8<A, B, C, D, E, F, G, H> > { - typedef Tuple8<typename TupleTraits<A>::ValueType, - typename TupleTraits<B>::ValueType, - typename TupleTraits<C>::ValueType, - typename TupleTraits<D>::ValueType, - typename TupleTraits<E>::ValueType, - typename TupleTraits<F>::ValueType, - typename TupleTraits<G>::ValueType, - typename TupleTraits<H>::ValueType> ValueTuple; -typedef Tuple8<typename TupleTraits<A>::RefType, - typename TupleTraits<B>::RefType, - typename TupleTraits<C>::RefType, - typename TupleTraits<D>::RefType, - typename TupleTraits<E>::RefType, - typename TupleTraits<F>::RefType, - typename TupleTraits<G>::RefType, - typename TupleTraits<H>::RefType> RefTuple; - typedef Tuple8<typename TupleTraits<A>::ParamType, - typename TupleTraits<B>::ParamType, - typename TupleTraits<C>::ParamType, - typename TupleTraits<D>::ParamType, - typename TupleTraits<E>::ParamType, - typename TupleTraits<F>::ParamType, - typename TupleTraits<G>::ParamType, - typename TupleTraits<H>::ParamType> ParamTuple; +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; } }; -// Tuple creators ------------------------------------------------------------- -// -// Helper functions for constructing tuples while inferring the template -// argument types. +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; } +}; -inline Tuple0 MakeTuple() { - return Tuple0(); -} +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 <class A> -inline Tuple1<A> MakeTuple(const A& a) { - return Tuple1<A>(a); -} +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 <class A, class B> -inline Tuple2<A, B> MakeTuple(const A& a, const B& b) { - return Tuple2<A, B>(a, b); +template <size_t I, typename... Ts> +typename TupleElement<I, Tuple<Ts...>>::Type& get(Tuple<Ts...>& tuple) { + return TupleGetter<I, Tuple<Ts...>>::Get(tuple); } -template <class A, class B, class C> -inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c) { - return Tuple3<A, B, C>(a, b, c); +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 <class A, class B, class C, class D> -inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c, - const D& d) { - return Tuple4<A, B, C, D>(a, b, c, d); -} +// Tuple types ---------------------------------------------------------------- +// +// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the +// definitions of class types the tuple takes as parameters. -template <class A, class B, class C, class D, class E> -inline Tuple5<A, B, C, D, E> MakeTuple(const A& a, const B& b, const C& c, - const D& d, const E& e) { - return Tuple5<A, B, C, D, E>(a, b, c, d, e); -} +template <typename T> +struct TupleTypes; -template <class A, class B, class C, class D, class E, class F> -inline Tuple6<A, B, C, D, E, F> MakeTuple(const A& a, const B& b, const C& c, - const D& d, const E& e, const F& f) { - return Tuple6<A, B, C, D, E, F>(a, b, c, d, e, f); -} +template <typename... Ts> +struct TupleTypes<Tuple<Ts...>> { + using ValueTuple = Tuple<typename TupleTraits<Ts>::ValueType...>; + using RefTuple = Tuple<typename TupleTraits<Ts>::RefType...>; + using ParamTuple = Tuple<typename TupleTraits<Ts>::ParamType...>; +}; -template <class A, class B, class C, class D, class E, class F, class G> -inline Tuple7<A, B, C, D, E, F, G> MakeTuple(const A& a, const B& b, const C& c, - const D& d, const E& e, const F& f, - const G& g) { - return Tuple7<A, B, C, D, E, F, G>(a, b, c, d, e, f, g); -} +// Tuple creators ------------------------------------------------------------- +// +// Helper functions for constructing tuples while inferring the template +// argument types. -template <class A, class B, class C, class D, class E, class F, class G, - class H> -inline Tuple8<A, B, C, D, E, F, G, H> MakeTuple(const A& a, const B& b, - const C& c, const D& d, - const E& e, const F& f, - const G& g, const H& h) { - return Tuple8<A, B, C, D, E, F, G, H>(a, b, c, d, e, f, g, h); +template <typename... Ts> +inline Tuple<Ts...> MakeTuple(const Ts&... arg) { + return Tuple<Ts...>(arg...); } // The following set of helpers make what Boost refers to as "Tiers" - a tuple // of references. -template <class A> -inline Tuple1<A&> MakeRefTuple(A& a) { - return Tuple1<A&>(a); -} - -template <class A, class B> -inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) { - return Tuple2<A&, B&>(a, b); -} - -template <class A, class B, class C> -inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) { - return Tuple3<A&, B&, C&>(a, b, c); -} - -template <class A, class B, class C, class D> -inline Tuple4<A&, B&, C&, D&> MakeRefTuple(A& a, B& b, C& c, D& d) { - return Tuple4<A&, B&, C&, D&>(a, b, c, d); -} - -template <class A, class B, class C, class D, class E> -inline Tuple5<A&, B&, C&, D&, E&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e) { - return Tuple5<A&, B&, C&, D&, E&>(a, b, c, d, e); -} - -template <class A, class B, class C, class D, class E, class F> -inline Tuple6<A&, B&, C&, D&, E&, F&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e, - F& f) { - return Tuple6<A&, B&, C&, D&, E&, F&>(a, b, c, d, e, f); -} - -template <class A, class B, class C, class D, class E, class F, class G> -inline Tuple7<A&, B&, C&, D&, E&, F&, G&> MakeRefTuple(A& a, B& b, C& c, D& d, - E& e, F& f, G& g) { - return Tuple7<A&, B&, C&, D&, E&, F&, G&>(a, b, c, d, e, f, g); -} - -template <class A, class B, class C, class D, class E, class F, class G, - class H> -inline Tuple8<A&, B&, C&, D&, E&, F&, G&, H&> MakeRefTuple(A& a, B& b, C& c, - D& d, E& e, F& f, - G& g, H& h) { - return Tuple8<A&, B&, C&, D&, E&, F&, G&, H&>(a, b, c, d, e, f, g, h); +template <typename... Ts> +inline Tuple<Ts&...> MakeRefTuple(Ts&... arg) { + return Tuple<Ts&...>(arg...); } // Dispatchers ---------------------------------------------------------------- @@ -533,759 +462,94 @@ inline Tuple8<A&, B&, C&, D&, E&, F&, G&, H&> MakeRefTuple(A& a, B& b, C& c, // Non-Static Dispatchers with no out params. -template <class ObjT, class Method> -inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) { - (obj->*method)(); -} - -template <class ObjT, class Method, class A> +template <typename ObjT, typename Method, typename A> inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) { (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg)); } -template <class ObjT, class Method, class A> -inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a)); +template <typename ObjT, typename Method, typename... Ts, size_t... Ns> +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const Tuple<Ts...>& arg, + IndexSequence<Ns...>) { + (obj->*method)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); } -template<class ObjT, class Method, class A, class B> +template <typename ObjT, typename Method, typename... Ts> inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<A, B>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b)); -} - -template<class ObjT, class Method, class A, class B, class C> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<A, B, C>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c)); -} - -template<class ObjT, class Method, class A, class B, class C, class D> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<A, B, C, D>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<A, B, C, D, E>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E, - class F> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<A, B, C, D, E, F>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E, - class F, class G> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple7<A, B, C, D, E, F, G>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f), - base::internal::UnwrapTraits<G>::Unwrap(arg.g)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E, - class F, class G, class H> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple8<A, B, C, D, E, F, G, H>& arg) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f), - base::internal::UnwrapTraits<G>::Unwrap(arg.g), - base::internal::UnwrapTraits<H>::Unwrap(arg.h)); + const Tuple<Ts...>& arg) { + DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>()); } // Static Dispatchers with no out params. -template <class Function> -inline void DispatchToFunction(Function function, const Tuple0& arg) { - (*function)(); -} - -template <class Function, class A> -inline void DispatchToFunction(Function function, const A& arg) { - (*function)(arg); -} - -template <class Function, class A> -inline void DispatchToFunction(Function function, const Tuple1<A>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a)); +template <typename Function, typename A> +inline void DispatchToMethod(Function function, const A& arg) { + (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg)); } -template<class Function, class A, class B> -inline void DispatchToFunction(Function function, const Tuple2<A, B>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b)); +template <typename Function, typename... Ts, size_t... Ns> +inline void DispatchToFunctionImpl(Function function, + const Tuple<Ts...>& arg, + IndexSequence<Ns...>) { + (*function)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); } -template<class Function, class A, class B, class C> -inline void DispatchToFunction(Function function, const Tuple3<A, B, C>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c)); +template <typename Function, typename... Ts> +inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) { + DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>()); } -template<class Function, class A, class B, class C, class D> -inline void DispatchToFunction(Function function, - const Tuple4<A, B, C, D>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d)); -} - -template<class Function, class A, class B, class C, class D, class E> -inline void DispatchToFunction(Function function, - const Tuple5<A, B, C, D, E>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e)); -} +// Dispatchers with out parameters. -template<class Function, class A, class B, class C, class D, class E, class F> -inline void DispatchToFunction(Function function, - const Tuple6<A, B, C, D, E, F>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f)); +template <typename ObjT, + typename Method, + typename In, + typename... OutTs, + size_t... OutNs> +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const In& in, + Tuple<OutTs...>* out, + IndexSequence<OutNs...>) { + (obj->*method)(base::internal::UnwrapTraits<In>::Unwrap(in), + &get<OutNs>(*out)...); } -template<class Function, class A, class B, class C, class D, class E, class F, - class G> -inline void DispatchToFunction(Function function, - const Tuple7<A, B, C, D, E, F, G>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f), - base::internal::UnwrapTraits<G>::Unwrap(arg.g)); -} - -template<class Function, class A, class B, class C, class D, class E, class F, - class G, class H> -inline void DispatchToFunction(Function function, - const Tuple8<A, B, C, D, E, F, G, H>& arg) { - (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f), - base::internal::UnwrapTraits<G>::Unwrap(arg.g), - base::internal::UnwrapTraits<H>::Unwrap(arg.h)); -} - -// Dispatchers with 0 out param (as a Tuple0). - -template <class ObjT, class Method> +template <typename ObjT, typename Method, typename In, typename... OutTs> inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& arg, Tuple0*) { - (obj->*method)(); -} - -template <class ObjT, class Method, class A> -inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg)); -} - -template <class ObjT, class Method, class A> -inline void DispatchToMethod(ObjT* obj, - Method method, - const Tuple1<A>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a)); -} - -template<class ObjT, class Method, class A, class B> + const In& in, + Tuple<OutTs...>* out) { + DispatchToMethodImpl(obj, method, in, out, + MakeIndexSequence<sizeof...(OutTs)>()); +} + +template <typename ObjT, + typename Method, + typename... InTs, + typename... OutTs, + size_t... InNs, + size_t... OutNs> +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const Tuple<InTs...>& in, + Tuple<OutTs...>* out, + IndexSequence<InNs...>, + IndexSequence<OutNs...>) { + (obj->*method)(base::internal::UnwrapTraits<InTs>::Unwrap(get<InNs>(in))..., + &get<OutNs>(*out)...); +} + +template <typename ObjT, typename Method, typename... InTs, typename... OutTs> inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<A, B>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b)); -} - -template<class ObjT, class Method, class A, class B, class C> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<A, B, C>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c)); -} - -template<class ObjT, class Method, class A, class B, class C, class D> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<A, B, C, D>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<A, B, C, D, E>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e)); -} - -template<class ObjT, class Method, class A, class B, class C, class D, class E, - class F> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<A, B, C, D, E, F>& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a), - base::internal::UnwrapTraits<B>::Unwrap(arg.b), - base::internal::UnwrapTraits<C>::Unwrap(arg.c), - base::internal::UnwrapTraits<D>::Unwrap(arg.d), - base::internal::UnwrapTraits<E>::Unwrap(arg.e), - base::internal::UnwrapTraits<F>::Unwrap(arg.f)); -} - -// Dispatchers with 1 out param. - -template<class ObjT, class Method, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple1<OutA>* out) { - (obj->*method)(&out->a); -} - -template<class ObjT, class Method, class InA, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple1<OutA>* out) { - (obj->*method)(in, &out->a); -} - -template<class ObjT, class Method, class InA, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<InA>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a); -} - -template<class ObjT, class Method, class InA, class InB, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<InA, InB>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - &out->a); -} - -template<class ObjT, class Method, class InA, class InB, class InC, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<InA, InB, InC>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - &out->a); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<InA, InB, InC, InD>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - &out->a); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class InE, class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<InA, InB, InC, InD, InE>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - &out->a); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, class InF, - class OutA> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<InA, InB, InC, InD, InE, InF>& in, - Tuple1<OutA>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - base::internal::UnwrapTraits<InF>::Unwrap(in.f), - &out->a); -} - -// Dispatchers with 2 out params. - -template<class ObjT, class Method, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(&out->a, &out->b); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(in, &out->a, &out->b); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<InA>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)( - base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a, &out->b); -} - -template<class ObjT, class Method, class InA, class InB, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<InA, InB>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - &out->a, - &out->b); -} - -template<class ObjT, class Method, class InA, class InB, class InC, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<InA, InB, InC>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - &out->a, - &out->b); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<InA, InB, InC, InD>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - &out->a, - &out->b); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<InA, InB, InC, InD, InE>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - &out->a, - &out->b); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, class InF, - class OutA, class OutB> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<InA, InB, InC, InD, InE, InF>& in, - Tuple2<OutA, OutB>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - base::internal::UnwrapTraits<InF>::Unwrap(in.f), - &out->a, - &out->b); -} - -// Dispatchers with 3 out params. - -template<class ObjT, class Method, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(&out->a, &out->b, &out->c); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(in, &out->a, &out->b, &out->c); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<InA>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - &out->a, - &out->b, - &out->c); -} - -template<class ObjT, class Method, class InA, class InB, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<InA, InB>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - &out->a, - &out->b, - &out->c); -} - -template<class ObjT, class Method, class InA, class InB, class InC, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<InA, InB, InC>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - &out->a, - &out->b, - &out->c); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<InA, InB, InC, InD>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - &out->a, - &out->b, - &out->c); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<InA, InB, InC, InD, InE>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - &out->a, - &out->b, - &out->c); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, class InF, - class OutA, class OutB, class OutC> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<InA, InB, InC, InD, InE, InF>& in, - Tuple3<OutA, OutB, OutC>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - base::internal::UnwrapTraits<InF>::Unwrap(in.f), - &out->a, - &out->b, - &out->c); -} - -// Dispatchers with 4 out params. - -template<class ObjT, class Method, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(&out->a, &out->b, &out->c, &out->d); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<InA>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, class InA, class InB, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<InA, InB>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, class InA, class InB, class InC, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<InA, InB, InC>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<InA, InB, InC, InD>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<InA, InB, InC, InD, InE>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, class InF, - class OutA, class OutB, class OutC, class OutD> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<InA, InB, InC, InD, InE, InF>& in, - Tuple4<OutA, OutB, OutC, OutD>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - base::internal::UnwrapTraits<InF>::Unwrap(in.f), - &out->a, - &out->b, - &out->c, - &out->d); -} - -// Dispatchers with 5 out params. - -template<class ObjT, class Method, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, class InA, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1<InA>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, class InA, class InB, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2<InA, InB>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, class InA, class InB, class InC, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3<InA, InB, InC>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, class InA, class InB, class InC, class InD, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4<InA, InB, InC, InD>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5<InA, InB, InC, InD, InE>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template<class ObjT, class Method, - class InA, class InB, class InC, class InD, class InE, class InF, - class OutA, class OutB, class OutC, class OutD, class OutE> -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6<InA, InB, InC, InD, InE, InF>& in, - Tuple5<OutA, OutB, OutC, OutD, OutE>* out) { - (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), - base::internal::UnwrapTraits<InB>::Unwrap(in.b), - base::internal::UnwrapTraits<InC>::Unwrap(in.c), - base::internal::UnwrapTraits<InD>::Unwrap(in.d), - base::internal::UnwrapTraits<InE>::Unwrap(in.e), - base::internal::UnwrapTraits<InF>::Unwrap(in.f), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); + const Tuple<InTs...>& in, + Tuple<OutTs...>* out) { + DispatchToMethodImpl(obj, method, in, out, + MakeIndexSequence<sizeof...(InTs)>(), + MakeIndexSequence<sizeof...(OutTs)>()); } #endif // BASE_TUPLE_H__ |