49template <
class R,
class... A>
class delegate<R(A...)> {
50 using stub_ptr_type = R (*)(
void*, A&&...);
52 delegate(
void*
const o, stub_ptr_type
const m) noexcept
59 delegate(delegate
const&) =
default;
61 delegate(delegate&&) =
default;
63 delegate(::std::nullptr_t
const) noexcept
66 template <
class C,
typename =
typename ::std::enable_if<::std::is_
class<C>{}>::type>
67 explicit delegate(C
const*
const o) noexcept
68 : object_ptr_(
const_cast<C*
>(o)) {}
70 template <
class C,
typename =
typename ::std::enable_if<::std::is_
class<C>{}>::type>
71 explicit delegate(C
const& o) noexcept
72 : object_ptr_(
const_cast<C*
>(&o)) {}
74 template <
class C> delegate(C*
const object_ptr, R (C::*
const method_ptr)(A...)) { *
this = from(object_ptr, method_ptr); }
76 template <
class C> delegate(C*
const object_ptr, R (C::*
const method_ptr)(A...)
const) { *
this = from(object_ptr, method_ptr); }
78 template <
class C> delegate(C&
object, R (C::*
const method_ptr)(A...)) { *
this = from(
object, method_ptr); }
80 template <
class C> delegate(C
const&
object, R (C::*
const method_ptr)(A...)
const) { *
this = from(
object, method_ptr); }
82 template <typename T, typename = typename ::std::enable_if<!::std::is_same<delegate, typename ::std::decay<T>::type>{}>::type>
84 : store_(
operator new(
sizeof(typename ::std::decay<T>::type)), functor_deleter<typename ::std::decay<T>::type>)
85 , store_size_(
sizeof(typename ::std::decay<T>::type)) {
86 using functor_type = typename ::std::decay<T>::type;
88 new(store_.get()) functor_type(::std::forward<T>(f));
90 object_ptr_ = store_.get();
92 stub_ptr_ = functor_stub<functor_type>;
94 deleter_ = deleter_stub<functor_type>;
97 delegate& operator=(delegate
const&) =
default;
99 delegate& operator=(delegate&&) =
default;
101 template <
class C> delegate& operator=(R (C::*
const rhs)(A...)) {
return *
this = from(
static_cast<C*
>(object_ptr_), rhs); }
103 template <
class C> delegate& operator=(R (C::*
const rhs)(A...)
const) {
return *
this = from(
static_cast<C const*
>(object_ptr_), rhs); }
105 template <typename T, typename = typename ::std::enable_if<!::std::is_same<delegate, typename ::std::decay<T>::type>{}>::type>
106 delegate& operator=(T&& f) {
107 using functor_type = typename ::std::decay<T>::type;
109 if((
sizeof(functor_type) > store_size_) || !store_.unique()) {
110 store_.reset(
operator new(
sizeof(functor_type)), functor_deleter<functor_type>);
112 store_size_ =
sizeof(functor_type);
114 deleter_(store_.get());
117 new(store_.get()) functor_type(::std::forward<T>(f));
119 object_ptr_ = store_.get();
121 stub_ptr_ = functor_stub<functor_type>;
123 deleter_ = deleter_stub<functor_type>;
128 template <R (*
const function_ptr)(A...)>
static delegate from()
noexcept {
return {
nullptr, function_stub<function_ptr>}; }
130 template <
class C, R (C::*
const method_ptr)(A...)>
static delegate from(C*
const object_ptr)
noexcept {
131 return {object_ptr, method_stub<C, method_ptr>};
134 template <
class C, R (C::*
const method_ptr)(A...)
const>
static delegate from(C
const*
const object_ptr)
noexcept {
135 return {
const_cast<C*
>(object_ptr), const_method_stub<C, method_ptr>};
138 template <
class C, R (C::*
const method_ptr)(A...)>
static delegate from(C&
object)
noexcept {
139 return {&object, method_stub<C, method_ptr>};
142 template <
class C, R (C::*
const method_ptr)(A...)
const>
static delegate from(C
const&
object)
noexcept {
143 return {
const_cast<C*
>(&object), const_method_stub<C, method_ptr>};
146 template <
typename T>
static delegate from(T&& f) { return ::std::forward<T>(f); }
148 static delegate from(R (*
const function_ptr)(A...)) {
return function_ptr; }
150 template <
class C>
using member_pair = ::std::pair<C*
const, R (C::*
const)(A...)>;
152 template <
class C>
using const_member_pair = ::std::pair<C
const*
const, R (C::*
const)(A...)
const>;
154 template <
class C>
static delegate from(C*
const object_ptr, R (C::*
const method_ptr)(A...)) {
155 return member_pair<C>(object_ptr, method_ptr);
158 template <
class C>
static delegate from(C
const*
const object_ptr, R (C::*
const method_ptr)(A...)
const) {
159 return const_member_pair<C>(object_ptr, method_ptr);
162 template <
class C>
static delegate from(C&
object, R (C::*
const method_ptr)(A...)) {
return member_pair<C>(&
object, method_ptr); }
164 template <
class C>
static delegate from(C
const&
object, R (C::*
const method_ptr)(A...)
const) {
165 return const_member_pair<C>(&
object, method_ptr);
173 void reset_stub()
noexcept { stub_ptr_ =
nullptr; }
175 void swap(delegate& other)
noexcept { ::std::swap(*
this, other); }
177 bool operator==(delegate
const& rhs)
const noexcept {
return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_); }
179 bool operator!=(delegate
const& rhs)
const noexcept {
return !operator==(rhs); }
181 bool operator<(delegate
const& rhs)
const noexcept {
182 return (object_ptr_ < rhs.object_ptr_) || ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
185 bool operator==(::std::nullptr_t
const)
const noexcept {
return !stub_ptr_; }
187 bool operator!=(::std::nullptr_t
const)
const noexcept {
return stub_ptr_; }
189 explicit operator bool()
const noexcept {
return stub_ptr_; }
191 R operator()(A... args)
const {
193 return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
197 friend struct ::std::hash<delegate>;
199 using deleter_type = void (*)(
void*);
201 void* object_ptr_{
nullptr};
202 stub_ptr_type stub_ptr_{};
204 deleter_type deleter_{};
206 ::std::shared_ptr<void> store_;
207 ::std::size_t store_size_{0};
209 template <
class T>
static void functor_deleter(
void*
const p) {
210 static_cast<T*
>(p)->~T();
215 template <
class T>
static void deleter_stub(
void*
const p) {
static_cast<T*
>(p)->~T(); }
217 template <R (*function_ptr)(A...)>
static R function_stub(
void*
const, A&&... args) {
return function_ptr(::std::forward<A>(args)...); }
219 template <
class C, R (C::*method_ptr)(A...)>
static R method_stub(
void*
const object_ptr, A&&... args) {
220 return (
static_cast<C*
>(object_ptr)->*method_ptr)(::std::forward<A>(args)...);
223 template <
class C, R (C::*method_ptr)(A...)
const>
static R const_method_stub(
void*
const object_ptr, A&&... args) {
224 return (
static_cast<C const*
>(object_ptr)->*method_ptr)(::std::forward<A>(args)...);
227 template <
typename>
struct is_member_pair : std::false_type {};
229 template <
class C>
struct is_member_pair<::std::pair<C* const, R (C::*const)(A...)>> : std::true_type {};
231 template <
typename>
struct is_const_member_pair : std::false_type {};
233 template <
class C>
struct is_const_member_pair<::std::pair<C const* const, R (C::*const)(A...) const>> : std::true_type {};
235 template <
typename T>
236 static typename ::std::enable_if<!(is_member_pair<T>{} || is_const_member_pair<T>{}), R>::type functor_stub(
void*
const object_ptr,
238 return (*
static_cast<T*
>(object_ptr))(::std::forward<A>(args)...);
241 template <
typename T>
242 static typename ::std::enable_if<is_member_pair<T>{} || is_const_member_pair<T>{}, R>::type functor_stub(
void*
const object_ptr,
244 return (
static_cast<T*
>(object_ptr)->first->*
static_cast<T*
>(object_ptr)->second)(::std::forward<A>(args)...);