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