Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: base/tuple.h

Issue 792763002: tuple: further generalize/simplify Tuple implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove NthType; add documentation for get<N>(Tuple&) Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A Tuple is a generic templatized container, similar in concept to std::pair. 5 // A Tuple is a generic templatized container, similar in concept to std::pair
6 // There are classes Tuple0 to Tuple6, cooresponding to the number of elements 6 // and std::tuple. The convenient MakeTuple() function takes any number of
7 // it contains. The convenient MakeTuple() function takes 0 to 6 arguments, 7 // arguments and will construct and return the appropriate Tuple object. The
8 // and will construct and return the appropriate Tuple object. The functions 8 // functions DispatchToMethod and DispatchToFunction take a function pointer or
9 // DispatchToMethod and DispatchToFunction take a function pointer or instance 9 // instance and method pointer, and unpack a tuple into arguments to the call.
10 // and method pointer, and unpack a tuple into arguments to the call.
11 // 10 //
12 // Tuple elements are copied by value, and stored in the tuple. See the unit 11 // Tuple elements are copied by value, and stored in the tuple. See the unit
13 // tests for more details of how/when the values are copied. 12 // tests for more details of how/when the values are copied.
14 // 13 //
15 // Example usage: 14 // Example usage:
16 // // These two methods of creating a Tuple are identical. 15 // // These two methods of creating a Tuple are identical.
17 // Tuple2<int, const char*> tuple_a(1, "wee"); 16 // Tuple<int, const char*> tuple_a(1, "wee");
18 // Tuple2<int, const char*> tuple_b = MakeTuple(1, "wee"); 17 // Tuple<int, const char*> tuple_b = MakeTuple(1, "wee");
19 // 18 //
20 // void SomeFunc(int a, const char* b) { } 19 // void SomeFunc(int a, const char* b) { }
21 // DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") 20 // DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee")
22 // DispatchToFunction( 21 // DispatchToFunction(
23 // &SomeFunc, MakeTuple(10, "foo")); // SomeFunc(10, "foo") 22 // &SomeFunc, MakeTuple(10, "foo")); // SomeFunc(10, "foo")
24 // 23 //
25 // struct { void SomeMeth(int a, int b, int c) { } } foo; 24 // struct { void SomeMeth(int a, int b, int c) { } } foo;
26 // DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3)); 25 // DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3));
27 // // foo->SomeMeth(1, 2, 3); 26 // // foo->SomeMeth(1, 2, 3);
28 27
(...skipping 11 matching lines...) Expand all
40 39
41 template <size_t... Ns> 40 template <size_t... Ns>
42 struct MakeIndexSequenceImpl; 41 struct MakeIndexSequenceImpl;
43 42
44 template <size_t... Ns> 43 template <size_t... Ns>
45 struct MakeIndexSequenceImpl<0, Ns...> { 44 struct MakeIndexSequenceImpl<0, Ns...> {
46 using Type = IndexSequence<Ns...>; 45 using Type = IndexSequence<Ns...>;
47 }; 46 };
48 47
49 template <size_t N, size_t... Ns> 48 template <size_t N, size_t... Ns>
50 struct MakeIndexSequenceImpl<N, Ns...> { 49 struct MakeIndexSequenceImpl<N, Ns...>
51 using Type = typename MakeIndexSequenceImpl<N - 1, N - 1, Ns...>::Type; 50 : MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {};
52 };
53 51
54 template <size_t N> 52 template <size_t N>
55 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; 53 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type;
56 54
57 // Traits ---------------------------------------------------------------------- 55 // Traits ----------------------------------------------------------------------
58 // 56 //
59 // A simple traits class for tuple arguments. 57 // A simple traits class for tuple arguments.
60 // 58 //
61 // ValueType: the bare, nonref version of a type (same as the type for nonrefs). 59 // ValueType: the bare, nonref version of a type (same as the type for nonrefs).
62 // RefType: the ref version of a type (same as the type for refs). 60 // RefType: the ref version of a type (same as the type for refs).
(...skipping 13 matching lines...) Expand all
76 typedef P& ParamType; 74 typedef P& ParamType;
77 }; 75 };
78 76
79 // Tuple ----------------------------------------------------------------------- 77 // Tuple -----------------------------------------------------------------------
80 // 78 //
81 // This set of classes is useful for bundling 0 or more heterogeneous data types 79 // This set of classes is useful for bundling 0 or more heterogeneous data types
82 // into a single variable. The advantage of this is that it greatly simplifies 80 // into a single variable. The advantage of this is that it greatly simplifies
83 // function objects that need to take an arbitrary number of parameters; see 81 // function objects that need to take an arbitrary number of parameters; see
84 // RunnableMethod and IPC::MessageWithTuple. 82 // RunnableMethod and IPC::MessageWithTuple.
85 // 83 //
86 // Tuple0 is supplied to act as a 'void' type. It can be used, for example, 84 // Tuple<> is supplied to act as a 'void' type. It can be used, for example,
87 // when dispatching to a function that accepts no arguments (see the 85 // when dispatching to a function that accepts no arguments (see the
88 // Dispatchers below). 86 // Dispatchers below).
89 // Tuple1<A> is rarely useful. One such use is when A is non-const ref that you 87 // Tuple<A> is rarely useful. One such use is when A is non-const ref that you
90 // want filled by the dispatchee, and the tuple is merely a container for that 88 // want filled by the dispatchee, and the tuple is merely a container for that
91 // output (a "tier"). See MakeRefTuple and its usages. 89 // output (a "tier"). See MakeRefTuple and its usages.
92 90
91 template <typename IxSeq, typename... Ts>
92 struct TupleBaseImpl;
93 template <typename... Ts> 93 template <typename... Ts>
94 struct Tuple; 94 using TupleBase = TupleBaseImpl<MakeIndexSequence<sizeof...(Ts)>, Ts...>;
95 template <size_t N, typename T>
96 struct TupleLeaf;
95 97
98 template <typename... Ts>
99 struct Tuple : TupleBase<Ts...> {
100 Tuple() : TupleBase<Ts...>() {}
101 explicit Tuple(typename TupleTraits<Ts>::ParamType... args)
102 : TupleBase<Ts...>(args...) {}
103 };
104
105 // Avoids ambiguity between Tuple's two constructors.
96 template <> 106 template <>
97 struct Tuple<> {}; 107 struct Tuple<> {};
98 108
99 template <typename A> 109 template <size_t... Ns, typename... Ts>
100 struct Tuple<A> { 110 struct TupleBaseImpl<IndexSequence<Ns...>, Ts...> : TupleLeaf<Ns, Ts>... {
101 public: 111 TupleBaseImpl() : TupleLeaf<Ns, Ts>()... {}
102 typedef A TypeA; 112 explicit TupleBaseImpl(typename TupleTraits<Ts>::ParamType... args)
103 113 : TupleLeaf<Ns, Ts>(args)... {}
104 Tuple() {}
105 explicit Tuple(typename TupleTraits<A>::ParamType a) : a(a) {}
106
107 A a;
108 }; 114 };
109 115
110 template <typename A, typename B> 116 template <size_t N, typename T>
111 struct Tuple<A, B> { 117 struct TupleLeaf {
112 public: 118 TupleLeaf() : x() {}
113 typedef A TypeA; 119 explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {}
114 typedef B TypeB;
115 120
116 Tuple() {} 121 T& get() { return x; }
117 Tuple(typename TupleTraits<A>::ParamType a, 122 const T& get() const { return x; }
118 typename TupleTraits<B>::ParamType b)
119 : a(a), b(b) {}
120 123
121 A a; 124 T x;
122 B b;
123 }; 125 };
124 126
125 template <typename A, typename B, typename C> 127 // For legacy compatibility, we name the first 8 tuple elements "a", "b", ...
126 struct Tuple<A, B, C> { 128 // TODO(mdempsky): Update users to use get<N>() (crbug.com/440675).
127 public:
128 typedef A TypeA;
129 typedef B TypeB;
130 typedef C TypeC;
131 129
132 Tuple() {} 130 #define DEFINE_TUPLE_LEAF(N, x) \
133 Tuple(typename TupleTraits<A>::ParamType a, 131 template <typename T> \
134 typename TupleTraits<B>::ParamType b, 132 struct TupleLeaf<N, T> { \
135 typename TupleTraits<C>::ParamType c) 133 TupleLeaf() : x() {} \
136 : a(a), b(b), c(c) {} 134 explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {} \
135 \
136 T& get() { return x; } \
137 const T& get() const { return x; } \
138 \
139 T x; \
140 }
137 141
138 A a; 142 DEFINE_TUPLE_LEAF(0, a);
139 B b; 143 DEFINE_TUPLE_LEAF(1, b);
140 C c; 144 DEFINE_TUPLE_LEAF(2, c);
141 }; 145 DEFINE_TUPLE_LEAF(3, d);
146 DEFINE_TUPLE_LEAF(4, e);
147 DEFINE_TUPLE_LEAF(5, f);
148 DEFINE_TUPLE_LEAF(6, g);
149 DEFINE_TUPLE_LEAF(7, h);
142 150
143 template <typename A, typename B, typename C, typename D> 151 #undef DEFINE_TUPLE_LEAF
144 struct Tuple<A, B, C, D> {
145 public:
146 typedef A TypeA;
147 typedef B TypeB;
148 typedef C TypeC;
149 typedef D TypeD;
150
151 Tuple() {}
152 Tuple(typename TupleTraits<A>::ParamType a,
153 typename TupleTraits<B>::ParamType b,
154 typename TupleTraits<C>::ParamType c,
155 typename TupleTraits<D>::ParamType d)
156 : a(a), b(b), c(c), d(d) {}
157
158 A a;
159 B b;
160 C c;
161 D d;
162 };
163
164 template <typename A, typename B, typename C, typename D, typename E>
165 struct Tuple<A, B, C, D, E> {
166 public:
167 typedef A TypeA;
168 typedef B TypeB;
169 typedef C TypeC;
170 typedef D TypeD;
171 typedef E TypeE;
172
173 Tuple() {}
174 Tuple(typename TupleTraits<A>::ParamType a,
175 typename TupleTraits<B>::ParamType b,
176 typename TupleTraits<C>::ParamType c,
177 typename TupleTraits<D>::ParamType d,
178 typename TupleTraits<E>::ParamType e)
179 : a(a), b(b), c(c), d(d), e(e) {}
180
181 A a;
182 B b;
183 C c;
184 D d;
185 E e;
186 };
187
188 template <typename A,
189 typename B,
190 typename C,
191 typename D,
192 typename E,
193 typename F>
194 struct Tuple<A, B, C, D, E, F> {
195 public:
196 typedef A TypeA;
197 typedef B TypeB;
198 typedef C TypeC;
199 typedef D TypeD;
200 typedef E TypeE;
201 typedef F TypeF;
202
203 Tuple() {}
204 Tuple(typename TupleTraits<A>::ParamType a,
205 typename TupleTraits<B>::ParamType b,
206 typename TupleTraits<C>::ParamType c,
207 typename TupleTraits<D>::ParamType d,
208 typename TupleTraits<E>::ParamType e,
209 typename TupleTraits<F>::ParamType f)
210 : a(a), b(b), c(c), d(d), e(e), f(f) {}
211
212 A a;
213 B b;
214 C c;
215 D d;
216 E e;
217 F f;
218 };
219
220 template <typename A,
221 typename B,
222 typename C,
223 typename D,
224 typename E,
225 typename F,
226 typename G>
227 struct Tuple<A, B, C, D, E, F, G> {
228 public:
229 typedef A TypeA;
230 typedef B TypeB;
231 typedef C TypeC;
232 typedef D TypeD;
233 typedef E TypeE;
234 typedef F TypeF;
235 typedef G TypeG;
236
237 Tuple() {}
238 Tuple(typename TupleTraits<A>::ParamType a,
239 typename TupleTraits<B>::ParamType b,
240 typename TupleTraits<C>::ParamType c,
241 typename TupleTraits<D>::ParamType d,
242 typename TupleTraits<E>::ParamType e,
243 typename TupleTraits<F>::ParamType f,
244 typename TupleTraits<G>::ParamType g)
245 : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {}
246
247 A a;
248 B b;
249 C c;
250 D d;
251 E e;
252 F f;
253 G g;
254 };
255
256 template <typename A,
257 typename B,
258 typename C,
259 typename D,
260 typename E,
261 typename F,
262 typename G,
263 typename H>
264 struct Tuple<A, B, C, D, E, F, G, H> {
265 public:
266 typedef A TypeA;
267 typedef B TypeB;
268 typedef C TypeC;
269 typedef D TypeD;
270 typedef E TypeE;
271 typedef F TypeF;
272 typedef G TypeG;
273 typedef H TypeH;
274
275 Tuple() {}
276 Tuple(typename TupleTraits<A>::ParamType a,
277 typename TupleTraits<B>::ParamType b,
278 typename TupleTraits<C>::ParamType c,
279 typename TupleTraits<D>::ParamType d,
280 typename TupleTraits<E>::ParamType e,
281 typename TupleTraits<F>::ParamType f,
282 typename TupleTraits<G>::ParamType g,
283 typename TupleTraits<H>::ParamType h)
284 : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {}
285
286 A a;
287 B b;
288 C c;
289 D d;
290 E e;
291 F f;
292 G g;
293 H h;
294 };
295 152
296 // Deprecated compat aliases 153 // Deprecated compat aliases
154 // TODO(mdempsky): Update users to just use Tuple instead (crbug.com/440675).
297 155
298 using Tuple0 = Tuple<>; 156 using Tuple0 = Tuple<>;
299 template <typename A> 157 template <typename A>
300 using Tuple1 = Tuple<A>; 158 using Tuple1 = Tuple<A>;
301 template <typename A, typename B> 159 template <typename A, typename B>
302 using Tuple2 = Tuple<A, B>; 160 using Tuple2 = Tuple<A, B>;
303 template <typename A, typename B, typename C> 161 template <typename A, typename B, typename C>
304 using Tuple3 = Tuple<A, B, C>; 162 using Tuple3 = Tuple<A, B, C>;
305 template <typename A, typename B, typename C, typename D> 163 template <typename A, typename B, typename C, typename D>
306 using Tuple4 = Tuple<A, B, C, D>; 164 using Tuple4 = Tuple<A, B, C, D>;
(...skipping 17 matching lines...) Expand all
324 template <typename A, 182 template <typename A,
325 typename B, 183 typename B,
326 typename C, 184 typename C,
327 typename D, 185 typename D,
328 typename E, 186 typename E,
329 typename F, 187 typename F,
330 typename G, 188 typename G,
331 typename H> 189 typename H>
332 using Tuple8 = Tuple<A, B, C, D, E, F, G, H>; 190 using Tuple8 = Tuple<A, B, C, D, E, F, G, H>;
333 191
334 // Tuple element -------------------------------------------------------------- 192 // Tuple getters --------------------------------------------------------------
193 //
194 // Allows accessing an arbitrary tuple element by index.
195 //
196 // Example usage:
197 // Tuple<int, double> t2;
198 // get<0>(t2) = 42;
199 // get<1>(t2) = 3.14;
335 200
336 template <size_t N, typename T> 201 template <size_t I, typename T>
337 struct TupleElement; 202 T& get(TupleLeaf<I, T>& leaf) {
338 203 return leaf.get();
339 template <typename T, typename... Ts>
340 struct TupleElement<0, Tuple<T, Ts...>> {
341 using Type = T;
342 };
343
344 template <size_t N, typename T, typename... Ts>
345 struct TupleElement<N, Tuple<T, Ts...>> {
346 using Type = typename TupleElement<N - 1, Tuple<Ts...>>::Type;
347 };
348
349 // Tuple getters --------------------------------------------------------------
350
351 template <size_t, typename T>
352 struct TupleGetter;
353
354 template <typename... Ts>
355 struct TupleGetter<0, Tuple<Ts...>> {
356 using Elem = typename TupleElement<0, Tuple<Ts...>>::Type;
357 static Elem& Get(Tuple<Ts...>& t) { return t.a; }
358 static const Elem& Get(const Tuple<Ts...>& t) { return t.a; }
359 };
360
361 template <typename... Ts>
362 struct TupleGetter<1, Tuple<Ts...>> {
363 using Elem = typename TupleElement<1, Tuple<Ts...>>::Type;
364 static Elem& Get(Tuple<Ts...>& t) { return t.b; }
365 static const Elem& Get(const Tuple<Ts...>& t) { return t.b; }
366 };
367
368 template <typename... Ts>
369 struct TupleGetter<2, Tuple<Ts...>> {
370 using Elem = typename TupleElement<2, Tuple<Ts...>>::Type;
371 static Elem& Get(Tuple<Ts...>& t) { return t.c; }
372 static const Elem& Get(const Tuple<Ts...>& t) { return t.c; }
373 };
374
375 template <typename... Ts>
376 struct TupleGetter<3, Tuple<Ts...>> {
377 using Elem = typename TupleElement<3, Tuple<Ts...>>::Type;
378 static Elem& Get(Tuple<Ts...>& t) { return t.d; }
379 static const Elem& Get(const Tuple<Ts...>& t) { return t.d; }
380 };
381
382 template <typename... Ts>
383 struct TupleGetter<4, Tuple<Ts...>> {
384 using Elem = typename TupleElement<4, Tuple<Ts...>>::Type;
385 static Elem& Get(Tuple<Ts...>& t) { return t.e; }
386 static const Elem& Get(const Tuple<Ts...>& t) { return t.e; }
387 };
388
389 template <typename... Ts>
390 struct TupleGetter<5, Tuple<Ts...>> {
391 using Elem = typename TupleElement<5, Tuple<Ts...>>::Type;
392 static Elem& Get(Tuple<Ts...>& t) { return t.f; }
393 static const Elem& Get(const Tuple<Ts...>& t) { return t.f; }
394 };
395
396 template <typename... Ts>
397 struct TupleGetter<6, Tuple<Ts...>> {
398 using Elem = typename TupleElement<6, Tuple<Ts...>>::Type;
399 static Elem& Get(Tuple<Ts...>& t) { return t.g; }
400 static const Elem& Get(const Tuple<Ts...>& t) { return t.g; }
401 };
402
403 template <typename... Ts>
404 struct TupleGetter<7, Tuple<Ts...>> {
405 using Elem = typename TupleElement<7, Tuple<Ts...>>::Type;
406 static Elem& Get(Tuple<Ts...>& t) { return t.h; }
407 static const Elem& Get(const Tuple<Ts...>& t) { return t.h; }
408 };
409
410 template <size_t I, typename... Ts>
411 typename TupleElement<I, Tuple<Ts...>>::Type& get(Tuple<Ts...>& tuple) {
412 return TupleGetter<I, Tuple<Ts...>>::Get(tuple);
413 } 204 }
414 205
415 template <size_t I, typename... Ts> 206 template <size_t I, typename T>
416 const typename TupleElement<I, Tuple<Ts...>>::Type& get( 207 const T& get(const TupleLeaf<I, T>& leaf) {
417 const Tuple<Ts...>& tuple) { 208 return leaf.get();
418 return TupleGetter<I, Tuple<Ts...>>::Get(tuple);
419 } 209 }
420 210
421 // Tuple types ---------------------------------------------------------------- 211 // Tuple types ----------------------------------------------------------------
422 // 212 //
423 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the 213 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the
424 // definitions of class types the tuple takes as parameters. 214 // definitions of class types the tuple takes as parameters.
425 215
426 template <typename T> 216 template <typename T>
427 struct TupleTypes; 217 struct TupleTypes;
428 218
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 inline void DispatchToMethod(ObjT* obj, 336 inline void DispatchToMethod(ObjT* obj,
547 Method method, 337 Method method,
548 const Tuple<InTs...>& in, 338 const Tuple<InTs...>& in,
549 Tuple<OutTs...>* out) { 339 Tuple<OutTs...>* out) {
550 DispatchToMethodImpl(obj, method, in, out, 340 DispatchToMethodImpl(obj, method, in, out,
551 MakeIndexSequence<sizeof...(InTs)>(), 341 MakeIndexSequence<sizeof...(InTs)>(),
552 MakeIndexSequence<sizeof...(OutTs)>()); 342 MakeIndexSequence<sizeof...(OutTs)>());
553 } 343 }
554 344
555 #endif // BASE_TUPLE_H__ 345 #endif // BASE_TUPLE_H__
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698