15 #ifndef TLX_DELEGATE_HEADER 16 #define TLX_DELEGATE_HEADER 22 #include <type_traits> 27 template <
typename T,
typename Allocator = std::allocator<
void> >
90 template <
typename R,
typename... A,
typename Allocator>
113 template <R(*
const Function)(A...)>
115 return Delegate(function_caller<Function>,
nullptr);
124 explicit Delegate(R(*
const function_ptr)(A...)) noexcept
126 *reinterpret_cast<
void* const*>(&function_ptr)) { }
128 static_assert(
sizeof(
void*) ==
sizeof(
void (*)(
void)),
129 "object pointer and function pointer sizes must equal");
142 template <
class C, R(C::*
const Method)(A...)>
144 return Delegate(method_caller<C, Method>, object_ptr);
148 template <
class C, R(C::*
const Method)(A...)
const>
150 return Delegate(const_method_caller<C, Method>,
151 const_cast<C*>(object_ptr));
156 template <
class C, R(C::*
const Method)(A...)>
158 return Delegate(method_caller<C, Method>, &
object);
163 template <
class C, R(C::*
const Method)(A...)
const>
165 return Delegate(const_method_caller<C, Method>,
166 const_cast<C*>(&
object));
178 typename =
typename std::enable_if<
179 !std::is_same<Delegate, typename std::decay<T>::type>::value
185 typename
std::allocator_traits<Allocator>::template rebind_alloc<
186 typename
std::decay<T>::type>{}.allocate(1),
187 store_deleter<typename std::decay<T>::type>, Allocator()) {
189 using Functor =
typename std::decay<T>::type;
190 using Rebind =
typename std::allocator_traits<Allocator>::template rebind_alloc<Functor>;
194 std::allocator_traits<Rebind>::construct(
195 rebind, static_cast<Functor*>(store_.get()), Functor(std::forward<T>(f)));
197 object_ptr_ = store_.get();
199 caller_ = functor_caller<Functor>;
204 template <
typename T>
206 return std::forward<T>(f);
211 Delegate(C*
const object_ptr, R(C::*
const method_ptr)(A...))
216 Delegate(C*
const object_ptr, R(C::*
const method_ptr)(A...)
const)
221 Delegate(C&
object, R(C::*
const method_ptr)(A...))
226 Delegate(C
const&
object, R(C::*
const method_ptr)(A...)
const)
232 R(C::*
const method_ptr)(A...)) {
239 R(C::*
const method_ptr)(A...)
const) {
252 R(C::*
const method_ptr)(A...)
const) {
262 void reset() { caller_ =
nullptr; store_.reset(); }
271 return (object_ptr_ == rhs.object_ptr_) && (caller_ == rhs.caller_);
281 return (object_ptr_ < rhs.object_ptr_) ||
282 ((object_ptr_ == rhs.object_ptr_) && (caller_ < rhs.caller_));
287 return caller_ ==
nullptr;
292 return caller_ !=
nullptr;
296 explicit operator bool () const noexcept {
return caller_ !=
nullptr; }
300 R operator () (A... args)
const {
302 return caller_(object_ptr_, std::forward<A>(args) ...);
323 void* object_ptr_ =
nullptr;
331 : caller_(m), object_ptr_(obj) { }
334 template <
typename T>
336 using Rebind =
typename std::allocator_traits<Allocator>::template rebind_alloc<T>;
339 std::allocator_traits<Rebind>::destroy(rebind, static_cast<T*>(ptr));
340 std::allocator_traits<Rebind>::deallocate(rebind, static_cast<T*>(ptr), 1);
347 template <R(* Function)(A...)>
349 return Function(std::forward<A>(args) ...);
354 return (*
reinterpret_cast<R(* const*)(A...)
>(&object_ptr))(args...);
358 template <
class C, R(C::* method_ptr)(A...)>
360 return (static_cast<C*>(object_ptr)->*method_ptr)(
361 std::forward<A>(args) ...);
365 template <
class C, R(C::* method_ptr)(A...)
const>
367 return (static_cast<C const*>(object_ptr)->*method_ptr)(
368 std::forward<A>(args) ...);
380 std::pair<C*
const, R(C::*
const)(A...)>;
386 std::pair<C
const*
const, R(C::*
const)(A...)
const>;
390 struct IsMemberPair : std::false_type { };
398 struct IsConstMemberPair : std::false_type { };
405 template <
typename T>
406 static typename std::enable_if<
407 !(IsMemberPair<T>::value || IsConstMemberPair<T>::value), R
410 return (*static_cast<T*>(object_ptr))(std::forward<A>(args) ...);
414 template <
typename T>
415 static typename std::enable_if<
416 (IsMemberPair<T>::value || IsConstMemberPair<T>::value), R
419 return (static_cast<T*>(object_ptr)->first->*
420 static_cast<T*
>(object_ptr)->second)(std::forward<A>(args) ...);
427 template <
typename T,
typename Allocator = std::allocator<
void> >
431 template <
class C,
typename R,
typename... A>
434 C*
const object_ptr, R(C::*
const method_ptr)(A...)) noexcept {
435 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
439 template <
class C,
typename R,
typename... A>
442 C*
const object_ptr, R(C::*
const method_ptr)(A...)
const) noexcept {
443 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
447 template <
class C,
typename R,
typename... A>
450 C& object_ptr, R(C::*
const method_ptr)(A...)) noexcept {
451 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
455 template <
class C,
typename R,
typename... A>
458 C
const& object_ptr, R(C::*
const method_ptr)(A...)
const) noexcept {
459 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
464 #endif // !TLX_DELEGATE_HEADER Delegate(const Caller &m, void *const obj) noexcept
private constructor for plain
static Delegate make(C const *const object_ptr, R(C::*const method_ptr)(A...) const)
constructor for wrapping a const class::method with object pointer.
Delegate(C const &object, R(C::*const method_ptr)(A...) const)
constructor for wrapping a const class::method with object reference.
static Delegate make(C *const object_ptr) noexcept
construction for an immediate class::method with class object
static Delegate make(C *const object_ptr, R(C::*const method_ptr)(A...))
constructor for wrapping a class::method with object pointer.
void reset()
reset delegate to invalid.
static std::enable_if< !(IsMemberPair< T >::value||IsConstMemberPair< T >::value), R >::type functor_caller(void *const object_ptr, A &&...args)
function caller for functor class.
Delegate< R(A...)> make_delegate(C *const object_ptr, R(C::*const method_ptr)(A...)) noexcept
constructor for wrapping a class::method with object pointer.
static std::enable_if< (IsMemberPair< T >::value||IsConstMemberPair< T >::value), R >::type functor_caller(void *const object_ptr, A &&...args)
function caller for const functor class.
static void store_deleter(void *const ptr)
deleter for stored functor closures
static bool operator!=(const StringView &a, const std::string &b) noexcept
inequality operator to compare a StringView with a std::string
void reset_caller() noexcept
static R const_method_caller(void *const object_ptr, A &&...args)
function caller for immediate const class::method functions calls.
std::pair< C const *const, R(C::*const)(A...) const > ConstMemberPair
wrappers for indirect const class::method calls containing (object, const method_ptr) ...
Delegate(R(*const function_ptr)(A...)) noexcept
constructor from a plain function pointer with no object.
static R method_caller(void *const object_ptr, A &&...args)
function caller for immediate class::method function calls
std::shared_ptr< void > store_
shared_ptr used to contain a memory object containing the callable, like lambdas with closures...
R(*)(void *, A &&...) Caller
type of the function caller pointer.
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
static Delegate make(C const *const object_ptr) noexcept
construction for an immediate class::method with class object
static Delegate make(T &&f)
constructor from any functor object T, which may be a lambda with capture or a MemberPair or ConstMem...
Delegate(C &object, R(C::*const method_ptr)(A...))
constructor for wrapping a class::method with object reference.
static Delegate make(C const &object) noexcept
construction for an immediate class::method with class object by reference
void swap(Delegate &other) noexcept
swap delegates
static bool operator==(const StringView &a, const std::string &b) noexcept
equality operator to compare a StringView with a std::string
Delegate(C *const object_ptr, R(C::*const method_ptr)(A...) const)
constructor for wrapping a const class::method with object pointer.
static R function_ptr_caller(void *const object_ptr, A &&...args)
caller for a plain function pointer.
static Delegate make(C const &object, R(C::*const method_ptr)(A...) const)
constructor for wrapping a const class::method with object reference.
Delegate(C *const object_ptr, R(C::*const method_ptr)(A...))
constructor for wrapping a class::method with object pointer.
Delegate(T &&f)
constructor from any functor object T, which may be a lambda with capture or a MemberPair or ConstMem...
static Delegate make(C &object) noexcept
construction for an immediate class::method with class object by reference
static bool operator<(const StringView &a, const std::string &b) noexcept
less operator to compare a StringView with a std::string lexicographically
static Delegate make(C &object, R(C::*const method_ptr)(A...))
constructor for wrapping a class::method with object reference.
static Delegate make(R(*const function_ptr)(A...)) noexcept
construction from a plain function pointer with no object.
std::pair< C *const, R(C::*const)(A...)> MemberPair
wrappers for indirect class::method calls containing (object, method_ptr)
static R function_caller(void *const, A &&...args)
caller for an immediate function with no object or pointer.
static Delegate make() noexcept
construction from an immediate function with no object or pointer.