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