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