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