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;
87 new(store_.get()) functor_type(::std::forward<T>(f));
88 object_ptr_ = store_.get();
89 stub_ptr_ = functor_stub<functor_type>;
90 deleter_ = deleter_stub<functor_type>;
93 delegate& operator=(delegate
const&) =
default;
95 delegate& operator=(delegate&&) =
default;
97 template <
class C> delegate& operator=(R (C::*
const rhs)(A...)) {
return *
this = from(
static_cast<C*
>(object_ptr_), rhs); }
99 template <
class C> delegate& operator=(R (C::*
const rhs)(A...)
const) {
return *
this = from(
static_cast<C const*
>(object_ptr_), rhs); }
101 template <typename T, typename = typename ::std::enable_if<!::std::is_same<delegate, typename ::std::decay<T>::type>{}>::type>
102 delegate& operator=(T&& f) {
103 using functor_type = typename ::std::decay<T>::type;
105 if((
sizeof(functor_type) > store_size_) || store_.use_count() != 1) {
106 store_.reset(
operator new(
sizeof(functor_type)), functor_deleter<functor_type>);
107 store_size_ =
sizeof(functor_type);
109 deleter_(store_.get());
112 new(store_.get()) functor_type(::std::forward<T>(f));
114 object_ptr_ = store_.get();
116 stub_ptr_ = functor_stub<functor_type>;
118 deleter_ = deleter_stub<functor_type>;
123 template <R (*
const function_ptr)(A...)>
static delegate from()
noexcept {
return {
nullptr, function_stub<function_ptr>}; }
125 template <
class C, R (C::*
const method_ptr)(A...)>
static delegate from(C*
const object_ptr)
noexcept {
126 return {object_ptr, method_stub<C, method_ptr>};
129 template <
class C, R (C::*
const method_ptr)(A...)
const>
static delegate from(C
const*
const object_ptr)
noexcept {
130 return {
const_cast<C*
>(object_ptr), const_method_stub<C, method_ptr>};
133 template <
class C, R (C::*
const method_ptr)(A...)>
static delegate from(C&
object)
noexcept {
134 return {&object, method_stub<C, method_ptr>};
137 template <
class C, R (C::*
const method_ptr)(A...)
const>
static delegate from(C
const&
object)
noexcept {
138 return {
const_cast<C*
>(&object), const_method_stub<C, method_ptr>};
141 template <
typename T>
static delegate from(T&& f) { return ::std::forward<T>(f); }
143 static delegate from(R (*
const function_ptr)(A...)) {
return function_ptr; }
145 template <
class C>
using member_pair = ::std::pair<C*
const, R (C::*
const)(A...)>;
147 template <
class C>
using const_member_pair = ::std::pair<C
const*
const, R (C::*
const)(A...)
const>;
149 template <
class C>
static delegate from(C*
const object_ptr, R (C::*
const method_ptr)(A...)) {
150 return member_pair<C>(object_ptr, method_ptr);
153 template <
class C>
static delegate from(C
const*
const object_ptr, R (C::*
const method_ptr)(A...)
const) {
154 return const_member_pair<C>(object_ptr, method_ptr);
157 template <
class C>
static delegate from(C&
object, R (C::*
const method_ptr)(A...)) {
return member_pair<C>(&
object, method_ptr); }
159 template <
class C>
static delegate from(C
const&
object, R (C::*
const method_ptr)(A...)
const) {
160 return const_member_pair<C>(&
object, method_ptr);
168 void reset_stub()
noexcept { stub_ptr_ =
nullptr; }
170 void swap(delegate& other)
noexcept { ::std::swap(*
this, other); }
172 bool operator==(delegate
const& rhs)
const noexcept {
return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_); }
174 bool operator!=(delegate
const& rhs)
const noexcept {
return !operator==(rhs); }
176 bool operator<(delegate
const& rhs)
const noexcept {
177 return (object_ptr_ < rhs.object_ptr_) || ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
180 bool operator==(::std::nullptr_t
const)
const noexcept {
return !stub_ptr_; }
182 bool operator!=(::std::nullptr_t
const)
const noexcept {
return stub_ptr_; }
184 explicit operator bool()
const noexcept {
return stub_ptr_; }
186 R operator()(A... args)
const {
188 return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
192 friend struct ::std::hash<delegate>;
194 using deleter_type = void (*)(
void*);
196 void* object_ptr_{
nullptr};
197 stub_ptr_type stub_ptr_{
nullptr};
199 deleter_type deleter_{};
201 ::std::shared_ptr<void> store_;
202 ::std::size_t store_size_{0};
204 template <
class T>
static void functor_deleter(
void*
const p) {
205 static_cast<T*
>(p)->~T();
210 template <
class T>
static void deleter_stub(
void*
const p) {
static_cast<T*
>(p)->~T(); }
212 template <R (*function_ptr)(A...)>
static R function_stub(
void*
const, A&&... args) {
return function_ptr(::std::forward<A>(args)...); }
214 template <
class C, R (C::*method_ptr)(A...)>
static R method_stub(
void*
const object_ptr, A&&... args) {
215 return (
static_cast<C*
>(object_ptr)->*method_ptr)(::std::forward<A>(args)...);
218 template <
class C, R (C::*method_ptr)(A...)
const>
static R const_method_stub(
void*
const object_ptr, A&&... args) {
219 return (
static_cast<C const*
>(object_ptr)->*method_ptr)(::std::forward<A>(args)...);
222 template <
typename>
struct is_member_pair : std::false_type {};
224 template <
class C>
struct is_member_pair<::std::pair<C* const, R (C::*const)(A...)>> : std::true_type {};
226 template <
typename>
struct is_const_member_pair : std::false_type {};
228 template <
class C>
struct is_const_member_pair<::std::pair<C const* const, R (C::*const)(A...) const>> : std::true_type {};
230 template <
typename T>
231 static typename ::std::enable_if<!(is_member_pair<T>{} || is_const_member_pair<T>{}), R>::type functor_stub(
void*
const object_ptr,
233 return (*
static_cast<T*
>(object_ptr))(::std::forward<A>(args)...);
236 template <
typename T>
237 static typename ::std::enable_if<is_member_pair<T>{} || is_const_member_pair<T>{}, R>::type functor_stub(
void*
const object_ptr,
239 return (
static_cast<T*
>(object_ptr)->first->*
static_cast<T*
>(object_ptr)->second)(::std::forward<A>(args)...);