From 6e7f615f49056439312aad3fcdd2284e2bd69647 Mon Sep 17 00:00:00 2001 From: mdempsky Date: Tue, 9 Dec 2014 19:10:59 -0800 Subject: 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(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} --- base/tuple.h | 1336 +++++++++++++--------------------------------------------- 1 file 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 +struct IndexSequence {}; + +template +struct MakeIndexSequenceImpl; + +template +struct MakeIndexSequenceImpl<0, Ns...> { + using Type = IndexSequence; +}; + +template +struct MakeIndexSequenceImpl { + using Type = typename MakeIndexSequenceImpl::Type; +}; + +template +using MakeIndexSequence = typename MakeIndexSequenceImpl::Type; + // Traits ---------------------------------------------------------------------- // // A simple traits class for tuple arguments. @@ -53,9 +76,6 @@ struct TupleTraits { typedef P& ParamType; }; -template -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 +struct Tuple; -template -struct Tuple1 { +template <> +struct Tuple<> {}; + +template +struct Tuple { public: typedef A TypeA; - Tuple1() {} - explicit Tuple1(typename TupleTraits::ParamType a) : a(a) {} + Tuple() {} + explicit Tuple(typename TupleTraits::ParamType a) : a(a) {} A a; }; -template -struct Tuple2 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; - Tuple2() {} - Tuple2(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b) - : a(a), b(b) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b) + : a(a), b(b) {} A a; B b; }; -template -struct Tuple3 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; typedef C TypeC; - Tuple3() {} - Tuple3(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c) - : a(a), b(b), c(c){ - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c) + : a(a), b(b), c(c) {} A a; B b; C c; }; -template -struct Tuple4 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; typedef C TypeC; typedef D TypeD; - Tuple4() {} - Tuple4(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c, - typename TupleTraits::ParamType d) - : a(a), b(b), c(c), d(d) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d) + : a(a), b(b), c(c), d(d) {} A a; B b; @@ -144,8 +161,8 @@ struct Tuple4 { D d; }; -template -struct Tuple5 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; @@ -153,14 +170,13 @@ struct Tuple5 { typedef D TypeD; typedef E TypeE; - Tuple5() {} - Tuple5(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c, - typename TupleTraits::ParamType d, - typename TupleTraits::ParamType e) - : a(a), b(b), c(c), d(d), e(e) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::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 -struct Tuple6 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; @@ -179,15 +200,14 @@ struct Tuple6 { typedef E TypeE; typedef F TypeF; - Tuple6() {} - Tuple6(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c, - typename TupleTraits::ParamType d, - typename TupleTraits::ParamType e, - typename TupleTraits::ParamType f) - : a(a), b(b), c(c), d(d), e(e), f(f) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::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 -struct Tuple7 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; @@ -208,16 +234,15 @@ struct Tuple7 { typedef F TypeF; typedef G TypeG; - Tuple7() {} - Tuple7(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c, - typename TupleTraits::ParamType d, - typename TupleTraits::ParamType e, - typename TupleTraits::ParamType f, - typename TupleTraits::ParamType g) - : a(a), b(b), c(c), d(d), e(e), f(f), g(g) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::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 -struct Tuple8 { +template +struct Tuple { public: typedef A TypeA; typedef B TypeB; @@ -241,17 +272,16 @@ struct Tuple8 { typedef G TypeG; typedef H TypeH; - Tuple8() {} - Tuple8(typename TupleTraits::ParamType a, - typename TupleTraits::ParamType b, - typename TupleTraits::ParamType c, - typename TupleTraits::ParamType d, - typename TupleTraits::ParamType e, - typename TupleTraits::ParamType f, - typename TupleTraits::ParamType g, - typename TupleTraits::ParamType h) - : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) { - } + Tuple() {} + Tuple(typename TupleTraits::ParamType a, + typename TupleTraits::ParamType b, + typename TupleTraits::ParamType c, + typename TupleTraits::ParamType d, + typename TupleTraits::ParamType e, + typename TupleTraits::ParamType f, + typename TupleTraits::ParamType g, + typename TupleTraits::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 +using Tuple1 = Tuple; +template +using Tuple2 = Tuple; +template +using Tuple3 = Tuple; +template +using Tuple4 = Tuple; +template +using Tuple5 = Tuple; +template +using Tuple6 = Tuple; +template +using Tuple7 = Tuple; +template +using Tuple8 = Tuple; + +// Tuple element -------------------------------------------------------------- + +template +struct TupleElement; + +template +struct TupleElement<0, Tuple> { + using Type = T; }; -template -struct TupleTypes< Tuple1 > { - typedef Tuple1::ValueType> ValueTuple; - typedef Tuple1::RefType> RefTuple; - typedef Tuple1::ParamType> ParamTuple; +template +struct TupleElement> { + using Type = typename TupleElement>::Type; }; -template -struct TupleTypes< Tuple2 > { - typedef Tuple2::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple2::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple2::ParamType, - typename TupleTraits::ParamType> ParamTuple; -}; +// Tuple getters -------------------------------------------------------------- -template -struct TupleTypes< Tuple3 > { - typedef Tuple3::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple3::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple3::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; -}; +template +struct TupleGetter; -template -struct TupleTypes< Tuple4 > { - typedef Tuple4::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple4::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple4::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; +template +struct TupleGetter<0, Tuple> { + using Elem = typename TupleElement<0, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.a; } + static const Elem& Get(const Tuple& t) { return t.a; } }; -template -struct TupleTypes< Tuple5 > { - typedef Tuple5::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple5::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple5::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; +template +struct TupleGetter<1, Tuple> { + using Elem = typename TupleElement<1, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.b; } + static const Elem& Get(const Tuple& t) { return t.b; } }; -template -struct TupleTypes< Tuple6 > { - typedef Tuple6::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple6::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple6::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; +template +struct TupleGetter<2, Tuple> { + using Elem = typename TupleElement<2, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.c; } + static const Elem& Get(const Tuple& t) { return t.c; } }; -template -struct TupleTypes< Tuple7 > { - typedef Tuple7::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple7::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple7::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; +template +struct TupleGetter<3, Tuple> { + using Elem = typename TupleElement<3, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.d; } + static const Elem& Get(const Tuple& t) { return t.d; } }; -template -struct TupleTypes< Tuple8 > { - typedef Tuple8::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType, - typename TupleTraits::ValueType> ValueTuple; -typedef Tuple8::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType, - typename TupleTraits::RefType> RefTuple; - typedef Tuple8::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType, - typename TupleTraits::ParamType> ParamTuple; +template +struct TupleGetter<4, Tuple> { + using Elem = typename TupleElement<4, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.e; } + static const Elem& Get(const Tuple& t) { return t.e; } }; -// Tuple creators ------------------------------------------------------------- -// -// Helper functions for constructing tuples while inferring the template -// argument types. +template +struct TupleGetter<5, Tuple> { + using Elem = typename TupleElement<5, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.f; } + static const Elem& Get(const Tuple& t) { return t.f; } +}; -inline Tuple0 MakeTuple() { - return Tuple0(); -} +template +struct TupleGetter<6, Tuple> { + using Elem = typename TupleElement<6, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.g; } + static const Elem& Get(const Tuple& t) { return t.g; } +}; -template -inline Tuple1 MakeTuple(const A& a) { - return Tuple1(a); -} +template +struct TupleGetter<7, Tuple> { + using Elem = typename TupleElement<7, Tuple>::Type; + static Elem& Get(Tuple& t) { return t.h; } + static const Elem& Get(const Tuple& t) { return t.h; } +}; -template -inline Tuple2 MakeTuple(const A& a, const B& b) { - return Tuple2(a, b); +template +typename TupleElement>::Type& get(Tuple& tuple) { + return TupleGetter>::Get(tuple); } -template -inline Tuple3 MakeTuple(const A& a, const B& b, const C& c) { - return Tuple3(a, b, c); +template +const typename TupleElement>::Type& get( + const Tuple& tuple) { + return TupleGetter>::Get(tuple); } -template -inline Tuple4 MakeTuple(const A& a, const B& b, const C& c, - const D& d) { - return Tuple4(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 -inline Tuple5 MakeTuple(const A& a, const B& b, const C& c, - const D& d, const E& e) { - return Tuple5(a, b, c, d, e); -} +template +struct TupleTypes; -template -inline Tuple6 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); -} +template +struct TupleTypes> { + using ValueTuple = Tuple::ValueType...>; + using RefTuple = Tuple::RefType...>; + using ParamTuple = Tuple::ParamType...>; +}; -template -inline Tuple7 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); -} +// Tuple creators ------------------------------------------------------------- +// +// Helper functions for constructing tuples while inferring the template +// argument types. -template -inline Tuple8 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); +template +inline Tuple MakeTuple(const Ts&... arg) { + return Tuple(arg...); } // The following set of helpers make what Boost refers to as "Tiers" - a tuple // of references. -template -inline Tuple1 MakeRefTuple(A& a) { - return Tuple1(a); -} - -template -inline Tuple2 MakeRefTuple(A& a, B& b) { - return Tuple2(a, b); -} - -template -inline Tuple3 MakeRefTuple(A& a, B& b, C& c) { - return Tuple3(a, b, c); -} - -template -inline Tuple4 MakeRefTuple(A& a, B& b, C& c, D& d) { - return Tuple4(a, b, c, d); -} - -template -inline Tuple5 MakeRefTuple(A& a, B& b, C& c, D& d, E& e) { - return Tuple5(a, b, c, d, e); -} - -template -inline Tuple6 MakeRefTuple(A& a, B& b, C& c, D& d, E& e, - F& f) { - return Tuple6(a, b, c, d, e, f); -} - -template -inline Tuple7 MakeRefTuple(A& a, B& b, C& c, D& d, - E& e, F& f, G& g) { - return Tuple7(a, b, c, d, e, f, g); -} - -template -inline Tuple8 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); +template +inline Tuple MakeRefTuple(Ts&... arg) { + return Tuple(arg...); } // Dispatchers ---------------------------------------------------------------- @@ -533,759 +462,94 @@ inline Tuple8 MakeRefTuple(A& a, B& b, C& c, // Non-Static Dispatchers with no out params. -template -inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) { - (obj->*method)(); -} - -template +template inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) { (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg)); } -template -inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a)); +template +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const Tuple& arg, + IndexSequence) { + (obj->*method)(base::internal::UnwrapTraits::Unwrap(get(arg))...); } -template +template inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple7& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f), - base::internal::UnwrapTraits::Unwrap(arg.g)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple8& arg) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f), - base::internal::UnwrapTraits::Unwrap(arg.g), - base::internal::UnwrapTraits::Unwrap(arg.h)); + const Tuple& arg) { + DispatchToMethodImpl(obj, method, arg, MakeIndexSequence()); } // Static Dispatchers with no out params. -template -inline void DispatchToFunction(Function function, const Tuple0& arg) { - (*function)(); -} - -template -inline void DispatchToFunction(Function function, const A& arg) { - (*function)(arg); -} - -template -inline void DispatchToFunction(Function function, const Tuple1& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a)); +template +inline void DispatchToMethod(Function function, const A& arg) { + (*function)(base::internal::UnwrapTraits::Unwrap(arg)); } -template -inline void DispatchToFunction(Function function, const Tuple2& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b)); +template +inline void DispatchToFunctionImpl(Function function, + const Tuple& arg, + IndexSequence) { + (*function)(base::internal::UnwrapTraits::Unwrap(get(arg))...); } -template -inline void DispatchToFunction(Function function, const Tuple3& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c)); +template +inline void DispatchToFunction(Function function, const Tuple& arg) { + DispatchToFunctionImpl(function, arg, MakeIndexSequence()); } -template -inline void DispatchToFunction(Function function, - const Tuple4& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d)); -} - -template -inline void DispatchToFunction(Function function, - const Tuple5& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e)); -} +// Dispatchers with out parameters. -template -inline void DispatchToFunction(Function function, - const Tuple6& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f)); +template +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const In& in, + Tuple* out, + IndexSequence) { + (obj->*method)(base::internal::UnwrapTraits::Unwrap(in), + &get(*out)...); } -template -inline void DispatchToFunction(Function function, - const Tuple7& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f), - base::internal::UnwrapTraits::Unwrap(arg.g)); -} - -template -inline void DispatchToFunction(Function function, - const Tuple8& arg) { - (*function)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f), - base::internal::UnwrapTraits::Unwrap(arg.g), - base::internal::UnwrapTraits::Unwrap(arg.h)); -} - -// Dispatchers with 0 out param (as a Tuple0). - -template +template inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& arg, Tuple0*) { - (obj->*method)(); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg)); -} - -template -inline void DispatchToMethod(ObjT* obj, - Method method, - const Tuple1& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a)); -} - -template + const In& in, + Tuple* out) { + DispatchToMethodImpl(obj, method, in, out, + MakeIndexSequence()); +} + +template +inline void DispatchToMethodImpl(ObjT* obj, + Method method, + const Tuple& in, + Tuple* out, + IndexSequence, + IndexSequence) { + (obj->*method)(base::internal::UnwrapTraits::Unwrap(get(in))..., + &get(*out)...); +} + +template inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e)); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& arg, Tuple0*) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(arg.a), - base::internal::UnwrapTraits::Unwrap(arg.b), - base::internal::UnwrapTraits::Unwrap(arg.c), - base::internal::UnwrapTraits::Unwrap(arg.d), - base::internal::UnwrapTraits::Unwrap(arg.e), - base::internal::UnwrapTraits::Unwrap(arg.f)); -} - -// Dispatchers with 1 out param. - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple1* out) { - (obj->*method)(&out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple1* out) { - (obj->*method)(in, &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - &out->a); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& in, - Tuple1* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - base::internal::UnwrapTraits::Unwrap(in.f), - &out->a); -} - -// Dispatchers with 2 out params. - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple2* out) { - (obj->*method)(&out->a, &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple2* out) { - (obj->*method)(in, &out->a, &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1& in, - Tuple2* out) { - (obj->*method)( - base::internal::UnwrapTraits::Unwrap(in.a), &out->a, &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& in, - Tuple2* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - &out->a, - &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& in, - Tuple2* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - &out->a, - &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& in, - Tuple2* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - &out->a, - &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& in, - Tuple2* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - &out->a, - &out->b); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& in, - Tuple2* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - base::internal::UnwrapTraits::Unwrap(in.f), - &out->a, - &out->b); -} - -// Dispatchers with 3 out params. - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple3* out) { - (obj->*method)(&out->a, &out->b, &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple3* out) { - (obj->*method)(in, &out->a, &out->b, &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - &out->a, - &out->b, - &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - &out->a, - &out->b, - &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - &out->a, - &out->b, - &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - &out->a, - &out->b, - &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - &out->a, - &out->b, - &out->c); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& in, - Tuple3* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - base::internal::UnwrapTraits::Unwrap(in.f), - &out->a, - &out->b, - &out->c); -} - -// Dispatchers with 4 out params. - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple4* out) { - (obj->*method)(&out->a, &out->b, &out->c, &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - &out->a, - &out->b, - &out->c, - &out->d); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& in, - Tuple4* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - base::internal::UnwrapTraits::Unwrap(in.f), - &out->a, - &out->b, - &out->c, - &out->d); -} - -// Dispatchers with 5 out params. - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple0& in, - Tuple5* out) { - (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const InA& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple1& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple2& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple3& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple4& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple5& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); -} - -template -inline void DispatchToMethod(ObjT* obj, Method method, - const Tuple6& in, - Tuple5* out) { - (obj->*method)(base::internal::UnwrapTraits::Unwrap(in.a), - base::internal::UnwrapTraits::Unwrap(in.b), - base::internal::UnwrapTraits::Unwrap(in.c), - base::internal::UnwrapTraits::Unwrap(in.d), - base::internal::UnwrapTraits::Unwrap(in.e), - base::internal::UnwrapTraits::Unwrap(in.f), - &out->a, - &out->b, - &out->c, - &out->d, - &out->e); + const Tuple& in, + Tuple* out) { + DispatchToMethodImpl(obj, method, in, out, + MakeIndexSequence(), + MakeIndexSequence()); } #endif // BASE_TUPLE_H__ -- cgit v1.1