• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //    * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //    * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //    * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Use std::tuple as tuple type. This file contains helper functions for
32 // working with std::tuples.
33 // The functions DispatchToMethod and DispatchToFunction take a function pointer
34 // or instance and method pointer, and unpack a tuple into arguments to the
35 // call.
36 //
37 // Example usage:
38 //   // These two methods of creating a Tuple are identical.
39 //   std::tuple<int, const char*> tuple_a(1, "wee");
40 //   std::tuple<int, const char*> tuple_b = std::make_tuple(1, "wee");
41 //
42 //   void SomeFunc(int a, const char* b) { }
43 //   DispatchToFunction(&SomeFunc, tuple_a);  // SomeFunc(1, "wee")
44 //   DispatchToFunction(
45 //       &SomeFunc, std::make_tuple(10, "foo"));    // SomeFunc(10, "foo")
46 //
47 //   struct { void SomeMeth(int a, int b, int c) { } } foo;
48 //   DispatchToMethod(&foo, &Foo::SomeMeth, std::make_tuple(1, 2, 3));
49 //   // foo->SomeMeth(1, 2, 3);
50 
51 #ifndef CEF_INCLUDE_BASE_CEF_TUPLE_H_
52 #define CEF_INCLUDE_BASE_CEF_TUPLE_H_
53 #pragma once
54 
55 #if defined(USING_CHROMIUM_INCLUDES)
56 // When building CEF include the Chromium header directly.
57 #include "base/tuple.h"
58 #else  // !USING_CHROMIUM_INCLUDES
59 // The following is substantially similar to the Chromium implementation.
60 // If the Chromium implementation diverges the below implementation should be
61 // updated to match.
62 
63 #include <stddef.h>
64 #include <tuple>
65 #include <utility>
66 
67 #include "include/base/cef_build.h"
68 
69 namespace base {
70 
71 // Dispatchers ----------------------------------------------------------------
72 //
73 // Helper functions that call the given method on an object, with the unpacked
74 // tuple arguments.  Notice that they all have the same number of arguments,
75 // so you need only write:
76 //   DispatchToMethod(object, &Object::method, args);
77 // This is very useful for templated dispatchers, since they don't need to know
78 // what type |args| is.
79 
80 // Non-Static Dispatchers with no out params.
81 
82 template <typename ObjT, typename Method, typename Tuple, size_t... Ns>
DispatchToMethodImpl(const ObjT & obj,Method method,Tuple && args,std::index_sequence<Ns...>)83 inline void DispatchToMethodImpl(const ObjT& obj,
84                                  Method method,
85                                  Tuple&& args,
86                                  std::index_sequence<Ns...>) {
87   (obj->*method)(std::get<Ns>(std::forward<Tuple>(args))...);
88 }
89 
90 template <typename ObjT, typename Method, typename Tuple>
DispatchToMethod(const ObjT & obj,Method method,Tuple && args)91 inline void DispatchToMethod(const ObjT& obj,
92                              Method method,
93                              Tuple&& args) {
94   constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value;
95   DispatchToMethodImpl(obj, method, std::forward<Tuple>(args),
96                        std::make_index_sequence<size>());
97 }
98 
99 // Static Dispatchers with no out params.
100 
101 template <typename Function, typename Tuple, size_t... Ns>
DispatchToFunctionImpl(Function function,Tuple && args,std::index_sequence<Ns...>)102 inline void DispatchToFunctionImpl(Function function,
103                                    Tuple&& args,
104                                    std::index_sequence<Ns...>) {
105   (*function)(std::get<Ns>(std::forward<Tuple>(args))...);
106 }
107 
108 template <typename Function, typename Tuple>
DispatchToFunction(Function function,Tuple && args)109 inline void DispatchToFunction(Function function, Tuple&& args) {
110   constexpr size_t size = std::tuple_size<std::decay_t<Tuple>>::value;
111   DispatchToFunctionImpl(function, std::forward<Tuple>(args),
112                          std::make_index_sequence<size>());
113 }
114 
115 // Dispatchers with out parameters.
116 
117 template <typename ObjT,
118           typename Method,
119           typename InTuple,
120           typename OutTuple,
121           size_t... InNs,
122           size_t... OutNs>
DispatchToMethodImpl(const ObjT & obj,Method method,InTuple && in,OutTuple * out,std::index_sequence<InNs...>,std::index_sequence<OutNs...>)123 inline void DispatchToMethodImpl(const ObjT& obj,
124                                  Method method,
125                                  InTuple&& in,
126                                  OutTuple* out,
127                                  std::index_sequence<InNs...>,
128                                  std::index_sequence<OutNs...>) {
129   (obj->*method)(std::get<InNs>(std::forward<InTuple>(in))...,
130                  &std::get<OutNs>(*out)...);
131 }
132 
133 template <typename ObjT, typename Method, typename InTuple, typename OutTuple>
DispatchToMethod(const ObjT & obj,Method method,InTuple && in,OutTuple * out)134 inline void DispatchToMethod(const ObjT& obj,
135                              Method method,
136                              InTuple&& in,
137                              OutTuple* out) {
138   constexpr size_t in_size = std::tuple_size<std::decay_t<InTuple>>::value;
139   constexpr size_t out_size = std::tuple_size<OutTuple>::value;
140   DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out,
141                        std::make_index_sequence<in_size>(),
142                        std::make_index_sequence<out_size>());
143 }
144 
145 }  // namespace base
146 
147 #endif  // !USING_CHROMIUM_INCLUDES
148 
149 #endif  // CEF_INCLUDE_BASE_CEF_TUPLE_H_
150