tuple.h 4.2 KB

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