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