| // Copyright 2011 The Chromium Authors |
| // 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" |
| |
| namespacebase{ |
| |
| // 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<typenameObjT,typenameMethod,typenameTuple,size_t...Ns> |
| inlinevoidDispatchToMethodImpl(constObjT& obj, |
| Method method, |
| Tuple&& args, |
| std::index_sequence<Ns...>){ |
| (obj->*method)(std::get<Ns>(std::forward<Tuple>(args))...); |
| } |
| |
| template<typenameObjT,typenameMethod,typenameTuple> |
| inlinevoidDispatchToMethod(constObjT& obj,Method method,Tuple&& args){ |
| constexprsize_t size= std::tuple_size_v<std::decay_t<Tuple>>; |
| DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), |
| std::make_index_sequence<size>()); |
| } |
| |
| // Static Dispatchers with no out params. |
| |
| template<typenameFunction,typenameTuple,size_t...Ns> |
| inlinevoidDispatchToFunctionImpl(Functionfunction, |
| Tuple&& args, |
| std::index_sequence<Ns...>){ |
| (*function)(std::get<Ns>(std::forward<Tuple>(args))...); |
| } |
| |
| template<typenameFunction,typenameTuple> |
| inlinevoidDispatchToFunction(Functionfunction,Tuple&& args){ |
| constexprsize_t size= std::tuple_size_v<std::decay_t<Tuple>>; |
| DispatchToFunctionImpl(function, std::forward<Tuple>(args), |
| std::make_index_sequence<size>()); |
| } |
| |
| // Dispatchers with out parameters. |
| |
| template<typenameObjT, |
| typenameMethod, |
| typenameInTuple, |
| typenameOutTuple, |
| size_t...InNs, |
| size_t...OutNs> |
| inlinevoidDispatchToMethodImpl(constObjT& 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<typenameObjT,typenameMethod,typenameInTuple,typenameOutTuple> |
| inlinevoidDispatchToMethod(constObjT& obj, |
| Method method, |
| InTuple&&in, |
| OutTuple*out){ |
| constexprsize_t in_size= std::tuple_size_v<std::decay_t<InTuple>>; |
| constexprsize_t out_size= std::tuple_size_v<OutTuple>; |
| 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_ |