1 #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
10 namespace google {
11 namespace 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.
70 class LIBPROTOBUF_EXPORT Closure {
71 public:
Closure()72 Closure() {}
73 virtual ~Closure();
74
75 virtual void Run() = 0;
76
77 private:
78 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
79 };
80
81 template<typename R>
82 class ResultCallback {
83 public:
ResultCallback()84 ResultCallback() {}
~ResultCallback()85 virtual ~ResultCallback() {}
86
87 virtual R Run() = 0;
88
89 private:
90 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback);
91 };
92
93 template<typename R, typename A1>
94 class LIBPROTOBUF_EXPORT ResultCallback1 {
95 public:
ResultCallback1()96 ResultCallback1() {}
~ResultCallback1()97 virtual ~ResultCallback1() {}
98
99 virtual R Run(A1) = 0;
100
101 private:
102 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1);
103 };
104
105 template<typename R, typename A1, typename A2>
106 class LIBPROTOBUF_EXPORT ResultCallback2 {
107 public:
ResultCallback2()108 ResultCallback2() {}
~ResultCallback2()109 virtual ~ResultCallback2() {}
110
111 virtual R Run(A1,A2) = 0;
112
113 private:
114 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2);
115 };
116
117 namespace internal {
118
119 class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
120 public:
121 typedef void (*FunctionType)();
122
FunctionClosure0(FunctionType function,bool self_deleting)123 FunctionClosure0(FunctionType function, bool self_deleting)
124 : function_(function), self_deleting_(self_deleting) {}
125 ~FunctionClosure0();
126
Run()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
138 template <typename Class>
139 class MethodClosure0 : public Closure {
140 public:
141 typedef void (Class::*MethodType)();
142
MethodClosure0(Class * object,MethodType method,bool self_deleting)143 MethodClosure0(Class* object, MethodType method, bool self_deleting)
144 : object_(object), method_(method), self_deleting_(self_deleting) {}
~MethodClosure0()145 ~MethodClosure0() {}
146
Run()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
159 template <typename Arg1>
160 class FunctionClosure1 : public Closure {
161 public:
162 typedef void (*FunctionType)(Arg1 arg1);
163
FunctionClosure1(FunctionType function,bool self_deleting,Arg1 arg1)164 FunctionClosure1(FunctionType function, bool self_deleting,
165 Arg1 arg1)
166 : function_(function), self_deleting_(self_deleting),
167 arg1_(arg1) {}
~FunctionClosure1()168 ~FunctionClosure1() {}
169
Run()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
182 template <typename Class, typename Arg1>
183 class MethodClosure1 : public Closure {
184 public:
185 typedef void (Class::*MethodType)(Arg1 arg1);
186
MethodClosure1(Class * object,MethodType method,bool self_deleting,Arg1 arg1)187 MethodClosure1(Class* object, MethodType method, bool self_deleting,
188 Arg1 arg1)
189 : object_(object), method_(method), self_deleting_(self_deleting),
190 arg1_(arg1) {}
~MethodClosure1()191 ~MethodClosure1() {}
192
Run()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
206 template <typename Arg1, typename Arg2>
207 class FunctionClosure2 : public Closure {
208 public:
209 typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
210
FunctionClosure2(FunctionType function,bool self_deleting,Arg1 arg1,Arg2 arg2)211 FunctionClosure2(FunctionType function, bool self_deleting,
212 Arg1 arg1, Arg2 arg2)
213 : function_(function), self_deleting_(self_deleting),
214 arg1_(arg1), arg2_(arg2) {}
~FunctionClosure2()215 ~FunctionClosure2() {}
216
Run()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
230 template <typename Class, typename Arg1, typename Arg2>
231 class MethodClosure2 : public Closure {
232 public:
233 typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
234
MethodClosure2(Class * object,MethodType method,bool self_deleting,Arg1 arg1,Arg2 arg2)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) {}
~MethodClosure2()239 ~MethodClosure2() {}
240
Run()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
255 template<typename R>
256 class FunctionResultCallback_0_0 : public ResultCallback<R> {
257 public:
258 typedef R (*FunctionType)();
259
FunctionResultCallback_0_0(FunctionType function,bool self_deleting)260 FunctionResultCallback_0_0(FunctionType function, bool self_deleting)
261 : function_(function), self_deleting_(self_deleting) {}
~FunctionResultCallback_0_0()262 ~FunctionResultCallback_0_0() {}
263
Run()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
276 template<typename R, typename P1>
277 class FunctionResultCallback_1_0 : public ResultCallback<R> {
278 public:
279 typedef R (*FunctionType)(P1);
280
FunctionResultCallback_1_0(FunctionType function,bool self_deleting,P1 p1)281 FunctionResultCallback_1_0(FunctionType function, bool self_deleting,
282 P1 p1)
283 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
~FunctionResultCallback_1_0()284 ~FunctionResultCallback_1_0() {}
285
Run()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
299 template<typename R, typename Arg1>
300 class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
301 public:
302 typedef R (*FunctionType)(Arg1 arg1);
303
FunctionResultCallback_0_1(FunctionType function,bool self_deleting)304 FunctionResultCallback_0_1(FunctionType function, bool self_deleting)
305 : function_(function), self_deleting_(self_deleting) {}
~FunctionResultCallback_0_1()306 ~FunctionResultCallback_0_1() {}
307
Run(Arg1 a1)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
320 template<typename R, typename P1, typename A1>
321 class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
322 public:
323 typedef R (*FunctionType)(P1, A1);
324
FunctionResultCallback_1_1(FunctionType function,bool self_deleting,P1 p1)325 FunctionResultCallback_1_1(FunctionType function, bool self_deleting,
326 P1 p1)
327 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
~FunctionResultCallback_1_1()328 ~FunctionResultCallback_1_1() {}
329
Run(A1 a1)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
343 template <typename T>
344 struct InternalConstRef {
345 typedef typename remove_reference<T>::type base_type;
346 typedef const base_type& type;
347 };
348
349 template <typename R, typename T, typename P1, typename P2, typename P3,
350 typename P4, typename P5, typename A1, typename A2>
351 class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
352 public:
353 typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2);
MethodResultCallback_5_2(T * object,MethodType method,bool self_deleting,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)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) {}
~MethodResultCallback_5_2()364 ~MethodResultCallback_5_2() {}
365
Run(A1 a1,A2 a2)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.
NewCallback(void (* function)())385 inline Closure* NewCallback(void (*function)()) {
386 return new internal::FunctionClosure0(function, true);
387 }
388
389 // See Closure.
NewPermanentCallback(void (* function)())390 inline Closure* NewPermanentCallback(void (*function)()) {
391 return new internal::FunctionClosure0(function, false);
392 }
393
394 // See Closure.
395 template <typename Class>
NewCallback(Class * object,void (Class::* method)())396 inline Closure* NewCallback(Class* object, void (Class::*method)()) {
397 return new internal::MethodClosure0<Class>(object, method, true);
398 }
399
400 // See Closure.
401 template <typename Class>
NewPermanentCallback(Class * object,void (Class::* method)())402 inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
403 return new internal::MethodClosure0<Class>(object, method, false);
404 }
405
406 // See Closure.
407 template <typename Arg1>
NewCallback(void (* function)(Arg1),Arg1 arg1)408 inline Closure* NewCallback(void (*function)(Arg1),
409 Arg1 arg1) {
410 return new internal::FunctionClosure1<Arg1>(function, true, arg1);
411 }
412
413 // See Closure.
414 template <typename Arg1>
NewPermanentCallback(void (* function)(Arg1),Arg1 arg1)415 inline Closure* NewPermanentCallback(void (*function)(Arg1),
416 Arg1 arg1) {
417 return new internal::FunctionClosure1<Arg1>(function, false, arg1);
418 }
419
420 // See Closure.
421 template <typename Class, typename Arg1>
NewCallback(Class * object,void (Class::* method)(Arg1),Arg1 arg1)422 inline 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.
428 template <typename Class, typename Arg1>
NewPermanentCallback(Class * object,void (Class::* method)(Arg1),Arg1 arg1)429 inline 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.
435 template <typename Arg1, typename Arg2>
NewCallback(void (* function)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)436 inline 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.
443 template <typename Arg1, typename Arg2>
NewPermanentCallback(void (* function)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)444 inline 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.
451 template <typename Class, typename Arg1, typename Arg2>
NewCallback(Class * object,void (Class::* method)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)452 inline 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.
459 template <typename Class, typename Arg1, typename Arg2>
NewPermanentCallback(Class * object,void (Class::* method)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)460 inline 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
468 template<typename R>
NewCallback(R (* function)())469 inline ResultCallback<R>* NewCallback(R (*function)()) {
470 return new internal::FunctionResultCallback_0_0<R>(function, true);
471 }
472
473 // See ResultCallback
474 template<typename R>
NewPermanentCallback(R (* function)())475 inline ResultCallback<R>* NewPermanentCallback(R (*function)()) {
476 return new internal::FunctionResultCallback_0_0<R>(function, false);
477 }
478
479 // See ResultCallback
480 template<typename R, typename P1>
NewCallback(R (* function)(P1),P1 p1)481 inline 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
487 template<typename R, typename P1>
NewPermanentCallback(R (* function)(P1),P1 p1)488 inline 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
495 template<typename R, typename A1>
NewCallback(R (* function)(A1))496 inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
497 return new internal::FunctionResultCallback_0_1<R, A1>(function, true);
498 }
499
500 // See ResultCallback1
501 template<typename R, typename A1>
NewPermanentCallback(R (* function)(A1))502 inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) {
503 return new internal::FunctionResultCallback_0_1<R, A1>(function, false);
504 }
505
506 // See ResultCallback1
507 template<typename R, typename P1, typename A1>
NewCallback(R (* function)(P1,A1),P1 p1)508 inline 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
514 template<typename R, typename P1, typename A1>
NewPermanentCallback(R (* function)(P1,A1),P1 p1)515 inline 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
522 template <typename R, typename T, typename P1, typename P2, typename P3,
523 typename P4, typename P5, typename A1, typename A2>
NewPermanentCallback(T * object,R (T::* function)(P1,P2,P3,P4,P5,A1,A2),typename internal::InternalConstRef<P1>::type p1,typename internal::InternalConstRef<P2>::type p2,typename internal::InternalConstRef<P3>::type p3,typename internal::InternalConstRef<P4>::type p4,typename internal::InternalConstRef<P5>::type p5)524 inline 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);
540 void LIBPROTOBUF_EXPORT DoNothing();
541
542
543 } // namespace protobuf
544 } // namespace google
545
546 #endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
547