cpp-reflect
C++ Reflection and Annotations Library
Loading...
Searching...
No Matches
any.cppm
Go to the documentation of this file.
1
5
6export module reflect:any;
7
8import std;
9
10export import :type_info;
11
12namespace refl {
13 export class any {
14 private:
15 template<typename T>
16 requires (not std::same_as<std::remove_reference_t<T>, any>)
17 explicit any(T* t) {
18 using type = std::remove_const_t<std::remove_reference_t<T>>;
19 data_ = t;
20 destructor_ = [](void* ptr) { delete static_cast<type*>(ptr); };
21 type_info_ = &type_info::from<type>();
22 }
23
24 public:
25 any() {
26 data_ = nullptr;
27 destructor_ = [](void*) {
28 };
29 type_info_ = nullptr;
30 }
31
32 template<typename T>
33 requires (not std::same_as<std::remove_reference_t<T>, any>)
34 any(const T &t) {
35 using type = std::remove_const_t<std::remove_reference_t<T>>;
36 data_ = new type(t);
37 destructor_ = [](void* ptr) { delete static_cast<T*>(ptr); };
38 type_info_ = &type_info::from<type>();
39 }
40
41 template<typename T>
42 requires (not std::same_as<std::remove_reference_t<T>, any>)
43 any(T &&t) {
44 using type = std::remove_const_t<std::remove_reference_t<T>>;
45 data_ = new type(std::forward<T>(t));
46 destructor_ = [](void* ptr) { delete static_cast<T*>(ptr); };
47 type_info_ = &type_info::from<type>();
48 }
49
50 template<typename T, typename... Args>
51 requires (not std::is_reference_v<T>)
52 static any make(Args &&... args) {
53 using type = std::remove_const_t<std::remove_reference_t<T>>;
54 auto* ptr = new type(std::forward<Args>(args)...);
55 return any {ptr};
56 }
57
58 template<typename T>
59 requires (not std::same_as<std::remove_reference_t<T>, any>)
60 static any make(const T &value) {
61 using type = std::remove_const_t<std::remove_reference_t<T>>;
62 auto* ptr = new type(value);
63 return any {ptr};
64 }
65
66 static any make(const refl::type_info &t_info, void* ptr) {
67 any a { };
68 a.data_ = t_info.make_copy_of(ptr);
69 a.type_info_ = &t_info;
70 return a;
71 }
72
73 ~any() {
74 destructor_(data_);
75 data_ = nullptr;
76 }
77
78 any(const any &other) {
79 type_info_ = other.type_info_;
80 if (type_info_ != nullptr) {
81 data_ = type_info_->make_copy_of(other.data_);
82 }
83 destructor_ = other.destructor_;
84 }
85
86 any &operator=(const any &other) {
87 if (data_ != nullptr) {
88 destructor_(data_);
89 data_ = nullptr;
90 }
91 type_info_ = other.type_info_;
92 if (type_info_ != nullptr) {
93 type_info_->assign_copy_of(other.data_, data_);
94 }
95 destructor_ = other.destructor_;
96 return *this;
97 }
98
99 template<typename T>
100 bool is() const {
101 if (type_info_ == nullptr) return false;
102 return type_info_->is_type<T>();
103 }
104
105 bool is(const refl::type_info &tinfo) const {
106 if (type_info_ == nullptr) return false;
107 return type_info_->id() == tinfo.id();
108 }
109
110 template<typename T>
111 T &as() {
112 if (not is<T>()) { throw std::bad_cast(); }
113 return *static_cast<T*>(data_);
114 }
115
116 template<typename T>
117 const T &as() const {
118 if (not is<T>()) { throw std::bad_cast(); }
119 return *static_cast<T*>(data_);
120 }
121
122 const type_info &type() const {
123 if (type_info_ == nullptr) { throw std::bad_typeid(); }
124 return *type_info_;
125 }
126
127 bool is_null() const {
128 return data_ == nullptr or type_info_ == nullptr;
129 }
130
131 void* data() {
132 return data_;
133 }
134
135 const void* data() const {
136 return data_;
137 }
138
139 bool operator==(const any &other) const {
140 if (data_ == nullptr) {
141 return type_info_ == other.type_info_;
142 }
143 return type_info_ == other.type_info_ and type_info_->equality(data_, other.data_);
144 }
145
146 private:
147 void* data_;
148 [[refl::ignore]]
149 std::function<void(void*)> destructor_;
150 [[meta(eq_policy::shallow)]]
151 const type_info* type_info_;
152 };
153
154 export class any_ref {
155 public:
157 data_ = nullptr;
158 type_info_ = nullptr;
159 }
160
161 template<typename T>
162 requires (not std::same_as<std::remove_reference_t<T>, any_ref> and not std::same_as<
163 std::remove_reference_t<T>, any>)
164 any_ref(T &t) {
165 using type = std::remove_const_t<std::remove_reference_t<T>>;
166 data_ = &t;
167 type_info_ = &type_info::from<type>();
168 }
169
170 template<typename T>
171 requires (not std::same_as<std::remove_reference_t<T>, any_ref> and not std::same_as<
172 std::remove_reference_t<T>, any>)
173 any_ref(T* t) {
174 using type = std::remove_const_t<std::remove_reference_t<T>>;
175 data_ = t;
176 type_info_ = &type_info::from<type>();
177 }
178
179 any_ref(const refl::type_info &t_info, void* ptr) {
180 any_ref a { };
181 a.data_ = ptr;
182 a.type_info_ = &t_info;
183 }
184
185 any_ref(refl::any &owner_any) {
186 any_ref a { };
187 a.data_ = owner_any.data();
188 a.type_info_ = &owner_any.type();
189 }
190
191
193 data_ = nullptr;
194 }
195
196 any_ref(const any_ref &other) {
197 type_info_ = other.type_info_;
198 if (type_info_ != nullptr) {
199 data_ = other.data_;
200 }
201 }
202
203 any_ref &operator=(const any_ref &other) {
204 if (data_ != nullptr) {
205 data_ = nullptr;
206 }
207 type_info_ = other.type_info_;
208 if (type_info_ != nullptr) {
209 data_ = other.data_;
210 }
211 return *this;
212 }
213
214 template<typename T>
215 bool is() const {
216 if (type_info_ == nullptr) return false;
217 return type_info_->is_type<T>();
218 }
219
220 bool is(const refl::type_info &tinfo) const {
221 if (type_info_ == nullptr) return false;
222 return type_info_->id() == tinfo.id();
223 }
224
225 template<typename T>
226 T &as() {
227 if (not is<T>()) { throw std::bad_cast(); }
228 return *static_cast<T*>(data_);
229 }
230
231 template<typename T>
232 const T &as() const {
233 if (not is<T>()) { throw std::bad_cast(); }
234 return *static_cast<T*>(data_);
235 }
236
237 const type_info &type() const {
238 if (type_info_ == nullptr) { throw std::bad_typeid(); }
239 return *type_info_;
240 }
241
242 bool is_null() const {
243 return data_ == nullptr or type_info_ == nullptr;
244 }
245
246 void* data() {
247 return data_;
248 }
249
250 const void* data() const {
251 return data_;
252 }
253
254 private:
255 void* data_;
256 const type_info* type_info_;
257 };
258}
any_ref(T &t)
Definition any.cppm:164
bool is(const refl::type_info &tinfo) const
Definition any.cppm:220
any_ref & operator=(const any_ref &other)
Definition any.cppm:203
const void * data() const
Definition any.cppm:250
void * data()
Definition any.cppm:246
any_ref(const any_ref &other)
Definition any.cppm:196
const T & as() const
Definition any.cppm:232
const type_info & type() const
Definition any.cppm:237
any_ref(refl::any &owner_any)
Definition any.cppm:185
bool is() const
Definition any.cppm:215
any_ref(T *t)
Definition any.cppm:173
any_ref(const refl::type_info &t_info, void *ptr)
Definition any.cppm:179
bool is_null() const
Definition any.cppm:242
static any make(Args &&... args)
Definition any.cppm:52
bool is_null() const
Definition any.cppm:127
const void * data() const
Definition any.cppm:135
any(T &&t)
Definition any.cppm:43
static any make(const T &value)
Definition any.cppm:60
T & as()
Definition any.cppm:111
const T & as() const
Definition any.cppm:117
any & operator=(const any &other)
Definition any.cppm:86
static any make(const refl::type_info &t_info, void *ptr)
Definition any.cppm:66
bool is() const
Definition any.cppm:100
bool is(const refl::type_info &tinfo) const
Definition any.cppm:105
bool operator==(const any &other) const
Definition any.cppm:139
void * data()
Definition any.cppm:131
any(const any &other)
Definition any.cppm:78
const type_info & type() const
Definition any.cppm:122
any(const T &t)
Definition any.cppm:34
bool equality(const void *lhs, const void *rhs) const
void * make_copy_of(const void *ptr) const
std::size_t id() const
static const type_info & from()