-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfunction_ptr.h
More file actions
69 lines (58 loc) · 3.3 KB
/
function_ptr.h
File metadata and controls
69 lines (58 loc) · 3.3 KB
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
#pragma once
#include <concepts>
#include <functional>
#include "moar_ptr.h"
namespace moar
{
template<concepts::Function T1, concepts::CallingConvention T2 = types::default_calling_convention, concepts::Variadic T3 = types::default_variadic>
class function_ptr;
#define function_pointer_impl(convention) \
template<typename RT, typename ...A> requires moar::is_calling_convention_active_v<RT(A...), types::convention##_t, void> \
class function_ptr<RT convention##_m(A...)> final : public function_ptr_base<RT(A...), types::convention##_t, void> \
{ \
using base = function_ptr_base<RT(A...), types::convention##_t, void>; \
public: \
function_ptr() : base() {}; \
explicit function_ptr(base::pointer_type pointer) : base(pointer) {}; \
explicit function_ptr(nullptr_t pointer) : function_ptr(reinterpret_cast<base::pointer_type>(pointer)) {} \
explicit function_ptr(void* pointer) : base(reinterpret_cast<base::pointer_type>(pointer)) {} \
explicit function_ptr(std::size_t pointer) : base(reinterpret_cast<base::pointer_type>(pointer)) {} \
}; \
template<typename RT, typename ...A> requires moar::is_calling_convention_active_v<RT(A...), types::convention##_t, void> \
function_ptr(RT convention##_m(A...)) -> function_ptr<RT convention##_m (A...)>;
#define function_pointer_va_impl(convention) \
template<typename RT, typename ...A> requires moar::is_calling_convention_active_v<RT(A...), types::convention##_t, types::variadic_t> \
class function_ptr<RT convention##_m(A...,...)> final : public function_ptr_base<RT(A...), types::convention##_t, types::variadic_t> \
{ \
using base = function_ptr_base<RT(A...), types::convention##_t, types::variadic_t>; \
public: \
function_ptr() : base() {}; \
explicit function_ptr(base::pointer_type pointer) : base(pointer) {}; \
explicit function_ptr(nullptr_t pointer) : function_ptr(reinterpret_cast<base::pointer_type>(pointer)) {} \
explicit function_ptr(void* pointer) : base(reinterpret_cast<base::pointer_type>(pointer)) {} \
explicit function_ptr(std::size_t pointer) : base(reinterpret_cast<base::pointer_type>(pointer)) {} \
}; \
template<typename RT, typename ...A> requires moar::is_calling_convention_active_v<RT(A...), types::convention##_t, types::variadic_t> \
function_ptr(RT convention##_m(A...,...)) -> function_ptr<RT convention##_m (A...,...)>;
function_pointer_impl(cdecl);
function_pointer_impl(stdcall);
function_pointer_impl(thiscall);
function_pointer_impl(fastcall);
function_pointer_impl(vectorcall);
function_pointer_impl(regcall);
function_pointer_impl(sysv_abi);
function_pointer_impl(ms_abi);
function_pointer_va_impl(cdecl);
function_pointer_va_impl(regcall);
function_pointer_va_impl(sysv_abi);
function_pointer_va_impl(ms_abi);
#undef function_pointer_va_impl
#undef function_pointer_impl
}
/* Implementation of std::hash (injected into STD.)
*/
template<typename T>
struct std::hash<moar::function_ptr<T>> // NOLINT(cert-dcl58-cpp)
{
std::size_t operator()(moar::function_ptr<T> const& p) const noexcept { return std::hash<T*>{}(p.get()); }
};