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 3 // found in the LICENSE file. 4 5 // Use std::tuple as tuple type. This file contains helper functions for 6 // working with std::tuples. 7 // The functions DispatchToMethod and DispatchToFunction take a function pointer 8 // or instance and method pointer, and unpack a tuple into arguments to the 9 // call. 10 // 11 // Example usage: 12 // // These two methods of creating a Tuple are identical. 13 // std::tuple<int, const char*> tuple_a(1, "wee"); 14 // std::tuple<int, const char*> tuple_b = std::make_tuple(1, "wee"); 15 // 16 // void SomeFunc(int a, const char* b) { } 17 // DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") 18 // DispatchToFunction( 19 // &SomeFunc, std::make_tuple(10, "foo")); // SomeFunc(10, "foo") 20 // 21 // struct { void SomeMeth(int a, int b, int c) { } } foo; 22 // DispatchToMethod(&foo, &Foo::SomeMeth, std::make_tuple(1, 2, 3)); 23 // // foo->SomeMeth(1, 2, 3); 24 25 #ifndef BASE_TUPLE_H_ 26 #define BASE_TUPLE_H_ 27 28 #include <stddef.h> 29 #include <tuple> 30 #include <utility> 31 32 #include "build/build_config.h" 33 34 namespace base { 35 36 // Dispatchers ---------------------------------------------------------------- 37 // 38 // Helper functions that call the given method on an object, with the unpacked 39 // tuple arguments. Notice that they all have the same number of arguments, 40 // so you need only write: 41 // DispatchToMethod(object, &Object::method, args); 42 // This is very useful for templated dispatchers, since they don't need to know 43 // what type |args| is. 44 45 // Non-Static Dispatchers with no out params. 46 47 template <typename ObjT, typename Method, typename Tuple, size_t... Ns> 48 inline void DispatchToMethodImpl(const ObjT& obj, 49 Method method, 50 Tuple&& args, 51 std::index_sequence<Ns...>) { 52 (obj->*method)(std::get<Ns>(std::forward<Tuple>(args))...); 53 } 54 55 template <typename ObjT, typename Method, typename Tuple> 56 inline void DispatchToMethod(const ObjT& obj, 57 Method method, 58 Tuple&& args) { 59 constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value; 60 DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), 61 std::make_index_sequence<size>()); 62 } 63 64 // Static Dispatchers with no out params. 65 66 template <typename Function, typename Tuple, size_t... Ns> 67 inline void DispatchToFunctionImpl(Function function, 68 Tuple&& args, 69 std::index_sequence<Ns...>) { 70 (*function)(std::get<Ns>(std::forward<Tuple>(args))...); 71 } 72 73 template <typename Function, typename Tuple> 74 inline void DispatchToFunction(Function function, Tuple&& args) { 75 constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value; 76 DispatchToFunctionImpl(function, std::forward<Tuple>(args), 77 std::make_index_sequence<size>()); 78 } 79 80 // Dispatchers with out parameters. 81 82 template <typename ObjT, 83 typename Method, 84 typename InTuple, 85 typename OutTuple, 86 size_t... InNs, 87 size_t... OutNs> 88 inline void DispatchToMethodImpl(const ObjT& obj, 89 Method method, 90 InTuple&& in, 91 OutTuple* out, 92 std::index_sequence<InNs...>, 93 std::index_sequence<OutNs...>) { 94 (obj->*method)(std::get<InNs>(std::forward<InTuple>(in))..., 95 &std::get<OutNs>(*out)...); 96 } 97 98 template <typename ObjT, typename Method, typename InTuple, typename OutTuple> 99 inline void DispatchToMethod(const ObjT& obj, 100 Method method, 101 InTuple&& in, 102 OutTuple* out) { 103 constexpr size_t in_size = std::tuple_size<std::decay_t<InTuple>>::value; 104 constexpr size_t out_size = std::tuple_size<OutTuple>::value; 105 DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out, 106 std::make_index_sequence<in_size>(), 107 std::make_index_sequence<out_size>()); 108 } 109 110 } // namespace base 111 112 #endif // BASE_TUPLE_H_ 113