fennec
Loading...
Searching...
No Matches
type_data.h
Go to the documentation of this file.
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
30
31#ifndef FENNEC_RTTI_TYPE_DATA_H
32#define FENNEC_RTTI_TYPE_DATA_H
33
36#include <fennec/string/string.h>
37#include <fennec/memory/pointers.h>
38#include <fennec/rtti/typeid.h>
39#include <fennec/rtti/forward.h>
40#include <fennec/rtti/detail/_type_name.h>
41
42namespace fennec
43{
44
45struct type_data {
46 enum property_ {
47 property_complete = 0,
48 property_iterable,
49 property_indexable,
50 property_mappable,
51
52 property_count
53 };
54
55 using properties_t = bitfield<property_count>;
56
57 uint64_t uuid;
58 string name;
59
60 type_data* raw_type;
61 dynarray<type_data*> supers;
62 dynarray<type_data*> subs;
63
64 properties_t properties;
65
66 type_data* key_type;
67};
68
69struct type_storage {
70private:
71 template<typename ClassT> using _super_class_list = typename ClassT::super_class_list;
72 template<typename ClassT> using _key_t = typename ClassT::key_t;
73
74 static dynarray<unique_ptr<type_data>>& _typelist() {
75 static dynarray<unique_ptr<type_data>> typelist;
76 return typelist;
77 }
78
79 template<typename T>
80 static unique_ptr<type_data> _make_data() {
81 using raw_t = remove_cvrefptr_t<T>;
82 using supers_t = detect_t<typelist<>, _super_class_list, T>;
83
84 auto res = fennec::unique_ptr<type_data>(new type_data{
85 .uuid = typeuuid<T>(),
86 .name = detail::type_name<T>(),
87
88 .raw_type = typeuuid<raw_t>() == typeuuid<T>() ? nullptr : type_storage::get_data<raw_t>(),
89 .supers = type_storage::get_data(supers_t{}),
90 .subs = {},
91
92 .properties = { is_complete_v<T>, is_iterable_v<T>, is_indexable_v<T>, is_mappable_v<T> },
93
94 .key_type = type_storage::get_data<detect_t<void, _key_t, T>>(),
95 });
96
97 for (type_data* t : res->supers) {
98 t->subs.push_back(res.get());
99 }
100
101 return res;
102 }
103
104public:
105 template<typename T>
106 static type_data* get_data() requires(not is_void_v<T>) {
107 auto& typelist = _typelist();
108 uint64_t uuid = typeuuid<T>();
109
110 if (typelist.size() <= uuid) {
111 typelist.resize(uuid * 2);
112 }
113
114 if (typelist[uuid].empty()) {
115 typelist[uuid] = fennec::forward<unique_ptr<type_data>>(_make_data<T>());
116 }
117
118 return typelist[uuid].get();
119 }
120
121 template<typename T>
122 static type_data* get_data() {
123 return nullptr;
124 }
125
126 template<typename...Ts>
127 static dynarray<type_data*> get_data(typelist<Ts...>) {
128 return {
129 get_data<Ts>()...
130 };
131 }
132};
133
134}
135
136#endif // FENNEC_RTTI_TYPE_DATA_H
Definition pointers.h:87
A header containing the definition for a dynamically allocated array.
::uint64_t uint64_t
Unsigned 64-bit integer.
Definition types.h:275