blob: 87271c5eb8f58692cc967c9dbdc3c9814810c6c6 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
2#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
3
4#include <google/protobuf/stubs/macros.h>
5#include <google/protobuf/stubs/type_traits.h>
6
7// ===================================================================
8// emulates google3/base/callback.h
9
10namespace google {
11namespace protobuf {
12
13// Abstract interface for a callback. When calling an RPC, you must provide
14// a Closure to call when the procedure completes. See the Service interface
15// in service.h.
16//
17// To automatically construct a Closure which calls a particular function or
18// method with a particular set of parameters, use the NewCallback() function.
19// Example:
20// void FooDone(const FooResponse* response) {
21// ...
22// }
23//
24// void CallFoo() {
25// ...
26// // When done, call FooDone() and pass it a pointer to the response.
27// Closure* callback = NewCallback(&FooDone, response);
28// // Make the call.
29// service->Foo(controller, request, response, callback);
30// }
31//
32// Example that calls a method:
33// class Handler {
34// public:
35// ...
36//
37// void FooDone(const FooResponse* response) {
38// ...
39// }
40//
41// void CallFoo() {
42// ...
43// // When done, call FooDone() and pass it a pointer to the response.
44// Closure* callback = NewCallback(this, &Handler::FooDone, response);
45// // Make the call.
46// service->Foo(controller, request, response, callback);
47// }
48// };
49//
50// Currently NewCallback() supports binding zero, one, or two arguments.
51//
52// Callbacks created with NewCallback() automatically delete themselves when
53// executed. They should be used when a callback is to be called exactly
54// once (usually the case with RPC callbacks). If a callback may be called
55// a different number of times (including zero), create it with
56// NewPermanentCallback() instead. You are then responsible for deleting the
57// callback (using the "delete" keyword as normal).
58//
59// Note that NewCallback() is a bit touchy regarding argument types. Generally,
60// the values you provide for the parameter bindings must exactly match the
61// types accepted by the callback function. For example:
62// void Foo(string s);
63// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string
64// NewCallback(&Foo, string("foo")); // WORKS
65// Also note that the arguments cannot be references:
66// void Foo(const string& s);
67// string my_str;
68// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes.
69// However, correctly-typed pointers will work just fine.
70class LIBPROTOBUF_EXPORT Closure {
71 public:
72 Closure() {}
73 virtual ~Closure();
74
75 virtual void Run() = 0;
76
77 private:
78 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
79};
80
81template<typename R>
82class ResultCallback {
83 public:
84 ResultCallback() {}
85 virtual ~ResultCallback() {}
86
87 virtual R Run() = 0;
88
89 private:
90 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback);
91};
92
93template<typename R, typename A1>
94class LIBPROTOBUF_EXPORT ResultCallback1 {
95 public:
96 ResultCallback1() {}
97 virtual ~ResultCallback1() {}
98
99 virtual R Run(A1) = 0;
100
101 private:
102 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1);
103};
104
105template<typename R, typename A1, typename A2>
106class LIBPROTOBUF_EXPORT ResultCallback2 {
107 public:
108 ResultCallback2() {}
109 virtual ~ResultCallback2() {}
110
111 virtual R Run(A1,A2) = 0;
112
113 private:
114 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2);
115};
116
117namespace internal {
118
119class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
120 public:
121 typedef void (*FunctionType)();
122
123 FunctionClosure0(FunctionType function, bool self_deleting)
124 : function_(function), self_deleting_(self_deleting) {}
125 ~FunctionClosure0();
126
127 void Run() {
128 bool needs_delete = self_deleting_; // read in case callback deletes
129 function_();
130 if (needs_delete) delete this;
131 }
132
133 private:
134 FunctionType function_;
135 bool self_deleting_;
136};
137
138template <typename Class>
139class MethodClosure0 : public Closure {
140 public:
141 typedef void (Class::*MethodType)();
142
143 MethodClosure0(Class* object, MethodType method, bool self_deleting)
144 : object_(object), method_(method), self_deleting_(self_deleting) {}
145 ~MethodClosure0() {}
146
147 void Run() {
148 bool needs_delete = self_deleting_; // read in case callback deletes
149 (object_->*method_)();
150 if (needs_delete) delete this;
151 }
152
153 private:
154 Class* object_;
155 MethodType method_;
156 bool self_deleting_;
157};
158
159template <typename Arg1>
160class FunctionClosure1 : public Closure {
161 public:
162 typedef void (*FunctionType)(Arg1 arg1);
163
164 FunctionClosure1(FunctionType function, bool self_deleting,
165 Arg1 arg1)
166 : function_(function), self_deleting_(self_deleting),
167 arg1_(arg1) {}
168 ~FunctionClosure1() {}
169
170 void Run() {
171 bool needs_delete = self_deleting_; // read in case callback deletes
172 function_(arg1_);
173 if (needs_delete) delete this;
174 }
175
176 private:
177 FunctionType function_;
178 bool self_deleting_;
179 Arg1 arg1_;
180};
181
182template <typename Class, typename Arg1>
183class MethodClosure1 : public Closure {
184 public:
185 typedef void (Class::*MethodType)(Arg1 arg1);
186
187 MethodClosure1(Class* object, MethodType method, bool self_deleting,
188 Arg1 arg1)
189 : object_(object), method_(method), self_deleting_(self_deleting),
190 arg1_(arg1) {}
191 ~MethodClosure1() {}
192
193 void Run() {
194 bool needs_delete = self_deleting_; // read in case callback deletes
195 (object_->*method_)(arg1_);
196 if (needs_delete) delete this;
197 }
198
199 private:
200 Class* object_;
201 MethodType method_;
202 bool self_deleting_;
203 Arg1 arg1_;
204};
205
206template <typename Arg1, typename Arg2>
207class FunctionClosure2 : public Closure {
208 public:
209 typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
210
211 FunctionClosure2(FunctionType function, bool self_deleting,
212 Arg1 arg1, Arg2 arg2)
213 : function_(function), self_deleting_(self_deleting),
214 arg1_(arg1), arg2_(arg2) {}
215 ~FunctionClosure2() {}
216
217 void Run() {
218 bool needs_delete = self_deleting_; // read in case callback deletes
219 function_(arg1_, arg2_);
220 if (needs_delete) delete this;
221 }
222
223 private:
224 FunctionType function_;
225 bool self_deleting_;
226 Arg1 arg1_;
227 Arg2 arg2_;
228};
229
230template <typename Class, typename Arg1, typename Arg2>
231class MethodClosure2 : public Closure {
232 public:
233 typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
234
235 MethodClosure2(Class* object, MethodType method, bool self_deleting,
236 Arg1 arg1, Arg2 arg2)
237 : object_(object), method_(method), self_deleting_(self_deleting),
238 arg1_(arg1), arg2_(arg2) {}
239 ~MethodClosure2() {}
240
241 void Run() {
242 bool needs_delete = self_deleting_; // read in case callback deletes
243 (object_->*method_)(arg1_, arg2_);
244 if (needs_delete) delete this;
245 }
246
247 private:
248 Class* object_;
249 MethodType method_;
250 bool self_deleting_;
251 Arg1 arg1_;
252 Arg2 arg2_;
253};
254
255template<typename R>
256class FunctionResultCallback_0_0 : public ResultCallback<R> {
257 public:
258 typedef R (*FunctionType)();
259
260 FunctionResultCallback_0_0(FunctionType function, bool self_deleting)
261 : function_(function), self_deleting_(self_deleting) {}
262 ~FunctionResultCallback_0_0() {}
263
264 R Run() {
265 bool needs_delete = self_deleting_; // read in case callback deletes
266 R result = function_();
267 if (needs_delete) delete this;
268 return result;
269 }
270
271 private:
272 FunctionType function_;
273 bool self_deleting_;
274};
275
276template<typename R, typename P1>
277class FunctionResultCallback_1_0 : public ResultCallback<R> {
278 public:
279 typedef R (*FunctionType)(P1);
280
281 FunctionResultCallback_1_0(FunctionType function, bool self_deleting,
282 P1 p1)
283 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
284 ~FunctionResultCallback_1_0() {}
285
286 R Run() {
287 bool needs_delete = self_deleting_; // read in case callback deletes
288 R result = function_(p1_);
289 if (needs_delete) delete this;
290 return result;
291 }
292
293 private:
294 FunctionType function_;
295 bool self_deleting_;
296 P1 p1_;
297};
298
299template<typename R, typename Arg1>
300class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
301 public:
302 typedef R (*FunctionType)(Arg1 arg1);
303
304 FunctionResultCallback_0_1(FunctionType function, bool self_deleting)
305 : function_(function), self_deleting_(self_deleting) {}
306 ~FunctionResultCallback_0_1() {}
307
308 R Run(Arg1 a1) {
309 bool needs_delete = self_deleting_; // read in case callback deletes
310 R result = function_(a1);
311 if (needs_delete) delete this;
312 return result;
313 }
314
315 private:
316 FunctionType function_;
317 bool self_deleting_;
318};
319
320template<typename R, typename P1, typename A1>
321class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
322 public:
323 typedef R (*FunctionType)(P1, A1);
324
325 FunctionResultCallback_1_1(FunctionType function, bool self_deleting,
326 P1 p1)
327 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
328 ~FunctionResultCallback_1_1() {}
329
330 R Run(A1 a1) {
331 bool needs_delete = self_deleting_; // read in case callback deletes
332 R result = function_(p1_, a1);
333 if (needs_delete) delete this;
334 return result;
335 }
336
337 private:
338 FunctionType function_;
339 bool self_deleting_;
340 P1 p1_;
341};
342
343template <typename T>
344struct InternalConstRef {
345 typedef typename remove_reference<T>::type base_type;
346 typedef const base_type& type;
347};
348
349template <typename R, typename T, typename P1, typename P2, typename P3,
350 typename P4, typename P5, typename A1, typename A2>
351class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
352 public:
353 typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2);
354 MethodResultCallback_5_2(T* object, MethodType method, bool self_deleting,
355 P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
356 : object_(object),
357 method_(method),
358 self_deleting_(self_deleting),
359 p1_(p1),
360 p2_(p2),
361 p3_(p3),
362 p4_(p4),
363 p5_(p5) {}
364 ~MethodResultCallback_5_2() {}
365
366 R Run(A1 a1, A2 a2) {
367 bool needs_delete = self_deleting_;
368 R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2);
369 if (needs_delete) delete this;
370 return result;
371 }
372
373 private:
374 T* object_;
375 MethodType method_;
376 bool self_deleting_;
377 typename remove_reference<P1>::type p1_;
378 typename remove_reference<P2>::type p2_;
379 typename remove_reference<P3>::type p3_;
380 typename remove_reference<P4>::type p4_;
381 typename remove_reference<P5>::type p5_;
382};
383
384// See Closure.
385inline Closure* NewCallback(void (*function)()) {
386 return new internal::FunctionClosure0(function, true);
387}
388
389// See Closure.
390inline Closure* NewPermanentCallback(void (*function)()) {
391 return new internal::FunctionClosure0(function, false);
392}
393
394// See Closure.
395template <typename Class>
396inline Closure* NewCallback(Class* object, void (Class::*method)()) {
397 return new internal::MethodClosure0<Class>(object, method, true);
398}
399
400// See Closure.
401template <typename Class>
402inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
403 return new internal::MethodClosure0<Class>(object, method, false);
404}
405
406// See Closure.
407template <typename Arg1>
408inline Closure* NewCallback(void (*function)(Arg1),
409 Arg1 arg1) {
410 return new internal::FunctionClosure1<Arg1>(function, true, arg1);
411}
412
413// See Closure.
414template <typename Arg1>
415inline Closure* NewPermanentCallback(void (*function)(Arg1),
416 Arg1 arg1) {
417 return new internal::FunctionClosure1<Arg1>(function, false, arg1);
418}
419
420// See Closure.
421template <typename Class, typename Arg1>
422inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1),
423 Arg1 arg1) {
424 return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1);
425}
426
427// See Closure.
428template <typename Class, typename Arg1>
429inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1),
430 Arg1 arg1) {
431 return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1);
432}
433
434// See Closure.
435template <typename Arg1, typename Arg2>
436inline Closure* NewCallback(void (*function)(Arg1, Arg2),
437 Arg1 arg1, Arg2 arg2) {
438 return new internal::FunctionClosure2<Arg1, Arg2>(
439 function, true, arg1, arg2);
440}
441
442// See Closure.
443template <typename Arg1, typename Arg2>
444inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2),
445 Arg1 arg1, Arg2 arg2) {
446 return new internal::FunctionClosure2<Arg1, Arg2>(
447 function, false, arg1, arg2);
448}
449
450// See Closure.
451template <typename Class, typename Arg1, typename Arg2>
452inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
453 Arg1 arg1, Arg2 arg2) {
454 return new internal::MethodClosure2<Class, Arg1, Arg2>(
455 object, method, true, arg1, arg2);
456}
457
458// See Closure.
459template <typename Class, typename Arg1, typename Arg2>
460inline Closure* NewPermanentCallback(
461 Class* object, void (Class::*method)(Arg1, Arg2),
462 Arg1 arg1, Arg2 arg2) {
463 return new internal::MethodClosure2<Class, Arg1, Arg2>(
464 object, method, false, arg1, arg2);
465}
466
467// See ResultCallback
468template<typename R>
469inline ResultCallback<R>* NewCallback(R (*function)()) {
470 return new internal::FunctionResultCallback_0_0<R>(function, true);
471}
472
473// See ResultCallback
474template<typename R>
475inline ResultCallback<R>* NewPermanentCallback(R (*function)()) {
476 return new internal::FunctionResultCallback_0_0<R>(function, false);
477}
478
479// See ResultCallback
480template<typename R, typename P1>
481inline ResultCallback<R>* NewCallback(R (*function)(P1), P1 p1) {
482 return new internal::FunctionResultCallback_1_0<R, P1>(
483 function, true, p1);
484}
485
486// See ResultCallback
487template<typename R, typename P1>
488inline ResultCallback<R>* NewPermanentCallback(
489 R (*function)(P1), P1 p1) {
490 return new internal::FunctionResultCallback_1_0<R, P1>(
491 function, false, p1);
492}
493
494// See ResultCallback1
495template<typename R, typename A1>
496inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
497 return new internal::FunctionResultCallback_0_1<R, A1>(function, true);
498}
499
500// See ResultCallback1
501template<typename R, typename A1>
502inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) {
503 return new internal::FunctionResultCallback_0_1<R, A1>(function, false);
504}
505
506// See ResultCallback1
507template<typename R, typename P1, typename A1>
508inline ResultCallback1<R, A1>* NewCallback(R (*function)(P1, A1), P1 p1) {
509 return new internal::FunctionResultCallback_1_1<R, P1, A1>(
510 function, true, p1);
511}
512
513// See ResultCallback1
514template<typename R, typename P1, typename A1>
515inline ResultCallback1<R, A1>* NewPermanentCallback(
516 R (*function)(P1, A1), P1 p1) {
517 return new internal::FunctionResultCallback_1_1<R, P1, A1>(
518 function, false, p1);
519}
520
521// See MethodResultCallback_5_2
522template <typename R, typename T, typename P1, typename P2, typename P3,
523 typename P4, typename P5, typename A1, typename A2>
524inline ResultCallback2<R, A1, A2>* NewPermanentCallback(
525 T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2),
526 typename internal::InternalConstRef<P1>::type p1,
527 typename internal::InternalConstRef<P2>::type p2,
528 typename internal::InternalConstRef<P3>::type p3,
529 typename internal::InternalConstRef<P4>::type p4,
530 typename internal::InternalConstRef<P5>::type p5) {
531 return new internal::MethodResultCallback_5_2<R, T, P1, P2, P3, P4, P5, A1,
532 A2>(object, function, false, p1,
533 p2, p3, p4, p5);
534}
535
536} // namespace internal
537
538// A function which does nothing. Useful for creating no-op callbacks, e.g.:
539// Closure* nothing = NewCallback(&DoNothing);
540void LIBPROTOBUF_EXPORT DoNothing();
541
542
543} // namespace protobuf
544} // namespace google
545
546#endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_