| // 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_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_ |