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
13namespace google {
14namespace 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.
73class PROTOBUF_EXPORT Closure {
74 public:
75 Closure() {}
76 virtual ~Closure();
77
78 virtual void Run() = 0;
79
80 private:
81 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
82};
83
84template<typename R>
85class ResultCallback {
86 public:
87 ResultCallback() {}
88 virtual ~ResultCallback() {}
89
90 virtual R Run() = 0;
91
92 private:
93 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback);
94};
95
96template <typename R, typename A1>
97class PROTOBUF_EXPORT ResultCallback1 {
98 public:
99 ResultCallback1() {}
100 virtual ~ResultCallback1() {}
101
102 virtual R Run(A1) = 0;
103
104 private:
105 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1);
106};
107
108template <typename R, typename A1, typename A2>
109class PROTOBUF_EXPORT ResultCallback2 {
110 public:
111 ResultCallback2() {}
112 virtual ~ResultCallback2() {}
113
114 virtual R Run(A1,A2) = 0;
115
116 private:
117 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2);
118};
119
120namespace internal {
121
122class PROTOBUF_EXPORT FunctionClosure0 : public Closure {
123 public:
124 typedef void (*FunctionType)();
125
126 FunctionClosure0(FunctionType function, bool self_deleting)
127 : function_(function), self_deleting_(self_deleting) {}
128 ~FunctionClosure0();
129
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
141template <typename Class>
142class MethodClosure0 : public Closure {
143 public:
144 typedef void (Class::*MethodType)();
145
146 MethodClosure0(Class* object, MethodType method, bool self_deleting)
147 : object_(object), method_(method), self_deleting_(self_deleting) {}
148 ~MethodClosure0() {}
149
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
162template <typename Arg1>
163class FunctionClosure1 : public Closure {
164 public:
165 typedef void (*FunctionType)(Arg1 arg1);
166
167 FunctionClosure1(FunctionType function, bool self_deleting,
168 Arg1 arg1)
169 : function_(function), self_deleting_(self_deleting),
170 arg1_(arg1) {}
171 ~FunctionClosure1() {}
172
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
185template <typename Class, typename Arg1>
186class MethodClosure1 : public Closure {
187 public:
188 typedef void (Class::*MethodType)(Arg1 arg1);
189
190 MethodClosure1(Class* object, MethodType method, bool self_deleting,
191 Arg1 arg1)
192 : object_(object), method_(method), self_deleting_(self_deleting),
193 arg1_(arg1) {}
194 ~MethodClosure1() {}
195
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
209template <typename Arg1, typename Arg2>
210class FunctionClosure2 : public Closure {
211 public:
212 typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
213
214 FunctionClosure2(FunctionType function, bool self_deleting,
215 Arg1 arg1, Arg2 arg2)
216 : function_(function), self_deleting_(self_deleting),
217 arg1_(arg1), arg2_(arg2) {}
218 ~FunctionClosure2() {}
219
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
233template <typename Class, typename Arg1, typename Arg2>
234class MethodClosure2 : public Closure {
235 public:
236 typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
237
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) {}
242 ~MethodClosure2() {}
243
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
258template<typename R>
259class FunctionResultCallback_0_0 : public ResultCallback<R> {
260 public:
261 typedef R (*FunctionType)();
262
263 FunctionResultCallback_0_0(FunctionType function, bool self_deleting)
264 : function_(function), self_deleting_(self_deleting) {}
265 ~FunctionResultCallback_0_0() {}
266
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
279template<typename R, typename P1>
280class FunctionResultCallback_1_0 : public ResultCallback<R> {
281 public:
282 typedef R (*FunctionType)(P1);
283
284 FunctionResultCallback_1_0(FunctionType function, bool self_deleting,
285 P1 p1)
286 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
287 ~FunctionResultCallback_1_0() {}
288
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
302template<typename R, typename Arg1>
303class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
304 public:
305 typedef R (*FunctionType)(Arg1 arg1);
306
307 FunctionResultCallback_0_1(FunctionType function, bool self_deleting)
308 : function_(function), self_deleting_(self_deleting) {}
309 ~FunctionResultCallback_0_1() {}
310
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
323template<typename R, typename P1, typename A1>
324class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
325 public:
326 typedef R (*FunctionType)(P1, A1);
327
328 FunctionResultCallback_1_1(FunctionType function, bool self_deleting,
329 P1 p1)
330 : function_(function), self_deleting_(self_deleting), p1_(p1) {}
331 ~FunctionResultCallback_1_1() {}
332
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
346template <typename T>
347struct InternalConstRef {
348 typedef typename std::remove_reference<T>::type base_type;
349 typedef const base_type& type;
350};
351
352template<typename R, typename T>
353class MethodResultCallback_0_0 : public ResultCallback<R> {
354 public:
355 typedef R (T::*MethodType)();
356 MethodResultCallback_0_0(T* object, MethodType method, bool self_deleting)
357 : object_(object),
358 method_(method),
359 self_deleting_(self_deleting) {}
360 ~MethodResultCallback_0_0() {}
361
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
375template <typename R, typename T, typename P1, typename P2, typename P3,
376 typename P4, typename P5, typename P6, typename A1, typename A2>
377class MethodResultCallback_6_2 : public ResultCallback2<R, A1, A2> {
378 public:
379 typedef R (T::*MethodType)(P1, P2, P3, P4, P5, P6, A1, A2);
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) {}
391 ~MethodResultCallback_6_2() {}
392
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.
415inline Closure* NewCallback(void (*function)()) {
416 return new internal::FunctionClosure0(function, true);
417}
418
419// See Closure.
420inline Closure* NewPermanentCallback(void (*function)()) {
421 return new internal::FunctionClosure0(function, false);
422}
423
424// See Closure.
425template <typename Class>
426inline Closure* NewCallback(Class* object, void (Class::*method)()) {
427 return new internal::MethodClosure0<Class>(object, method, true);
428}
429
430// See Closure.
431template <typename Class>
432inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
433 return new internal::MethodClosure0<Class>(object, method, false);
434}
435
436// See Closure.
437template <typename Arg1>
438inline Closure* NewCallback(void (*function)(Arg1),
439 Arg1 arg1) {
440 return new internal::FunctionClosure1<Arg1>(function, true, arg1);
441}
442
443// See Closure.
444template <typename Arg1>
445inline Closure* NewPermanentCallback(void (*function)(Arg1),
446 Arg1 arg1) {
447 return new internal::FunctionClosure1<Arg1>(function, false, arg1);
448}
449
450// See Closure.
451template <typename Class, typename Arg1>
452inline 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.
458template <typename Class, typename Arg1>
459inline 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.
465template <typename Arg1, typename Arg2>
466inline 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.
473template <typename Arg1, typename Arg2>
474inline 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.
481template <typename Class, typename Arg1, typename Arg2>
482inline 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.
489template <typename Class, typename Arg1, typename Arg2>
490inline 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
498template<typename R>
499inline ResultCallback<R>* NewCallback(R (*function)()) {
500 return new internal::FunctionResultCallback_0_0<R>(function, true);
501}
502
503// See ResultCallback
504template<typename R>
505inline ResultCallback<R>* NewPermanentCallback(R (*function)()) {
506 return new internal::FunctionResultCallback_0_0<R>(function, false);
507}
508
509// See ResultCallback
510template<typename R, typename P1>
511inline 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
517template<typename R, typename P1>
518inline 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
525template<typename R, typename A1>
526inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
527 return new internal::FunctionResultCallback_0_1<R, A1>(function, true);
528}
529
530// See ResultCallback1
531template<typename R, typename A1>
532inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) {
533 return new internal::FunctionResultCallback_0_1<R, A1>(function, false);
534}
535
536// See ResultCallback1
537template<typename R, typename P1, typename A1>
538inline 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
544template<typename R, typename P1, typename A1>
545inline 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
552template <typename R, typename T1, typename T2>
553inline 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
559template <typename R, typename T, typename P1, typename P2, typename P3,
560 typename P4, typename P5, typename P6, typename A1, typename A2>
561inline 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);
576void 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