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 Allocator::template rebind<
186 typename
std::decay<
T>::type>::other().allocate(1),
187 store_deleter<typename
std::decay<
T>::type>, Allocator()) {
189 using Functor =
typename std::decay<T>::type;
190 using Rebind =
typename Allocator::template rebind<Functor>::other;
194 static_cast<Functor*>(store_.get()), Functor(std::forward<T>(f)));
196 object_ptr_ = store_.get();
198 caller_ = functor_caller<Functor>;
203 template <
typename T>
205 return std::forward<T>(f);
210 Delegate(C*
const object_ptr, R(C::*
const method_ptr)(A...))
215 Delegate(C*
const object_ptr, R(C::*
const method_ptr)(A...)
const)
220 Delegate(C&
object, R(C::*
const method_ptr)(A...))
225 Delegate(C
const&
object, R(C::*
const method_ptr)(A...)
const)
231 R(C::*
const method_ptr)(A...)) {
238 R(C::*
const method_ptr)(A...)
const) {
251 R(C::*
const method_ptr)(A...)
const) {
261 void reset() { caller_ =
nullptr; store_.reset(); }
270 return (object_ptr_ == rhs.object_ptr_) && (caller_ == rhs.caller_);
280 return (object_ptr_ < rhs.object_ptr_) ||
281 ((object_ptr_ == rhs.object_ptr_) && (caller_ < rhs.caller_));
286 return caller_ ==
nullptr;
291 return caller_ !=
nullptr;
295 explicit operator bool () const noexcept {
return caller_ !=
nullptr; }
299 R operator () (A... args)
const {
301 return caller_(object_ptr_, std::forward<A>(args) ...);
322 void* object_ptr_ =
nullptr;
330 : caller_(m), object_ptr_(obj) { }
333 template <
typename T>
335 using Rebind =
typename Allocator::template rebind<T>::other;
337 Rebind().destroy(static_cast<T*>(ptr));
338 Rebind().deallocate(static_cast<T*>(ptr), 1);
345 template <R(* Function)(A...)>
347 return Function(std::forward<A>(args) ...);
352 return (*
reinterpret_cast<R(* const*)(A...)
>(&object_ptr))(args...);
356 template <
class C, R(C::* method_ptr)(A...)>
358 return (static_cast<C*>(object_ptr)->*method_ptr)(
359 std::forward<A>(args) ...);
363 template <
class C, R(C::* method_ptr)(A...)
const>
365 return (static_cast<C const*>(object_ptr)->*method_ptr)(
366 std::forward<A>(args) ...);
378 std::pair<C*
const, R(C::*
const)(A...)>;
384 std::pair<C
const*
const, R(C::*
const)(A...)
const>;
388 struct IsMemberPair : std::false_type { };
396 struct IsConstMemberPair : std::false_type { };
403 template <
typename T>
404 static typename std::enable_if<
408 return (*static_cast<T*>(object_ptr))(std::forward<A>(args) ...);
412 template <
typename T>
413 static typename std::enable_if<
417 return (static_cast<T*>(object_ptr)->first->*
418 static_cast<T*
>(object_ptr)->second)(std::forward<A>(args) ...);
425 template <
typename T,
typename Allocator = std::allocator<
void> >
429 template <
class C,
typename R,
typename... A>
432 C*
const object_ptr, R(C::*
const method_ptr)(A...)) noexcept {
433 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
437 template <
class C,
typename R,
typename... A>
440 C*
const object_ptr, R(C::*
const method_ptr)(A...)
const) noexcept {
441 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
445 template <
class C,
typename R,
typename... A>
448 C& object_ptr, R(C::*
const method_ptr)(A...)) noexcept {
449 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
453 template <
class C,
typename R,
typename... A>
456 C
const& object_ptr, R(C::*
const method_ptr)(A...)
const) noexcept {
457 return Delegate<R(A...)>::template make<C>(object_ptr, method_ptr);
462 #endif // !TLX_DELEGATE_HEADER Delegate(const Caller &m, void *const obj) noexcept
private constructor for plain
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.
static bool operator<(const std::string &a, const StringView &b) noexcept
Less operator to compare a std::string with a StringView lexicographically.
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 R function_ptr_caller(void *const object_ptr, A &&... args)
caller for a plain function pointer.
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 void store_deleter(void *const ptr)
deleter for stored functor closures
void reset_caller() noexcept
static R function_caller(void *const, A &&... args)
caller for an immediate function with no object or pointer.
std::pair< C const *const, R(C::*const)(A...) const > ConstMemberPair
Delegate(R(*const function_ptr)(A...)) noexcept
constructor from a plain function pointer with no object.
static bool operator!=(const std::string &a, const StringView &b) noexcept
Inequality operator to compare a std::string with a StringView.
static bool operator==(const std::string &a, const StringView &b) noexcept
Equality operator to compare a std::string with a StringView.
std::shared_ptr< void > store_
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.
R(*)(void *, A &&...) Caller
type of the function caller pointer.
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
static Delegate make(C const *const object_ptr) noexcept
construction for an immediate class::method with class object
static Delegate make(T &&f)
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
void swap(Delegate &other) noexcept
swap delegates
Delegate(C *const object_ptr, R(C::*const method_ptr)(A...) const)
constructor for wrapping a const class::method with object 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.
static Delegate make(C &object) noexcept
static R method_caller(void *const object_ptr, A &&... args)
function caller for immediate class::method function calls
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
static Delegate make() noexcept
construction from an immediate function with no object or pointer.
static R const_method_caller(void *const object_ptr, A &&... args)
function caller for immediate const class::method functions calls.