OLD | NEW |
---|---|
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 Loading... | |
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 : public MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {}; |
tzik
2014/12/10 06:43:27
can we remove "public" since it's default for stru
mdempsky
2014/12/10 07:46:03
Done (here and below).
| |
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 Loading... | |
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 : public TupleBase<Ts...> { | |
100 Tuple() : TupleBase<Ts...>() {} | |
Nico
2014/12/10 07:00:31
Isn't this the same as the constructor in the line
mdempsky
2014/12/10 07:15:23
If I understand your question: "for Tuple<>, would
mdempsky
2014/12/10 07:46:03
(On the chance that issue was the Tuple<> speciali
| |
101 explicit Tuple(typename TupleTraits<Ts>::ParamType... args) | |
102 : TupleBase<Ts...>(args...) {} | |
103 }; | |
104 | |
105 template <size_t... Ns, typename... Ts> | |
106 struct TupleBaseImpl<IndexSequence<Ns...>, Ts...> | |
107 : public TupleLeaf<Ns, Ts>... { | |
108 TupleBaseImpl() : TupleLeaf<Ns, Ts>()... {} | |
Nico
2014/12/10 07:00:31
same question
| |
109 explicit TupleBaseImpl(typename TupleTraits<Ts>::ParamType... args) | |
110 : TupleLeaf<Ns, Ts>(args)... {} | |
111 }; | |
112 | |
113 template <size_t N, typename T> | |
114 struct TupleLeaf { | |
115 TupleLeaf() : x() {} | |
116 explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {} | |
117 | |
118 T& get() { return x; } | |
119 const T& get() const { return x; } | |
120 | |
121 T x; | |
122 }; | |
123 | |
124 // Avoids ambiguity between Tuple's two constructors. | |
96 template <> | 125 template <> |
97 struct Tuple<> {}; | 126 struct Tuple<> {}; |
98 | 127 |
99 template <typename A> | 128 // For legacy compatibility, we name the first 8 tuple elements "a", "b", ... |
Nico
2014/12/10 07:00:31
Does it make sense to remove all clients of this a
mdempsky
2014/12/10 07:46:03
Done.
| |
100 struct Tuple<A> { | |
101 public: | |
102 typedef A TypeA; | |
103 | 129 |
104 Tuple() {} | 130 #define DEFINE_TUPLE_LEAF(N, x) \ |
105 explicit Tuple(typename TupleTraits<A>::ParamType a) : a(a) {} | 131 template <typename T> \ |
132 struct TupleLeaf<N, T> { \ | |
133 TupleLeaf() : x() {} \ | |
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 } | |
106 | 141 |
107 A a; | 142 DEFINE_TUPLE_LEAF(0, a); |
108 }; | 143 DEFINE_TUPLE_LEAF(1, b); |
144 DEFINE_TUPLE_LEAF(2, c); | |
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); | |
109 | 150 |
110 template <typename A, typename B> | 151 #undef DEFINE_TUPLE_LEAF |
111 struct Tuple<A, B> { | |
112 public: | |
113 typedef A TypeA; | |
114 typedef B TypeB; | |
115 | |
116 Tuple() {} | |
117 Tuple(typename TupleTraits<A>::ParamType a, | |
118 typename TupleTraits<B>::ParamType b) | |
119 : a(a), b(b) {} | |
120 | |
121 A a; | |
122 B b; | |
123 }; | |
124 | |
125 template <typename A, typename B, typename C> | |
126 struct Tuple<A, B, C> { | |
127 public: | |
128 typedef A TypeA; | |
129 typedef B TypeB; | |
130 typedef C TypeC; | |
131 | |
132 Tuple() {} | |
133 Tuple(typename TupleTraits<A>::ParamType a, | |
134 typename TupleTraits<B>::ParamType b, | |
135 typename TupleTraits<C>::ParamType c) | |
136 : a(a), b(b), c(c) {} | |
137 | |
138 A a; | |
139 B b; | |
140 C c; | |
141 }; | |
142 | |
143 template <typename A, typename B, typename C, typename D> | |
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 |
297 | 154 |
298 using Tuple0 = Tuple<>; | 155 using Tuple0 = Tuple<>; |
299 template <typename A> | 156 template <typename A> |
300 using Tuple1 = Tuple<A>; | 157 using Tuple1 = Tuple<A>; |
301 template <typename A, typename B> | 158 template <typename A, typename B> |
302 using Tuple2 = Tuple<A, B>; | 159 using Tuple2 = Tuple<A, B>; |
303 template <typename A, typename B, typename C> | 160 template <typename A, typename B, typename C> |
304 using Tuple3 = Tuple<A, B, C>; | 161 using Tuple3 = Tuple<A, B, C>; |
(...skipping 21 matching lines...) Expand all Loading... | |
326 typename C, | 183 typename C, |
327 typename D, | 184 typename D, |
328 typename E, | 185 typename E, |
329 typename F, | 186 typename F, |
330 typename G, | 187 typename G, |
331 typename H> | 188 typename H> |
332 using Tuple8 = Tuple<A, B, C, D, E, F, G, H>; | 189 using Tuple8 = Tuple<A, B, C, D, E, F, G, H>; |
333 | 190 |
334 // Tuple element -------------------------------------------------------------- | 191 // Tuple element -------------------------------------------------------------- |
335 | 192 |
336 template <size_t N, typename T> | 193 template <size_t N, typename... Ts> |
337 struct TupleElement; | 194 struct NthType; |
338 | 195 |
339 template <typename T, typename... Ts> | 196 template <typename T, typename... Ts> |
340 struct TupleElement<0, Tuple<T, Ts...>> { | 197 struct NthType<0, T, Ts...> { |
341 using Type = T; | 198 using Type = T; |
342 }; | 199 }; |
343 | 200 |
344 template <size_t N, typename T, typename... Ts> | 201 template <size_t N, typename T, typename... Ts> |
345 struct TupleElement<N, Tuple<T, Ts...>> { | 202 struct NthType<N, T, Ts...> : public NthType<N - 1, Ts...> {}; |
346 using Type = typename TupleElement<N - 1, Tuple<Ts...>>::Type; | |
347 }; | |
348 | 203 |
349 // Tuple getters -------------------------------------------------------------- | 204 // Tuple getters -------------------------------------------------------------- |
350 | 205 |
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> | 206 template <size_t I, typename... Ts> |
411 typename TupleElement<I, Tuple<Ts...>>::Type& get(Tuple<Ts...>& tuple) { | 207 typename NthType<I, Ts...>::Type& get(Tuple<Ts...>& tuple) { |
tzik
2014/12/10 06:43:27
If it works, how about matching the tuple against
mdempsky
2014/12/10 07:46:03
Nice, seems to work, and means NthType isn't neede
| |
412 return TupleGetter<I, Tuple<Ts...>>::Get(tuple); | 208 using Elem = typename NthType<I, Ts...>::Type; |
209 return static_cast<TupleLeaf<I, Elem>&>(tuple).get(); | |
413 } | 210 } |
414 | 211 |
415 template <size_t I, typename... Ts> | 212 template <size_t I, typename... Ts> |
416 const typename TupleElement<I, Tuple<Ts...>>::Type& get( | 213 const typename NthType<I, Ts...>::Type& get(const Tuple<Ts...>& tuple) { |
417 const Tuple<Ts...>& tuple) { | 214 using Elem = typename NthType<I, Ts...>::Type; |
418 return TupleGetter<I, Tuple<Ts...>>::Get(tuple); | 215 return static_cast<const TupleLeaf<I, Elem>&>(tuple).get(); |
419 } | 216 } |
420 | 217 |
421 // Tuple types ---------------------------------------------------------------- | 218 // Tuple types ---------------------------------------------------------------- |
422 // | 219 // |
423 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the | 220 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the |
424 // definitions of class types the tuple takes as parameters. | 221 // definitions of class types the tuple takes as parameters. |
425 | 222 |
426 template <typename T> | 223 template <typename T> |
427 struct TupleTypes; | 224 struct TupleTypes; |
428 | 225 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 inline void DispatchToMethod(ObjT* obj, | 343 inline void DispatchToMethod(ObjT* obj, |
547 Method method, | 344 Method method, |
548 const Tuple<InTs...>& in, | 345 const Tuple<InTs...>& in, |
549 Tuple<OutTs...>* out) { | 346 Tuple<OutTs...>* out) { |
550 DispatchToMethodImpl(obj, method, in, out, | 347 DispatchToMethodImpl(obj, method, in, out, |
551 MakeIndexSequence<sizeof...(InTs)>(), | 348 MakeIndexSequence<sizeof...(InTs)>(), |
552 MakeIndexSequence<sizeof...(OutTs)>()); | 349 MakeIndexSequence<sizeof...(OutTs)>()); |
553 } | 350 } |
554 | 351 |
555 #endif // BASE_TUPLE_H__ | 352 #endif // BASE_TUPLE_H__ |
OLD | NEW |