|  | // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Use std::tuple as tuple type. This file contains helper functions for | 
|  | // working with std::tuples. | 
|  | // The functions DispatchToMethod and DispatchToFunction take a function pointer | 
|  | // or instance and method pointer, and unpack a tuple into arguments to the | 
|  | // call. | 
|  | // | 
|  | // Example usage: | 
|  | //   // These two methods of creating a Tuple are identical. | 
|  | //   std::tuple<int, const char*> tuple_a(1, "wee"); | 
|  | //   std::tuple<int, const char*> tuple_b = std::make_tuple(1, "wee"); | 
|  | // | 
|  | //   void SomeFunc(int a, const char* b) { } | 
|  | //   DispatchToFunction(&SomeFunc, tuple_a);  // SomeFunc(1, "wee") | 
|  | //   DispatchToFunction( | 
|  | //       &SomeFunc, std::make_tuple(10, "foo"));    // SomeFunc(10, "foo") | 
|  | // | 
|  | //   struct { void SomeMeth(int a, int b, int c) { } } foo; | 
|  | //   DispatchToMethod(&foo, &Foo::SomeMeth, std::make_tuple(1, 2, 3)); | 
|  | //   // foo->SomeMeth(1, 2, 3); | 
|  |  | 
|  | #ifndef BASE_TUPLE_H_ | 
|  | #define BASE_TUPLE_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <tuple> | 
|  | #include <utility> | 
|  |  | 
|  | #include "build/build_config.h" | 
|  |  | 
|  | namespace base { | 
|  |  | 
|  | // Dispatchers ---------------------------------------------------------------- | 
|  | // | 
|  | // Helper functions that call the given method on an object, with the unpacked | 
|  | // tuple arguments.  Notice that they all have the same number of arguments, | 
|  | // so you need only write: | 
|  | //   DispatchToMethod(object, &Object::method, args); | 
|  | // This is very useful for templated dispatchers, since they don't need to know | 
|  | // what type |args| is. | 
|  |  | 
|  | // Non-Static Dispatchers with no out params. | 
|  |  | 
|  | template <typename ObjT, typename Method, typename Tuple, size_t... Ns> | 
|  | inline void DispatchToMethodImpl(const ObjT& obj, | 
|  | Method method, | 
|  | Tuple&& args, | 
|  | std::index_sequence<Ns...>) { | 
|  | (obj->*method)(std::get<Ns>(std::forward<Tuple>(args))...); | 
|  | } | 
|  |  | 
|  | template <typename ObjT, typename Method, typename Tuple> | 
|  | inline void DispatchToMethod(const ObjT& obj, | 
|  | Method method, | 
|  | Tuple&& args) { | 
|  | constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value; | 
|  | DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), | 
|  | std::make_index_sequence<size>()); | 
|  | } | 
|  |  | 
|  | // Static Dispatchers with no out params. | 
|  |  | 
|  | template <typename Function, typename Tuple, size_t... Ns> | 
|  | inline void DispatchToFunctionImpl(Function function, | 
|  | Tuple&& args, | 
|  | std::index_sequence<Ns...>) { | 
|  | (*function)(std::get<Ns>(std::forward<Tuple>(args))...); | 
|  | } | 
|  |  | 
|  | template <typename Function, typename Tuple> | 
|  | inline void DispatchToFunction(Function function, Tuple&& args) { | 
|  | constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value; | 
|  | DispatchToFunctionImpl(function, std::forward<Tuple>(args), | 
|  | std::make_index_sequence<size>()); | 
|  | } | 
|  |  | 
|  | // Dispatchers with out parameters. | 
|  |  | 
|  | template <typename ObjT, | 
|  | typename Method, | 
|  | typename InTuple, | 
|  | typename OutTuple, | 
|  | size_t... InNs, | 
|  | size_t... OutNs> | 
|  | inline void DispatchToMethodImpl(const ObjT& obj, | 
|  | Method method, | 
|  | InTuple&& in, | 
|  | OutTuple* out, | 
|  | std::index_sequence<InNs...>, | 
|  | std::index_sequence<OutNs...>) { | 
|  | (obj->*method)(std::get<InNs>(std::forward<InTuple>(in))..., | 
|  | &std::get<OutNs>(*out)...); | 
|  | } | 
|  |  | 
|  | template <typename ObjT, typename Method, typename InTuple, typename OutTuple> | 
|  | inline void DispatchToMethod(const ObjT& obj, | 
|  | Method method, | 
|  | InTuple&& in, | 
|  | OutTuple* out) { | 
|  | constexpr size_t in_size = std::tuple_size<std::decay_t<InTuple>>::value; | 
|  | constexpr size_t out_size = std::tuple_size<OutTuple>::value; | 
|  | DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out, | 
|  | std::make_index_sequence<in_size>(), | 
|  | std::make_index_sequence<out_size>()); | 
|  | } | 
|  |  | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_TUPLE_H_ |