NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
type.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_REFLECT_METATYPE_HPP__
2#define NEFORCE_CORE_REFLECT_METATYPE_HPP__
3
11
18NEFORCE_BEGIN_NAMESPACE__
19NEFORCE_BEGIN_REFLECT__
20
21class registry;
22
28
38
53class meta_type {
54public:
56 using clone_func = _NEFORCE function<meta_any(const void*)>;
57 using container_size_func = _NEFORCE function<size_t(const void*)>;
58 using container_get_func = _NEFORCE function<meta_any(const void*, size_t)>;
59 using container_insert_func = _NEFORCE function<void(void*, const meta_any&)>;
60 using container_insert_kv_func = _NEFORCE function<void(void*, const meta_any&, const meta_any&)>;
61
62private:
63 reflect::type_id type_id_;
64 string_view name_;
65 size_t size_;
66 string table_name_;
67 constructor_func constructor_;
68 clone_func cloner_;
69 vector<meta_type*> base_types_;
70 vector<string> pending_base_names_;
73 vector<string> signal_names_;
74 unique_ptr<meta_enum> enum_info_;
75 container_kind container_kind_ = container_kind::none;
76 reflect::type_id element_type_id_ = 0;
77 reflect::type_id key_type_id_ = 0;
78 reflect::type_id mapped_type_id_ = 0;
79 container_size_func container_size_;
80 container_get_func container_get_;
81 container_insert_func container_insert_;
82 container_insert_kv_func container_insert_kv_;
83
84 void collect_properties(vector<pair<string, const meta_property*>>& result,
85 vector<reflect::type_id>* visited = nullptr) const {
86 vector<reflect::type_id> local_visited;
87 if (visited == nullptr) {
88 visited = &local_visited;
89 }
90
91 if (find(visited->begin(), visited->end(), type_id_) != visited->end()) {
92 return;
93 }
94 visited->push_back(type_id_);
95
96 for (const auto* base: base_types_) {
97 if (base != nullptr) {
98 base->collect_properties(result, visited);
99 }
100 }
101
102 for (const auto& property: properties_) {
103 const auto& name = property.first;
104 const auto& prop = property.second;
105 result.emplace_back(name, prop.get());
106 }
107 }
108
109 void collect_functions(vector<pair<string, const meta_function*>>& result,
110 vector<reflect::type_id>* visited = nullptr) const {
111 vector<reflect::type_id> local_visited;
112 if (visited == nullptr) {
113 visited = &local_visited;
114 }
115
116 if (find(visited->begin(), visited->end(), type_id_) != visited->end()) {
117 return;
118 }
119 visited->push_back(type_id_);
120
121 for (const auto* base: base_types_) {
122 if (base != nullptr) {
123 base->collect_functions(result, visited);
124 }
125 }
126
127 for (const auto& f: functions_) {
128 const auto& name = f.first;
129 const auto& func = f.second;
130 result.emplace_back(name, func.get());
131 }
132 }
133
134public:
142 type_id_(id),
143 name_(name),
144 size_(size) {}
145
149 NEFORCE_NODISCARD reflect::type_id type_id() const noexcept { return type_id_; }
150
154 NEFORCE_NODISCARD string_view name() const noexcept { return name_; }
155
160 NEFORCE_NODISCARD string_view table_name() const noexcept { return table_name_.view(); }
161
168 table_name_ = table;
169 return *this;
170 }
171
175 NEFORCE_NODISCARD size_t size() const noexcept { return size_; }
176
180 NEFORCE_NODISCARD const vector<meta_type*>& base_types() const { return base_types_; }
181
188 if (base != nullptr) {
189 base_types_.push_back(base);
190 }
191 return *this;
192 }
193
200 pending_base_names_.push_back(base_name);
201 return *this;
202 }
203
209 NEFORCE_NODISCARD bool is_derived_from(reflect::type_id base_id) const {
210 if (type_id_ == base_id) {
211 return true;
212 }
213 for (const auto* base: base_types_) {
214 if (base != nullptr && base->is_derived_from(base_id)) {
215 return true;
216 }
217 }
218 return false;
219 }
220
226 NEFORCE_NODISCARD bool is_derived_from(string_view base_name) const {
227 for (const auto* base: base_types_) {
228 if (base != nullptr && (base->name() == base_name || base->is_derived_from(base_name))) {
229 return true;
230 }
231 }
232 return false;
233 }
234
245 meta_property::setter setter, const uint16_t attrs = PROP_NONE) {
246 auto prop = make_unique<meta_property>(name, prop_type_id, move(getter), move(setter), attrs);
247 properties_.emplace(name, move(prop));
248 return *this;
249 }
250
258 const auto it = functions_.emplace(name, make_unique<meta_function>(name, move(invoker))).first;
259 return it->second.get();
260 }
261
268 constructor_ = move(ctor);
269 return *this;
270 }
271
278 cloner_ = move(cloner);
279 return *this;
280 }
281
287 NEFORCE_NODISCARD meta_any clone(const void* src) const { return cloner_ ? cloner_(src) : meta_any{}; }
288
293 NEFORCE_NODISCARD const meta_enum* enum_info() const noexcept { return enum_info_.get(); }
294
298 NEFORCE_NODISCARD bool is_enum() const noexcept { return !!enum_info_; }
299
306 enum_info_ = move(info);
307 return *this;
308 }
309
313 NEFORCE_NODISCARD container_kind container() const noexcept { return container_kind_; }
314
321 container_kind_ = kind;
322 return *this;
323 }
324
328 NEFORCE_NODISCARD reflect::type_id element_type_id() const noexcept { return element_type_id_; }
329
334 element_type_id_ = id;
335 return *this;
336 }
337
341 NEFORCE_NODISCARD reflect::type_id key_type_id() const noexcept { return key_type_id_; }
342
347 key_type_id_ = id;
348 return *this;
349 }
350
354 NEFORCE_NODISCARD reflect::type_id mapped_type_id() const noexcept { return mapped_type_id_; }
355
360 mapped_type_id_ = id;
361 return *this;
362 }
363
368 container_size_ = move(func);
369 return *this;
370 }
371
377 NEFORCE_NODISCARD size_t container_element_count(const void* container_ptr) const {
378 return container_size_ ? container_size_(container_ptr) : 0;
379 }
380
385 container_get_ = move(func);
386 return *this;
387 }
388
395 NEFORCE_NODISCARD meta_any container_element_at(const void* container_ptr, size_t index) const {
396 return container_get_ ? container_get_(container_ptr, index) : meta_any{};
397 }
398
403 container_insert_ = move(func);
404 return *this;
405 }
406
410 void container_push_back(void* container_ptr, const meta_any& value) const {
411 if (container_insert_) {
412 container_insert_(container_ptr, value);
413 }
414 }
415
420 container_insert_kv_ = move(func);
421 return *this;
422 }
423
427 void container_insert_pair(void* container_ptr, const meta_any& key, const meta_any& value) const {
428 if (container_insert_kv_) {
429 container_insert_kv_(container_ptr, key, value);
430 }
431 }
432
436 NEFORCE_NODISCARD bool is_container() const noexcept { return container_kind_ != container_kind::none; }
437
443 NEFORCE_NODISCARD const meta_property* get_property(string_view name) const {
444 const auto it = properties_.find(name);
445 if (it != properties_.end()) {
446 return it->second.get();
447 }
448
449 for (const auto* base: base_types_) {
450 if (base != nullptr) {
451 if (const auto* prop = base->get_property(name)) {
452 return prop;
453 }
454 }
455 }
456 return nullptr;
457 }
458
464 NEFORCE_NODISCARD const meta_function* get_function(string_view name) const {
465 const auto it = functions_.find(name);
466 if (it != functions_.end()) {
467 return it->second.get();
468 }
469
470 for (const auto* base: base_types_) {
471 if (base != nullptr) {
472 if (const auto* func = base->get_function(name)) {
473 return func;
474 }
475 }
476 }
477 return nullptr;
478 }
479
486 signal_names_.push_back(name);
487 return *this;
488 }
489
493 NEFORCE_NODISCARD const vector<string>& signal_names() const noexcept { return signal_names_; }
494
500 void add_property(string_view name, unique_ptr<meta_property> prop) { properties_.emplace(name, move(prop)); }
501
506 NEFORCE_NODISCARD meta_any create() const { return constructor_ ? constructor_({}) : meta_any{}; }
507
513 NEFORCE_NODISCARD meta_any create(const vector<meta_any>& args) const {
514 return constructor_ ? constructor_(args) : meta_any{};
515 }
516
521 NEFORCE_NODISCARD const auto& properties() const { return properties_; }
522
527 NEFORCE_NODISCARD const auto& functions() const { return functions_; }
528
535 collect_properties(result);
536 return result;
537 }
538
545 collect_functions(result);
546 return result;
547 }
548
554
560
564 NEFORCE_NODISCARD bool has_pending_bases() const noexcept { return !pending_base_names_.empty(); }
565};
566 // Reflection
568
569NEFORCE_END_REFLECT__
570NEFORCE_END_NAMESPACE__
571#endif // NEFORCE_CORE_REFLECT_METATYPE_HPP__
constexpr basic_string_view view(const size_type off, const size_type count=npos) const
获取子视图
枚举反射元数据类
function< meta_any(void *, const vector< meta_any > &)> invoker
函数调用器类型
属性反射元数据类
function< void(void *, const meta_any &)> setter
属性写入器类型
function< meta_any(const void *)> getter
属性读取器类型
_NEFORCE function< void(void *, const meta_any &, const meta_any &)> container_insert_kv_func
插入键值对
bool is_enum() const noexcept
是否为枚举类型
size_t container_element_count(const void *container_ptr) const
获取容器元素数量
string_view table_name() const noexcept
获取数据库表名
meta_type & enum_info(unique_ptr< meta_enum > info)
设置枚举信息
vector< pair< string, const meta_property * > > all_properties() const
获取所有属性(包括继承的属性)
container_kind container() const noexcept
获取容器类型
string_view name() const noexcept
获取类型名称
meta_any clone(const void *src) const
克隆对象
meta_type & key_type_id(reflect::type_id id)
设置键类型 ID
void container_insert_pair(void *container_ptr, const meta_any &key, const meta_any &value) const
向关联容器插入键值对
_NEFORCE function< meta_any(const vector< meta_any > &)> constructor_func
构造函数调用器类型
meta_any create(const vector< meta_any > &args) const
创建对象(带参数)
const meta_property * get_property(string_view name) const
获取属性
meta_type & container_get(container_get_func func)
设置按索引获取元素的函数
void add_property(string_view name, unique_ptr< meta_property > prop)
运行时添加属性(动态属性)
meta_type & constructor(constructor_func ctor)
设置构造函数
reflect::type_id key_type_id() const noexcept
获取键类型 ID(关联容器)
const meta_function * get_function(string_view name) const
获取函数
bool is_container() const noexcept
是否为容器类型
meta_type & container_insert(container_insert_func func)
设置插入元素函数(顺序容器)
reflect::type_id element_type_id() const noexcept
获取元素类型 ID(顺序容器)
meta_type & container_insert_kv(container_insert_kv_func func)
设置插入键值对函数(关联容器)
meta_type & property(string_view name, reflect::type_id prop_type_id, meta_property::getter getter, meta_property::setter setter, const uint16_t attrs=PROP_NONE)
添加属性
meta_type & base_type(meta_type *base)
添加基类(已解析)
_NEFORCE function< void(void *, const meta_any &)> container_insert_func
插入元素
meta_type & set_table_name(string_view table)
设置数据库表名
const vector< meta_type * > & base_types() const
获取基类列表
meta_type & cloner(clone_func cloner)
设置克隆函数
bool is_derived_from(string_view base_name) const
检查是否派生自指定类型
meta_type & base_type(string_view base_name)
添加基类(延迟解析)
bool is_derived_from(reflect::type_id base_id) const
检查是否派生自指定类型
void container_push_back(void *container_ptr, const meta_any &value) const
向容器追加元素
reflect::type_id type_id() const noexcept
获取类型ID
bool has_pending_bases() const noexcept
是否有待解析的基类
meta_type & register_signal(string_view name)
注册信号名称
meta_any container_element_at(const void *container_ptr, size_t index) const
获取容器中指定索引的元素
const auto & properties() const
获取属性映射
meta_function * function(string_view name, meta_function::invoker invoker)
添加函数
vector< pair< string, const meta_function * > > all_functions() const
获取所有函数(包括继承的函数)
meta_type & element_type_id(reflect::type_id id)
设置元素类型 ID
meta_type & container_size(container_size_func func)
设置容器大小查询函数
const meta_enum * enum_info() const noexcept
获取枚举信息
_NEFORCE function< size_t(const void *)> container_size_func
容器大小查询
const auto & functions() const
获取函数映射
meta_any create() const
创建对象(无参构造)
reflect::type_id mapped_type_id() const noexcept
获取值类型 ID(关联容器)
size_t size() const noexcept
获取类型大小
meta_type & mapped_type_id(reflect::type_id id)
设置值类型 ID
_NEFORCE function< meta_any(const void *)> clone_func
克隆函数类型
meta_type & container(container_kind kind)
设置容器信息
meta_type(string_view name, reflect::type_id id, size_t size)
构造函数
void resolve_bases_unlocked(registry *registry)
解析待解析的基类名称(无需加锁版本)
const vector< string > & signal_names() const noexcept
获取信号名称列表
_NEFORCE function< meta_any(const void *, size_t)> container_get_func
按索引获取元素
void resolve_bases(registry *registry)
解析待解析的基类名称
反射类型注册表
独占智能指针
动态大小数组容器
constexpr void push_back(const T &value)
在末尾拷贝插入元素
枚举反射元数据
unsigned char uint8_t
8位无符号整数类型
unsigned short uint16_t
16位无符号整数类型
constexpr Iterator find(Iterator first, Iterator last, const T &value)
查找范围内第一个等于指定值的元素
constexpr none_t none
默认空表示
uint64_t size_t
无符号大小类型
size_t type_id
类型标识符
container_kind
容器类型标识
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
basic_string_view< char > string_view
字符字符串视图
bool name(char *buffer, size_t size)
获取当前线程名称
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
属性反射元数据
函数反射元数据
字符串类型别名和实用函数
存储两个值的元组对
独占智能指针
无序映射容器