Home | History | Annotate | Download | only in stubs
      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