Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: experimental/c_salt/callback.h

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/c_salt/c_salt_test_module.cc ('k') | experimental/c_salt/callback_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 The Ginsu Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can
3 // be found in the LICENSE file.
4
5 #ifndef C_SALT_CALLBACK_H_
6 #define C_SALT_CALLBACK_H_
7
8 #include "boost/function.hpp"
9 #include "boost/bind.hpp"
10 #include "boost/shared_ptr.hpp"
11 #include "boost/type_traits/remove_const.hpp"
12 #include "boost/type_traits/remove_reference.hpp"
13 #include "c_salt/variant_ptrs.h"
14 #include "c_salt/variant.h"
15
16 namespace c_salt {
17 namespace c_salt_private {
18 // VariantToArgConverter is a small helper class for converting c_salt Variants
19 // in to a given type, to allow them to be used as parameters.
20 // For most types, just call Variant::GetValue<> function and let it do the
21 // work.
22 // TODO(dmichael): Is there a nicer way to support passing c_salt::Variant as
23 // a parameter? Or is this a good way... it is certainly extensible. It also
24 // allows us to pass the Variant through without copying.
25 template <class T>
26 struct VariantToArgConverter {
27 static T Get(const c_salt::SharedVariant& var) {
28 return var->GetValue<T>();
29 }
30 };
31 // If the argument is a c_salt::SharedVariant, just pass it through.
32 template <>
33 struct VariantToArgConverter<c_salt::SharedVariant> {
34 static const c_salt::SharedVariant& Get(const c_salt::SharedVariant& var) {
35 return var;
36 }
37 };
38 // If the argument is a c_salt::Variant, just dereference the shared_ptr.
39 template <>
40 struct VariantToArgConverter<c_salt::Variant> {
41 static const c_salt::Variant& Get(const c_salt::SharedVariant& var) {
42 return *var;
43 }
44 };
45 } // namespace c_salt_private
46
47 // Pure virtual class that provides the interface for invoking a method given
48 // c_salt::Variant arguments. Clients should generally not use this interface
49 // directly; it simply allows c_salt code to invoke methods generically. See
50 // MethodCallbackExecutorImpl (and related classes) below for further
51 // details on how this is achieved.
52 class MethodCallbackExecutor {
53 public:
54 virtual ~MethodCallbackExecutor() {}
55
56 virtual bool Execute(const SharedVariant* params_begin,
57 const SharedVariant* params_end,
58 SharedVariant* return_value_var) = 0;
59 };
60 typedef boost::shared_ptr<MethodCallbackExecutor> SharedMethodCallbackExecutor;
61
62 // Templates used to support method call-backs when a method or property is
63 // accessed from the browser code.
64
65 // FunctionInvoker is a class template which holds a boost::function and
66 // provides a means for invoking that boost::function by providing a sequence
67 // of c_salt::Variant parameters. Its purpose is to allow turning scripting
68 // invocations in to a more natural C++ form. For example, it can be used to
69 // convert an NPAPI method invocation in to a conventional C++ function call,
70 // or similarly for PPAPI, SRPC, etc, by mapping the parameters to a sequence of
71 // c_salt::Variants.
72 //
73 // This is the default implementation of FunctionInvoker. Its methods are not
74 // implemented; it is left here for documentation purposes only. Any real usage
75 // of FunctionInvoker must match one of the specializations defined later. If
76 // a match is not found, it is likely because the user is attempting to create
77 // a function invoker with more arguments than we currently support.
78 template <class Signature>
79 class FunctionInvoker {
80 // Constructor for member functions that binds the target object to the
81 // FunctionInvoker's stored boost::function.
82 template <class T>
83 FunctionInvoker(T* target_object, Signature method);
84
85 // Convert the given parameters (taken as a sequence of c_salt::Variants) in
86 // to the C++ types required by the bound function. Then, invoke the
87 // boost::function owned by this FunctionInvoker, passing the arguments.
88 // Convert the return value to a c_salt::Variant.
89 // params_begin and params_end are pointers treated as forward iterators for a
90 // sequence that contains the arguments to be sent to the function. Note that
91 // we could just pass a vector, but this keeps STL dependencies to more of a
92 // minimum in the interface between client-compiled code (i.e., the template)
93 // and the Google-provided library (c_salt).
94 // return_val is an out-parameter. The caller must provide a valid pointer
95 // to a c_salt::Variant.
96 bool Invoke(const SharedVariant* begin,
97 const SharedVariant* end,
98 SharedVariant* return_value);
99 };
100
101 // Define some macros temporarily so that we can generate code succinctly for
102 // our FunctionInvoker classes. We need one specialization of FunctionInvoker
103 // for each number of arguments, and they are largely the same. The macros
104 // abstract out the repetive parts and allow us to only duplicate the parts that
105 // are unique.
106 //
107 // Here is an example of what the code looks like after the preprocessor is
108 // finished with it, in this case for 2 arguments:
109 #if 0
110 template <class T, class RetType, class Arg1, class Arg2>
111 class FunctionInvoker<RetType(T::*)(Arg1, Arg2)> {
112 public:
113 typedef RetType ReturnType;
114 typedef ReturnType (T::*MemFunSignature) (Arg1, Arg2);
115 typedef ReturnType (*Signature) (Arg1, Arg2);
116 typedef boost::function<ReturnType (Arg1, Arg2)> FunctionType;
117
118 FunctionInvoker(T* target_object, MemFunSignature method)
119 : function_(boost::bind(method, target_object, _1, _2)) {}
120 bool Invoke(const SharedVariant* params_begin,
121 const SharedVariant* params_end,
122 SharedVariant* return_value_var) {
123 // Declare a local instance of the argument type. If it's a const-ref
124 // parameter, remove the const-ref part of the type so we can make a local
125 // argument on the stack to pass.
126 typedef typename boost::remove_reference<Arg1>::type NoRef1;
127 typedef typename boost::remove_const<NoRef1>::type NoConstRef1;
128 NoConstRef1 arg1;
129 // See if we've run out of arguments. If so, that's an error, so return
130 // false.
131 if (params_begin == params_end) return false;
132 // Get the value from the c_salt::Variant, which handles conversions for us.
133 NoConstRef1 arg1(::c_salt::c_salt_private::
134 VariantToArgConverter<NoConstRef1>::Get(*params_begin));
135 // Advance to the next parameter.
136 ++params_begin;
137 typedef typename boost::remove_reference<Arg2>::type NoRef2;
138 typedef typename boost::remove_const<NoRef2>::type NoConstRef2;
139 if (params_begin == params_end) return false;
140 NoConstRef2 arg2(::c_salt::c_salt_private::
141 VariantToArgConverter<NoConstRef2>::Get(*params_begin));
142 ++params_begin;
143 NoConstRef2 arg2;
144
145 // Call the function and capture the return value (note, this does not
146 // currently support void returns).
147 ReturnType retval = function_(arg1, arg2);
148 // Create a Variant using the appropriate constructor.
149 *return_value_var = SharedVariant(retval);
150 return true;
151 }
152 private:
153 FunctionType function_;
154 };
155 #endif
156 // A macro that fills in the beginning of the class definition, including
157 // typedefs that we (or our clients) might find useful.
158 #define FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN(ARGLIST) \
159 class FunctionInvoker<RetType(T::*) ARGLIST> {\
160 public:\
161 typedef RetType ReturnType;\
162 typedef ReturnType (T::*MemFunSignature) ARGLIST;\
163 typedef ReturnType (*Signature) ARGLIST;\
164 typedef boost::function<ReturnType ARGLIST> FunctionType;\
165
166 // A macro for the constructor. BIND_ARGLIST is of the form:
167 // (method, target_object ...)
168 // where the ... is a list of 0 or more bind placeholders (, _1, _2, etc).
169 #define FUNCTIONINVOKER_CONSTRUCTOR(BIND_ARGLIST) \
170 FunctionInvoker(T* target_object, MemFunSignature method) : \
171 function_(boost::bind BIND_ARGLIST ) {}
172 // end FUNCTIONINVOKER_CONSTRUCTOR
173
174 // A macro for the beginning of the Invoke function.
175 #define FUNCTIONINVOKER_INVOKE_BEGIN() \
176 bool Invoke(const ::c_salt::SharedVariant* params_begin, \
177 const ::c_salt::SharedVariant* params_end, \
178 ::c_salt::SharedVariant* return_value_var) {
179 // end FUNCTIONINVOKER_INVOKE_BEGIN
180
181 // A portion of the invoker function that converts 1 argument, returning
182 // false if that conversion fails. NUM is a positive integer.
183 #define FUNCTIONINVOKER_INVOKE_CONVERT_ARG(NUM) \
184 typedef typename boost::remove_reference<Arg ## NUM>::type NoRef ## NUM; \
185 typedef typename boost::remove_const<NoRef ## NUM>::type NoConstRef ## NUM;\
186 if (params_begin == params_end) return false; \
187 NoConstRef##NUM arg##NUM(::c_salt::c_salt_private:: \
188 VariantToArgConverter<NoConstRef##NUM>::Get(*params_begin)); \
189 ++params_begin;
190 // end FUNCTIONINVOKER_INVOKE_CONVERT_ARG
191
192 // A macro for the end of the Invoke function.
193 #define FUNCTIONINVOKER_INVOKE_END(ARGLIST) \
194 ReturnType retval = function_ ARGLIST; \
195 return_value_var->reset(new ::c_salt::Variant(retval)); \
196 return true;\
197 }
198 // end FUNCTIONINVOKER_INVOKE_END
199
200 // A macro for the end of the FunctionInvoker class.
201 #define FUNCTIONINVOKER_CLASS_DEFINITION_END() \
202 private: \
203 FunctionType function_;\
204 };
205 // end FUNCTIONINVOKER_CLASS_DEFINITION_END
206
207 // Now we use the above macros to define FunctionInvoker partial specializations
208 // for each number of arguments which we want to support.
209 // 0 Args. Note the lack of semicolons. These macros are not written to allow
210 // for semicolons.
211 template <class T, class RetType>
212 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN(())
213 // Note that the parameter list here (and in INVOKE_END) must have additional
214 // parens around it. This makes it appear as 1 argument to the preprocessor,
215 // and places the entire parameter list in the resultant code.
216 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object))
217 FUNCTIONINVOKER_INVOKE_BEGIN()
218 FUNCTIONINVOKER_INVOKE_END(())
219 FUNCTIONINVOKER_CLASS_DEFINITION_END()
220 // 1 Args.
221 template <class T, class RetType, class Arg1>
222 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1))
223 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1))
224 FUNCTIONINVOKER_INVOKE_BEGIN()
225 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
226 FUNCTIONINVOKER_INVOKE_END((arg1))
227 FUNCTIONINVOKER_CLASS_DEFINITION_END()
228 // 2 Args.
229 template <class T, class RetType, class Arg1, class Arg2>
230 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1, Arg2))
231 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1, _2))
232 FUNCTIONINVOKER_INVOKE_BEGIN()
233 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
234 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(2)
235 FUNCTIONINVOKER_INVOKE_END((arg1, arg2))
236 FUNCTIONINVOKER_CLASS_DEFINITION_END()
237 // 3 Args.
238 template <class T, class RetType, class Arg1, class Arg2, class Arg3>
239 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1, Arg2, Arg3))
240 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1, _2, _3))
241 FUNCTIONINVOKER_INVOKE_BEGIN()
242 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
243 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(2)
244 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(3)
245 FUNCTIONINVOKER_INVOKE_END((arg1, arg2, arg3))
246 FUNCTIONINVOKER_CLASS_DEFINITION_END()
247 // 4 Args.
248 template <class T, class RetType, class Arg1, class Arg2, class Arg3
249 , class Arg4>
250 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1, Arg2, Arg3, Arg4))
251 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1, _2, _3, _4))
252 FUNCTIONINVOKER_INVOKE_BEGIN()
253 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
254 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(2)
255 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(3)
256 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(4)
257 FUNCTIONINVOKER_INVOKE_END((arg1, arg2, arg3, arg4))
258 FUNCTIONINVOKER_CLASS_DEFINITION_END()
259 // 5 Args.
260 template <class T, class RetType, class Arg1, class Arg2, class Arg3
261 , class Arg4, class Arg5>
262 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1, Arg2, Arg3, Arg4, Arg5))
263 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1, _2, _3, _4, _5))
264 FUNCTIONINVOKER_INVOKE_BEGIN()
265 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
266 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(2)
267 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(3)
268 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(4)
269 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(5)
270 FUNCTIONINVOKER_INVOKE_END((arg1, arg2, arg3, arg4, arg5))
271 FUNCTIONINVOKER_CLASS_DEFINITION_END()
272 // 6 Args.
273 template <class T, class RetType, class Arg1, class Arg2, class Arg3
274 , class Arg4, class Arg5, class Arg6>
275 FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN((Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
276 FUNCTIONINVOKER_CONSTRUCTOR((method, target_object, _1, _2, _3, _4, _5, _6))
277 FUNCTIONINVOKER_INVOKE_BEGIN()
278 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(1)
279 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(2)
280 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(3)
281 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(4)
282 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(5)
283 FUNCTIONINVOKER_INVOKE_CONVERT_ARG(6)
284 FUNCTIONINVOKER_INVOKE_END((arg1, arg2, arg3, arg4, arg5, arg6))
285 FUNCTIONINVOKER_CLASS_DEFINITION_END()
286
287 // Now clean up so these macros aren't exported outside this .h file.
288 #undef FUNCTIONINVOKER_CLASS_DEFINITION_BEGIN
289 #undef FUNCTIONINVOKER_CONSTRUCTOR
290 #undef FUNCTIONINVOKER_INVOKE_BEGIN
291 #undef FUNCTIONINVOKER_INVOKE_CONVERT_ARG
292 #undef FUNCTIONINVOKER_INVOKE_END
293 #undef FUNCTIONINVOKER_CLASS_DEFINITION_END
294
295 // MethodCallbackExecutorImpl is a class template that implements the
296 // MethodCallbackExecutor interface by calling an arbitrary boost::function
297 // and automatically handling marshalling/unmarshalling of the arguments and
298 // return type to bridge the gap between the method invocation and the
299 // invocation of a real C++ method on a client-defined class.
300 template <class Signature>
301 class MethodCallbackExecutorImpl : public MethodCallbackExecutor {
302 public:
303 typedef typename ::c_salt::FunctionInvoker<Signature> FunctionInvokerType;
304
305 template <class T>
306 MethodCallbackExecutorImpl(T* instance, Signature method)
307 : function_invoker_(instance, method) {}
308 virtual ~MethodCallbackExecutorImpl() {}
309
310 virtual bool Execute(const SharedVariant* params_begin,
311 const SharedVariant* params_end,
312 SharedVariant* return_value_var) {
313 return function_invoker_.Invoke(params_begin,
314 params_end,
315 return_value_var);
316 }
317 private:
318 FunctionInvokerType function_invoker_;
319 };
320
321 } // namespace c_salt
322
323 #endif // C_SALT_CALLBACK_H_
OLDNEW
« no previous file with comments | « experimental/c_salt/c_salt_test_module.cc ('k') | experimental/c_salt/callback_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698