#ifndef I18N_ADDRESSINPUT_CALLBACK_H_
#define I18N_ADDRESSINPUT_CALLBACK_H_
#include <libaddressinput/util/scoped_ptr.h>
#include <cassert>
#include <cstddef>
#include <string>
namespace i18n {
namespace addressinput {
template <typename Sig> class Callback;
template <typename ReturnType, typename RequestType, typename ResponseType>
class Callback<ReturnType(RequestType, ResponseType)> {
public:
virtual ~Callback() {}
virtual ReturnType operator()(bool success,
const RequestType& request,
const ResponseType& response) const = 0;
};
template <typename Sig> class ScopedPtrCallback;
template <typename ReturnType, typename RequestType, typename ResponseType>
class ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
public:
virtual ~ScopedPtrCallback() {}
virtual ReturnType operator()(bool success,
const RequestType& request,
scoped_ptr<ResponseType> response) const = 0;
};
namespace {
template <typename BaseType, typename ReturnType, typename RequestType,
typename ResponseType>
class CallbackImpl : public Callback<ReturnType(RequestType, ResponseType)> {
public:
typedef ReturnType (BaseType::*Method)(
bool, const RequestType&, const ResponseType&);
CallbackImpl(BaseType* instance, Method method)
: instance_(instance),
method_(method) {
assert(instance_ != NULL);
assert(method_ != NULL);
}
virtual ~CallbackImpl() {}
virtual ReturnType operator()(bool success,
const RequestType& request,
const ResponseType& response) const {
return (instance_->*method_)(success, request, response);
}
private:
BaseType* instance_;
Method method_;
};
template <typename BaseType, typename ReturnType, typename RequestType,
typename ResponseType>
class ScopedPtrCallbackImpl :
public ScopedPtrCallback<ReturnType(RequestType, ResponseType)> {
public:
typedef ReturnType (BaseType::*Method)(
bool, const RequestType&, scoped_ptr<ResponseType>);
ScopedPtrCallbackImpl(BaseType* instance, Method method)
: instance_(instance),
method_(method) {
assert(instance_ != NULL);
assert(method_ != NULL);
}
virtual ~ScopedPtrCallbackImpl() {}
virtual ReturnType operator()(bool success,
const RequestType& request,
scoped_ptr<ResponseType> response) const {
return (instance_->*method_)(success, request, response.Pass());
}
private:
BaseType* instance_;
Method method_;
};
}
template <typename BaseType, typename ReturnType, typename RequestType,
typename ResponseType>
scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> > BuildCallback(
BaseType* instance,
ReturnType (BaseType::*method)(
bool, const RequestType&, const ResponseType&)) {
return scoped_ptr<Callback<ReturnType(RequestType, ResponseType)> >(
new CallbackImpl<BaseType, ReturnType, RequestType, ResponseType>(
instance, method));
}
template <typename BaseType, typename ReturnType, typename RequestType,
typename ResponseType>
scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >
BuildScopedPtrCallback(
BaseType* instance,
ReturnType (BaseType::*method)(
bool, const RequestType&, scoped_ptr<ResponseType>)) {
return scoped_ptr<ScopedPtrCallback<ReturnType(RequestType, ResponseType)> >(
new ScopedPtrCallbackImpl<BaseType, ReturnType, RequestType,
ResponseType>(
instance, method));
}
}
}
#endif