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