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: 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: 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 94 CallbackImpl(BaseType* instance, Method method) 95 : instance_(instance), 96 method_(method) { 97 assert(instance_ != NULL); 98 assert(method_ != NULL); 99 } 100 101 virtual ~CallbackImpl() {} 102 103 // Callback implementation. 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 123 ScopedPtrCallbackImpl(BaseType* instance, Method method) 124 : instance_(instance), 125 method_(method) { 126 assert(instance_ != NULL); 127 assert(method_ != NULL); 128 } 129 130 virtual ~ScopedPtrCallbackImpl() {} 131 132 // ScopedPtrCallback implementation. 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> 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)> > 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