callback.h 13 KB

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