• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2013 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef I18N_ADDRESSINPUT_CALLBACK_H_
16 #define I18N_ADDRESSINPUT_CALLBACK_H_
17 
18 #include <libaddressinput/util/scoped_ptr.h>
19 
20 #include <cassert>
21 #include <cstddef>
22 #include <string>
23 
24 namespace i18n {
25 namespace addressinput {
26 
27 // Stores a pointer to a method in an object. Sample usage:
28 //    class MyClass {
29 //     public:
30 //      typedef Callback<std::string, std::string> MyConstRefCallback;
31 //      typedef ScopdedPtrCallback<std::string, MyDataType> MyScopedPtrCallback;
32 //
33 //      void GetStringAsynchronously() {
34 //        scoped_ptr<MyCallback> callback(BuildCallback(
35 //            this, &MyClass::OnStringReady));
36 //        bool success = ...
37 //        std::string key = ...
38 //        std::string data = ...
39 //        (*callback)(success, key, data);
40 //      }
41 //
42 //      void GetDataAsynchronously() {
43 //        scoped_ptr<MyScopedPtrCallback> callback(BuildScopedPtrCallback(
44 //            this, &MyClass::OnDataReady));
45 //        bool success = ...
46 //        std::string key = ...
47 //        scoped_ptr<MyDataType> data = ...
48 //        (*callback)(success, key, data.Pass());
49 //      }
50 //
51 //      void OnStringReady(bool success,
52 //                         const std::string& key,
53 //                         const std::string& data) {
54 //        ...
55 //      }
56 //
57 //      void OnDataReady(bool success,
58 //                       const std::string& key,
59 //                       scoped_ptr<MyDataType> data) {
60 //        ...
61 //      }
62 //    };
63 template <typename Sig> class Callback;
64 template <typename ReturnType, typename RequestType, typename ResponseType>
65 class Callback<ReturnType(RequestType, ResponseType)> {
66  public:
~Callback()67   virtual ~Callback() {}
68 
69   virtual ReturnType operator()(bool success,
70                                 const RequestType& request,
71                                 const ResponseType& response) const = 0;
72 };
73 
74 template <typename Sig> class ScopedPtrCallback;
75 template <typename ReturnType, typename RequestType, typename ResponseType>
76 class ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
77  public:
~ScopedPtrCallback()78   virtual ~ScopedPtrCallback() {}
79 
80   virtual ReturnType operator()(bool success,
81                                 const RequestType& request,
82                                 scoped_ptr<ResponseType> response) const = 0;
83 };
84 
85 namespace {
86 
87 template <typename BaseType, typename ReturnType, typename RequestType,
88           typename ResponseType>
89 class CallbackImpl : public Callback<ReturnType(RequestType, ResponseType)> {
90  public:
91   typedef ReturnType (BaseType::*Method)(
92       bool, const RequestType&, const ResponseType&);
93 
CallbackImpl(BaseType * instance,Method method)94   CallbackImpl(BaseType* instance, Method method)
95       : instance_(instance),
96         method_(method) {
97     assert(instance_ != NULL);
98     assert(method_ != NULL);
99   }
100 
~CallbackImpl()101   virtual ~CallbackImpl() {}
102 
103   // Callback implementation.
operator()104   virtual ReturnType operator()(bool success,
105                                 const RequestType& request,
106                                 const ResponseType& response) const {
107     return (instance_->*method_)(success, request, response);
108   }
109 
110  private:
111   BaseType* instance_;
112   Method method_;
113 };
114 
115 template <typename BaseType, typename ReturnType, typename RequestType,
116           typename ResponseType>
117 class ScopedPtrCallbackImpl :
118     public ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
119  public:
120   typedef ReturnType (BaseType::*Method)(
121       bool, const RequestType&, scoped_ptr<ResponseType>);
122 
ScopedPtrCallbackImpl(BaseType * instance,Method method)123   ScopedPtrCallbackImpl(BaseType* instance, Method method)
124       : instance_(instance),
125         method_(method) {
126     assert(instance_ != NULL);
127     assert(method_ != NULL);
128   }
129 
~ScopedPtrCallbackImpl()130   virtual ~ScopedPtrCallbackImpl() {}
131 
132   // ScopedPtrCallback implementation.
operator()133   virtual ReturnType operator()(bool success,
134                                 const RequestType& request,
135                                 scoped_ptr<ResponseType> response) const {
136     return (instance_->*method_)(success, request, response.Pass());
137   }
138 
139  private:
140   BaseType* instance_;
141   Method method_;
142 };
143 
144 }  // namespace
145 
146 // Returns a callback to |instance->method| with constant reference to data.
147 template <typename BaseType, typename ReturnType, typename RequestType,
148           typename ResponseType>
BuildCallback(BaseType * instance,ReturnType (BaseType::* method)(bool,const RequestType &,const ResponseType &))149 scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> > BuildCallback(
150     BaseType* instance,
151     ReturnType (BaseType::*method)(
152         bool, const RequestType&, const ResponseType&)) {
153   return scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> >(
154       new CallbackImpl<BaseType, ReturnType, RequestType, ResponseType>(
155           instance, method));
156 }
157 
158 // Returns a callback to |instance->method| with scoped pointer to data.
159 template <typename BaseType, typename ReturnType, typename RequestType,
160           typename ResponseType>
161 scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >
BuildScopedPtrCallback(BaseType * instance,ReturnType (BaseType::* method)(bool,const RequestType &,scoped_ptr<ResponseType>))162 BuildScopedPtrCallback(
163     BaseType* instance,
164     ReturnType (BaseType::*method)(
165         bool, const RequestType&, scoped_ptr<ResponseType>)) {
166   return scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >(
167       new ScopedPtrCallbackImpl<BaseType, ReturnType, RequestType,
168                                 ResponseType>(
169           instance, method));
170 }
171 
172 }  // namespace addressinput
173 }  // namespace i18n
174 
175 #endif  // I18N_ADDRESSINPUT_CALLBACK_H_
176