1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright (C) 2013 Google Inc.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Licensed under the Apache License, Version 2.0 (the "License");
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// you may not use this file except in compliance with the License.
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// You may obtain a copy of the License at
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// http://www.apache.org/licenses/LICENSE-2.0
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Unless required by applicable law or agreed to in writing, software
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// distributed under the License is distributed on an "AS IS" BASIS,
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// See the License for the specific language governing permissions and
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// limitations under the License.
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef I18N_ADDRESSINPUT_CALLBACK_H_
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define I18N_ADDRESSINPUT_CALLBACK_H_
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <libaddressinput/util/scoped_ptr.h>
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <cassert>
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <cstddef>
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace i18n {
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace addressinput {
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Stores a pointer to a method in an object. Sample usage:
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//    class MyClass {
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//     public:
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      typedef Callback<std::string, std::string> MyConstRefCallback;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      typedef ScopdedPtrCallback<std::string, MyDataType> MyScopedPtrCallback;
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      void GetStringAsynchronously() {
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//        scoped_ptr<MyCallback> callback(BuildCallback(
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//            this, &MyClass::OnStringReady));
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//        bool success = ...
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        std::string key = ...
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        std::string data = ...
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//        (*callback)(success, key, data);
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//      }
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      void GetDataAsynchronously() {
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        scoped_ptr<MyScopedPtrCallback> callback(BuildScopedPtrCallback(
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//            this, &MyClass::OnDataReady));
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        bool success = ...
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        std::string key = ...
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        scoped_ptr<MyDataType> data = ...
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        (*callback)(success, key, data.Pass());
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      void OnStringReady(bool success,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                         const std::string& key,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                         const std::string& data) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//        ...
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//      }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//      void OnDataReady(bool success,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                       const std::string& key,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                       scoped_ptr<MyDataType> data) {
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//        ...
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//      }
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//    };
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Sig> class Callback;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename ReturnType, typename RequestType, typename ResponseType>
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class Callback<ReturnType(RequestType, ResponseType)> {
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~Callback() {}
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ReturnType operator()(bool success,
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const RequestType& request,
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const ResponseType& response) const = 0;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Sig> class ScopedPtrCallback;
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename ReturnType, typename RequestType, typename ResponseType>
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ScopedPtrCallback() {}
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ReturnType operator()(bool success,
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const RequestType& request,
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                scoped_ptr<ResponseType> response) const = 0;
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename BaseType, typename ReturnType, typename RequestType,
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          typename ResponseType>
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CallbackImpl : public Callback<ReturnType(RequestType, ResponseType)> {
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef ReturnType (BaseType::*Method)(
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool, const RequestType&, const ResponseType&);
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CallbackImpl(BaseType* instance, Method method)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : instance_(instance),
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        method_(method) {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(instance_ != NULL);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(method_ != NULL);
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~CallbackImpl() {}
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Callback implementation.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ReturnType operator()(bool success,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const RequestType& request,
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const ResponseType& response) const {
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return (instance_->*method_)(success, request, response);
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BaseType* instance_;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Method method_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename BaseType, typename ReturnType, typename RequestType,
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          typename ResponseType>
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedPtrCallbackImpl :
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    public ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef ReturnType (BaseType::*Method)(
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool, const RequestType&, scoped_ptr<ResponseType>);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedPtrCallbackImpl(BaseType* instance, Method method)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : instance_(instance),
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        method_(method) {
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(instance_ != NULL);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(method_ != NULL);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ScopedPtrCallbackImpl() {}
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ScopedPtrCallback implementation.
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ReturnType operator()(bool success,
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const RequestType& request,
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                scoped_ptr<ResponseType> response) const {
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return (instance_->*method_)(success, request, response.Pass());
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BaseType* instance_;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Method method_;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a callback to |instance->method| with constant reference to data.
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename BaseType, typename ReturnType, typename RequestType,
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          typename ResponseType>
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> > BuildCallback(
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BaseType* instance,
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReturnType (BaseType::*method)(
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        bool, const RequestType&, const ResponseType&)) {
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> >(
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new CallbackImpl<BaseType, ReturnType, RequestType, ResponseType>(
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          instance, method));
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a callback to |instance->method| with scoped pointer to data.
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename BaseType, typename ReturnType, typename RequestType,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          typename ResponseType>
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BuildScopedPtrCallback(
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BaseType* instance,
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ReturnType (BaseType::*method)(
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bool, const RequestType&, scoped_ptr<ResponseType>)) {
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >(
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new ScopedPtrCallbackImpl<BaseType, ReturnType, RequestType,
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                ResponseType>(
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          instance, method));
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace addressinput
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace i18n
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // I18N_ADDRESSINPUT_CALLBACK_H_
176