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