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