Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
ser_common.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstdint>
5#include <type_traits>
6
7#include "gaia/core/utility.h"
8
9namespace gaia {
10 namespace ser {
11 enum class serialization_type_id : uint8_t {
12 // Dummy
13 ignore = 0,
14
15 // Integer types
16 s8 = 1,
17 u8 = 2,
18 s16 = 3,
19 u16 = 4,
20 s32 = 5,
21 u32 = 6,
22 s64 = 7,
23 u64 = 8,
24
25 // Boolean
26 b = 9,
27
28 // Character types
29 c8 = 10,
30 c16 = 11,
31 c32 = 12,
32 cw = 13,
33
34 // Floating point types
35 f8 = 14,
36 f16 = 15,
37 f32 = 16,
38 f64 = 17,
39 f128 = 18,
40
41 // Special
42 special_begin = 19,
43 trivial_wrapper = special_begin,
44 data_and_size = 20,
45
46 Last = data_and_size,
47 };
48
49 inline uint32_t serialization_type_size(serialization_type_id id, uint32_t size) {
50 static const uint32_t sizes[] = {
51 // Dummy
52 0, // ignore
53
54 // Integer types
55 1, // s8
56 1, // u8
57 2, // s16
58 2, // u16
59 4, // s32
60 4, // u32
61 8, // s64
62 8, // u64
63
64 // Boolean
65 1, // b
66
67 // Character types
68 1, // c8
69 2, // c16
70 4, // c32
71 8, // cw
72
73 // Floating point types
74 1, // f8
75 2, // f16
76 4, // f32
77 8, // f64
78 16, // f128
79
80 // Special
81 size, // trivial_wrapper
82 sizeof(uintptr_t), // data_and_size, assume natural alignment
83 };
84
85 const auto s = sizes[(uint32_t)id];
86 // Make sure we do not return an invalid value
87 GAIA_ASSERT(s != (uint32_t)-1);
88 return s;
89 }
90
91 template <typename T>
93 private:
94 static constexpr bool update() {
95 return std::is_enum_v<T> || std::is_fundamental_v<T> || std::is_trivially_copyable_v<T>;
96 }
97
98 public:
99 static constexpr bool value = update();
100 };
101
102 template <typename T>
104 std::disjunction<
105 std::is_same<T, char>, std::is_same<T, unsigned char>, //
106 std::is_same<T, int8_t>, std::is_same<T, uint8_t>, //
107 std::is_same<T, int16_t>, std::is_same<T, uint16_t>, //
108 std::is_same<T, int32_t>, std::is_same<T, uint32_t>, //
109 std::is_same<T, int64_t>, std::is_same<T, uint64_t>, //
110 std::is_same<T, size_t>, std::is_same<T, bool>> {};
111
112 template <typename T>
114 std::disjunction<
115 // std::is_same<T, float8_t>, //
116 // std::is_same<T, float16_t>, //
117 std::is_same<T, float>, //
118 std::is_same<T, double>, //
119 std::is_same<T, long double>> {};
120
121 template <typename T>
122 GAIA_NODISCARD constexpr serialization_type_id int_kind_id() {
123 static_assert(is_int_kind_id<T>::value, "Unsupported integral type");
124
125 if constexpr (std::is_same_v<char, T>) {
126 return serialization_type_id::s8;
127 } else if constexpr (std::is_same_v<unsigned char, T>) {
128 return serialization_type_id::u8;
129 } else if constexpr (std::is_same_v<int8_t, T>) {
130 return serialization_type_id::s8;
131 } else if constexpr (std::is_same_v<uint8_t, T>) {
132 return serialization_type_id::u8;
133 } else if constexpr (std::is_same_v<int16_t, T>) {
134 return serialization_type_id::s16;
135 } else if constexpr (std::is_same_v<uint16_t, T>) {
136 return serialization_type_id::u16;
137 } else if constexpr (std::is_same_v<int32_t, T>) {
138 return serialization_type_id::s32;
139 } else if constexpr (std::is_same_v<uint32_t, T>) {
140 return serialization_type_id::u32;
141 } else if constexpr (std::is_same_v<int64_t, T>) {
142 return serialization_type_id::s64;
143 } else if constexpr (std::is_same_v<uint64_t, T>) {
144 return serialization_type_id::u64;
145 } else if constexpr (std::is_same_v<size_t, T>) {
146 return serialization_type_id::u64;
147 } else { // if constexpr (std::is_same_v<bool, T>) {
148 return serialization_type_id::b;
149 }
150 }
151
152 template <typename T>
153 GAIA_NODISCARD constexpr serialization_type_id flt_type_id() {
154 static_assert(is_flt_kind_id<T>::value, "Unsupported floating type");
155
156 // if constexpr (std::is_same_v<float8_t, T>) {
157 // return serialization_type_id::f8;
158 // } else if constexpr (std::is_same_v<float16_t, T>) {
159 // return serialization_type_id::f16;
160 // } else
161 if constexpr (std::is_same_v<float, T>) {
162 return serialization_type_id::f32;
163 } else if constexpr (std::is_same_v<double, T>) {
164 return serialization_type_id::f64;
165 } else { // if constexpr (std::is_same_v<long double, T>) {
166 return serialization_type_id::f128;
167 }
168 }
169
170 template <typename T>
171 GAIA_NODISCARD constexpr serialization_type_id type_id() {
172 if constexpr (std::is_enum_v<T>)
173 return int_kind_id<std::underlying_type_t<T>>();
174 else if constexpr (std::is_integral_v<T>)
175 return int_kind_id<T>();
176 else if constexpr (std::is_floating_point_v<T>)
177 return flt_type_id<T>();
178 else if constexpr (std::is_pointer_v<T>)
179 return serialization_type_id::data_and_size;
180 else if constexpr (core::has_size_begin_end<T>::value)
181 return serialization_type_id::data_and_size;
182 else if constexpr (std::is_class_v<T>)
183 return serialization_type_id::trivial_wrapper;
184 else
185 return serialization_type_id::ignore;
186 }
187
188 // --------------------
189 // Define function detectors
190 // --------------------
191
192 GAIA_DEFINE_HAS_MEMBER_FUNC(save);
193 GAIA_DEFINE_HAS_MEMBER_FUNC(load);
194 GAIA_DEFINE_HAS_MEMBER_FUNC(resize);
195
196 // --------------------
197 // Customization tags
198 // --------------------
199
200 struct save_tag {};
201 struct load_tag {};
202 inline constexpr save_tag save_v{};
203 inline constexpr load_tag load_v{};
204
205 // --------------------
206 // Detection traits
207 // --------------------
208
209 template <typename S, typename T>
210 auto has_tag_save_impl(int)
211 -> decltype(tag_invoke(save_v, std::declval<S&>(), std::declval<const T&>()), std::true_type{});
212 template <typename, typename>
213 std::false_type has_tag_save_impl(...);
214 template <typename S, typename T>
215 using has_tag_save = decltype(has_tag_save_impl<S, T>(0));
216
217 template <typename S, typename T>
218 auto has_tag_load_impl(int)
219 -> decltype(tag_invoke(load_v, std::declval<S&>(), std::declval<T&>()), std::true_type{});
220 template <typename, typename>
221 std::false_type has_tag_load_impl(...);
222 template <typename S, typename T>
223 using has_tag_load = decltype(has_tag_load_impl<S, T>(0));
224 } // namespace ser
225} // namespace gaia
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition ser_common.h:119
Definition ser_common.h:110
Definition ser_common.h:92
Definition ser_common.h:201
Definition ser_common.h:200