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 // and std::tuple. The convenient MakeTuple() function takes any number of | 6 // and std::tuple. The convenient MakeTuple() function takes any number of |
7 // arguments and will construct and return the appropriate Tuple object. The | 7 // arguments and will construct and return the appropriate Tuple object. The |
8 // functions DispatchToMethod and DispatchToFunction take a function pointer or | 8 // functions DispatchToMethod and DispatchToFunction take a function pointer or |
9 // instance and method pointer, and unpack a tuple into arguments to the call. | 9 // instance and method pointer, and unpack a tuple into arguments to the call. |
10 // | 10 // |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 // | 234 // |
235 // Helper functions that call the given method on an object, with the unpacked | 235 // Helper functions that call the given method on an object, with the unpacked |
236 // tuple arguments. Notice that they all have the same number of arguments, | 236 // tuple arguments. Notice that they all have the same number of arguments, |
237 // so you need only write: | 237 // so you need only write: |
238 // DispatchToMethod(object, &Object::method, args); | 238 // DispatchToMethod(object, &Object::method, args); |
239 // This is very useful for templated dispatchers, since they don't need to know | 239 // This is very useful for templated dispatchers, since they don't need to know |
240 // what type |args| is. | 240 // what type |args| is. |
241 | 241 |
242 // Non-Static Dispatchers with no out params. | 242 // Non-Static Dispatchers with no out params. |
243 | 243 |
244 template <typename ObjT, typename Method, typename A> | |
245 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) { | |
246 (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg)); | |
247 } | |
248 | |
249 template <typename ObjT, typename Method, typename... Ts, size_t... Ns> | 244 template <typename ObjT, typename Method, typename... Ts, size_t... Ns> |
250 inline void DispatchToMethodImpl(ObjT* obj, | 245 inline void DispatchToMethodImpl(ObjT* obj, |
251 Method method, | 246 Method method, |
252 const Tuple<Ts...>& arg, | 247 const Tuple<Ts...>& arg, |
253 IndexSequence<Ns...>) { | 248 IndexSequence<Ns...>) { |
254 (obj->*method)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); | 249 (obj->*method)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); |
255 } | 250 } |
256 | 251 |
257 template <typename ObjT, typename Method, typename... Ts> | 252 template <typename ObjT, typename Method, typename... Ts> |
258 inline void DispatchToMethod(ObjT* obj, | 253 inline void DispatchToMethod(ObjT* obj, |
259 Method method, | 254 Method method, |
260 const Tuple<Ts...>& arg) { | 255 const Tuple<Ts...>& arg) { |
261 DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>()); | 256 DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>()); |
262 } | 257 } |
263 | 258 |
264 // Static Dispatchers with no out params. | 259 // Static Dispatchers with no out params. |
265 | 260 |
266 template <typename Function, typename A> | |
267 inline void DispatchToMethod(Function function, const A& arg) { | |
268 (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg)); | |
269 } | |
270 | |
271 template <typename Function, typename... Ts, size_t... Ns> | 261 template <typename Function, typename... Ts, size_t... Ns> |
272 inline void DispatchToFunctionImpl(Function function, | 262 inline void DispatchToFunctionImpl(Function function, |
273 const Tuple<Ts...>& arg, | 263 const Tuple<Ts...>& arg, |
274 IndexSequence<Ns...>) { | 264 IndexSequence<Ns...>) { |
275 (*function)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); | 265 (*function)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); |
276 } | 266 } |
277 | 267 |
278 template <typename Function, typename... Ts> | 268 template <typename Function, typename... Ts> |
279 inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) { | 269 inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) { |
280 DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>()); | 270 DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>()); |
281 } | 271 } |
282 | 272 |
283 // Dispatchers with out parameters. | 273 // Dispatchers with out parameters. |
284 | 274 |
285 template <typename ObjT, | 275 template <typename ObjT, |
286 typename Method, | 276 typename Method, |
287 typename In, | |
288 typename... OutTs, | |
289 size_t... OutNs> | |
290 inline void DispatchToMethodImpl(ObjT* obj, | |
291 Method method, | |
292 const In& in, | |
293 Tuple<OutTs...>* out, | |
294 IndexSequence<OutNs...>) { | |
295 (obj->*method)(base::internal::UnwrapTraits<In>::Unwrap(in), | |
296 &get<OutNs>(*out)...); | |
297 } | |
298 | |
299 template <typename ObjT, typename Method, typename In, typename... OutTs> | |
300 inline void DispatchToMethod(ObjT* obj, | |
301 Method method, | |
302 const In& in, | |
303 Tuple<OutTs...>* out) { | |
304 DispatchToMethodImpl(obj, method, in, out, | |
305 MakeIndexSequence<sizeof...(OutTs)>()); | |
306 } | |
307 | |
308 template <typename ObjT, | |
309 typename Method, | |
310 typename... InTs, | 277 typename... InTs, |
311 typename... OutTs, | 278 typename... OutTs, |
312 size_t... InNs, | 279 size_t... InNs, |
313 size_t... OutNs> | 280 size_t... OutNs> |
314 inline void DispatchToMethodImpl(ObjT* obj, | 281 inline void DispatchToMethodImpl(ObjT* obj, |
315 Method method, | 282 Method method, |
316 const Tuple<InTs...>& in, | 283 const Tuple<InTs...>& in, |
317 Tuple<OutTs...>* out, | 284 Tuple<OutTs...>* out, |
318 IndexSequence<InNs...>, | 285 IndexSequence<InNs...>, |
319 IndexSequence<OutNs...>) { | 286 IndexSequence<OutNs...>) { |
320 (obj->*method)(base::internal::UnwrapTraits<InTs>::Unwrap(get<InNs>(in))..., | 287 (obj->*method)(base::internal::UnwrapTraits<InTs>::Unwrap(get<InNs>(in))..., |
321 &get<OutNs>(*out)...); | 288 &get<OutNs>(*out)...); |
322 } | 289 } |
323 | 290 |
324 template <typename ObjT, typename Method, typename... InTs, typename... OutTs> | 291 template <typename ObjT, typename Method, typename... InTs, typename... OutTs> |
325 inline void DispatchToMethod(ObjT* obj, | 292 inline void DispatchToMethod(ObjT* obj, |
326 Method method, | 293 Method method, |
327 const Tuple<InTs...>& in, | 294 const Tuple<InTs...>& in, |
328 Tuple<OutTs...>* out) { | 295 Tuple<OutTs...>* out) { |
329 DispatchToMethodImpl(obj, method, in, out, | 296 DispatchToMethodImpl(obj, method, in, out, |
330 MakeIndexSequence<sizeof...(InTs)>(), | 297 MakeIndexSequence<sizeof...(InTs)>(), |
331 MakeIndexSequence<sizeof...(OutTs)>()); | 298 MakeIndexSequence<sizeof...(OutTs)>()); |
332 } | 299 } |
333 | 300 |
334 } // namespace base | 301 } // namespace base |
335 | 302 |
336 #endif // BASE_TUPLE_H_ | 303 #endif // BASE_TUPLE_H_ |
OLD | NEW |