forked from NoAvailableAlias/nano-signal-slot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nano_function.hpp
73 lines (61 loc) · 2.12 KB
/
nano_function.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef NANO_FUNCTION_HPP
#define NANO_FUNCTION_HPP
#include <cstdint>
#include <array>
namespace Nano
{
using DelegateKey = std::array<std::uintptr_t, 2>;
template <typename RT> class Function;
template <typename RT, typename... Args>
class Function<RT(Args...)>
{
using Thunk = RT (*)(void*, Args...);
friend class Observer;
void* m_this_ptr; // instance pointer
Thunk m_stub_ptr; // free function pointer
Function(void* this_ptr, Thunk stub_ptr) :
m_this_ptr(this_ptr), m_stub_ptr(stub_ptr) {}
Function(DelegateKey delegate_key) :
m_this_ptr(reinterpret_cast<void*>(delegate_key[0])),
m_stub_ptr(reinterpret_cast<Thunk>(delegate_key[1])) {}
public:
template <RT (*fun_ptr) (Args...)>
static inline Function bind()
{
return { nullptr, [](void* /*NULL*/, Args... args)
{ return (*fun_ptr)(std::forward<Args>(args)...); } };
}
template <typename T, RT (T::* mem_ptr) (Args...)>
static inline Function bind(T* pointer)
{
return { pointer, [](void* this_ptr, Args... args)
{ return (static_cast<T*>(this_ptr)->*mem_ptr) (std::forward<Args>(args)...); } };
}
template <typename T, RT (T::* mem_ptr) (Args...) const>
static inline Function bind(T* pointer)
{
return { pointer, [](void* this_ptr, Args... args)
{ return (static_cast<T*>(this_ptr)->*mem_ptr) (std::forward<Args>(args)...); } };
}
template <typename L>
static inline Function bind(L* pointer)
{
return { pointer, [](void *this_ptr, Args... args)
{ return (static_cast<L*>(this_ptr)->operator()(std::forward<Args>(args)...)); }};
}
inline operator DelegateKey() const
{
return
{{
reinterpret_cast<std::uintptr_t>(m_this_ptr),
reinterpret_cast<std::uintptr_t>(m_stub_ptr)
}};
}
template <typename... Uref>
inline RT operator() (Uref&&... args)
{
return (*m_stub_ptr)(m_this_ptr, std::forward<Uref>(args)...);
}
};
} // namespace Nano ------------------------------------------------------------
#endif // NANO_FUNCTION_HPP