-
Notifications
You must be signed in to change notification settings - Fork 0
/
DeclProperty.h
139 lines (116 loc) · 3.32 KB
/
DeclProperty.h
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
Made by Mauricius
Part of my MUtilize repo: https://github.com/LegendaryMauricius/MUtilize
*/
#pragma once
#ifndef _DECL_PROPERTY_H
#define _DECL_PROPERTY_H
#include <type_traits>
/*
Declares a property member.
To use it inside a class, you must typedef property_owner_t
to the type of the class.
*/
#define decl_property(NAME, ...) _decl_property_impl(NAME, __VA_ARGS__)
/*
Enables usage of this_owner inside a class' property's methods.
Use AFTER defining the owner class.
If enable_this_owner is used on a property, it has to be the single
member of its property type.
Example:
enable_this_owner(Owner::Member);
*/
#define enable_this_owner(PROP_OWNER_T, MEMBER_NAME) constexpr PROP_OWNER_T::property_##MEMBER_NAME##_t PROP_OWNER_T::* PROP_OWNER_T::property_##MEMBER_NAME##_t::_this_member_ptr() {return &PROP_OWNER_T::MEMBER_NAME;}
/*
Pointer to the owner of the property.
'this' points to the property member itself, so use 'this_owner' instead
*/
#define this_owner ((property_owner_t*)((char*)this - _PROP_OFFSET_OF_MEMBER_PTR(property_owner_t, _this_member_ptr())))
/*
Declaration of a getter. Used inside the property declaration body.
It can be used to either only declare a getter, or define it later.
*/
#define decl_get(TYPE) operator TYPE ()
/*
Declaration of a setter. Used inside the property declaration body.
It can be used to either only declare a setter, or define it later.
*/
#define decl_set(TYPE_VAL) operator=(TYPE_VAL)
/*
Enables usage of 'default_get' and 'default_set'.
Requires specifying a base property type.
*/
#define enable_property_defaults(BASETYPE) using _property_base_t = BASETYPE; _property_base_t _property_value
/*
Declares a default getter
*/
#define default_get() inline operator _property_base_t& () {return _property_value;}
/*
Declares a default setter
*/
#define default_set() inline void operator=(_property_base_t&& val) {_property_value = val;}
/*
EXAMPLES
*/
/*
// simple example
class PropOwner
{
public:
using property_owner_t = PropOwner;
decl_property(a_prop,
decl_get(int)
{
return this_owner->a;
}
void decl_set(int val)
{
this_owner->a = val;
}
);
int a;
};
enable_this_owner(PropOwner, a_prop);
*/
/*
// defaults example
class PropOwner
{
public:
using property_owner_t = PropOwner;
decl_property(prop,
enable_property_defaults(int);
default_get();
default_set();
);
};
*/
/*
// read-only example (writable by the PropOwner)
class PropOwner
{
public:
using property_owner_t = PropOwner;
decl_property(prop,
enable_property_defaults(int);
default_get();
private:
default_set();
);
};
*/
/*
UTILITIES
*/
#define _PROP_OFFSET_OF_MEMBER_PTR(OWNER, MEMBER_PTR) ((char*)&((OWNER*)nullptr->*(MEMBER_PTR)) - (char*)nullptr)
#define _PROP_OFFSET_OF_MEMBER(OWNER, MEMBER) ((char*)&((OWNER*)nullptr->*(&OWNER::MEMBER)) - (char*)nullptr)
#define _decl_property_impl(NAME, ...)\
[[no_unique_address]][[msvc::no_unique_address]] struct property_##NAME##_t {\
friend property_owner_t;\
\
__VA_ARGS__\
\
private:\
static constexpr property_##NAME##_t PropOwner::* _this_member_ptr();\
} NAME
#endif