4#include "../Algorithms/AlgorithmBubbleSort.h"
16template <
typename SchemaBuilder>
20 using Type =
typename SchemaBuilder::Type;
21 using TypeBuildFunction =
typename Type::TypeBuildFunction;
22 using VirtualTablesType =
decltype(SchemaBuilder::vtables);
25 template <u
int32_t MAX_TOTAL_TYPES>
28 ArrayWithSize<Type, MAX_TOTAL_TYPES> types;
29 VirtualTablesType vtables;
33 template <u
int32_t NUM_TYPES>
34 struct FlatTrimmedResult
36 ArrayWithSize<TypeInfo, NUM_TYPES> typeInfos;
37 ArrayWithSize<TypeStringView, NUM_TYPES> typeNames;
38 VirtualTablesType vtables;
41 template <u
int32_t MAX_TYPES>
42 [[nodiscard]]
static constexpr bool appendTypesTo(ArrayWithSize<Type, MAX_TYPES>& types, TypeBuildFunction build,
43 SchemaBuilder& builder)
46 const auto baseLinkID = types.size;
47 builder.currentLinkID = types.size;
48 builder.types = {types.values + types.size, MAX_TYPES - types.size};
53 const auto numberOfTypes = builder.currentLinkID - baseLinkID;
54 const auto numberOfChildren = numberOfTypes - 1;
55 if (numberOfChildren >
static_cast<decltype(TypeInfo::numberOfChildren)
>(MaxValue()))
57 if (not types.values[baseLinkID].typeInfo.setNumberOfChildren(numberOfChildren))
60 struct OrderByMemberOffset
62 constexpr bool operator()(
const Type& a,
const Type& b)
const
64 return a.typeInfo.memberInfo.offsetInBytes < b.typeInfo.memberInfo.offsetInBytes;
68 types.values[baseLinkID].typeInfo.structInfo.isPacked)
72 OrderByMemberOffset());
74 types.size += numberOfTypes;
80 template <u
int32_t MAX_LINK_BUFFER_SIZE, u
int32_t MAX_TOTAL_TYPES,
typename Func>
81 constexpr static FlatFullResult<MAX_TOTAL_TYPES> compileAllTypesFor(Func func)
84 FlatFullResult<MAX_TOTAL_TYPES> result;
86 SchemaBuilder container(result.types.values, MAX_TOTAL_TYPES);
89 ArrayWithSize<TypeStringView, MAX_LINK_BUFFER_SIZE> alreadyVisitedTypes;
91 ArrayWithSize<TypeBuildFunction, MAX_LINK_BUFFER_SIZE> alreadyVisitedTypes;
93 ArrayWithSize<uint32_t, MAX_LINK_BUFFER_SIZE> alreadyVisitedLinkID;
94 if (not appendTypesTo(result.types, func, container))
101 while (typeIndex < result.types.size)
103 Type& type = result.types.values[typeIndex];
104 if (not type.typeInfo.isPrimitiveType() and type.typeInfo.needsLinking())
108 if (alreadyVisitedTypes.contains(type.typeName, &outIndex))
110 if (alreadyVisitedTypes.contains(type.typeBuild, &outIndex))
113 if (not type.typeInfo.setLinkIndex(alreadyVisitedLinkID.values[outIndex]))
118 if (not type.typeInfo.setLinkIndex(result.types.size))
120 if (not alreadyVisitedLinkID.push_back(result.types.size))
123 if (not alreadyVisitedTypes.push_back(type.typeName))
125 if (not alreadyVisitedTypes.push_back(type.typeBuild))
128 if (not appendTypesTo(result.types, type.typeBuild, container))
134 result.vtables = container.vtables;
146 template <
typename T, u
int32_t MAX_LINK_BUFFER_SIZE = 20, u
int32_t MAX_TOTAL_TYPES = 100>
147 static constexpr auto compile()
149 constexpr auto schema =
150 compileAllTypesFor<MAX_LINK_BUFFER_SIZE, MAX_TOTAL_TYPES>(&Reflect<T>::template build<SchemaBuilder>);
151 static_assert(schema.types.size > 0,
"Something failed in compileAllTypesFor");
154 FlatTrimmedResult<schema.types.size> result;
155 for (
uint32_t i = 0; i < schema.types.size; ++i)
157 result.typeInfos.values[i] = schema.types.values[i].typeInfo;
158 result.typeNames.values[i] = schema.types.values[i].typeName;
160 result.typeInfos.size = schema.types.size;
161 result.typeNames.size = schema.types.size;
162 result.vtables = schema.vtables;
169template <
typename TypeVisitor>
172 using TypeBuildFunction = bool (*)(TypeVisitor& builder);
175 TypeStringView typeName;
176 TypeBuildFunction typeBuild;
178 constexpr SchemaType() : typeBuild(nullptr) {}
179 constexpr SchemaType(
const TypeInfo typeInfo, TypeStringView typeName, TypeBuildFunction typeBuild)
180 : typeInfo(typeInfo), typeName(typeName), typeBuild(typeBuild)
184 template <
typename T>
185 [[nodiscard]]
static constexpr SchemaType createGeneric()
187 return {TypeInfo(Reflect<T>::getCategory(),
sizeof(T)), TypeToString<T>::get(), &Reflect<T>::build};
191 template <
typename T>
192 [[nodiscard]]
static constexpr SchemaType createStruct(TypeStringView name = TypeToString<T>::get())
194 TypeInfo::StructInfo structInfo(ExtendedTypeInfo<T>::IsPacked);
195 return {TypeInfo(Reflect<T>::getCategory(),
sizeof(T), structInfo), name, &Reflect<T>::build};
199 template <
typename R,
typename T,
int N>
200 [[nodiscard]]
static constexpr SchemaType createMember(
uint8_t memberTag, R T::*,
const char (&name)[N],
203 const auto info = TypeInfo::MemberInfo(memberTag,
static_cast<SC::uint16_t>(offset));
204 return {TypeInfo(Reflect<R>::getCategory(),
sizeof(R), info), TypeStringView(name, N - 1), &Reflect<R>::build};
208 template <
typename T>
209 [[nodiscard]]
static constexpr SchemaType createArray(TypeStringView name,
uint8_t numChildren,
210 TypeInfo::ArrayInfo arrayInfo)
212 return {TypeInfo(Reflect<T>::getCategory(),
sizeof(T), numChildren, arrayInfo), name, &Reflect<T>::build};
217template <
typename TypeVisitor>
220 using Type = SchemaType<TypeVisitor>;
224 WritableRange<Type> types;
226 constexpr SchemaBuilder(Type* output,
const uint32_t capacity) : currentLinkID(0), types(output, capacity) {}
228 template <
typename R,
typename T,
int N>
229 [[nodiscard]]
constexpr bool operator()(
uint8_t memberTag, R T::* field,
const char (&name)[N],
size_t offset)
232 return types.writeAndAdvance(Type::createMember(memberTag, field, name, offset));
235 [[nodiscard]]
constexpr bool addType(Type type)
238 return types.writeAndAdvance(type);
243struct FlatSchemaBuilder :
public SchemaBuilder<FlatSchemaBuilder>
248 EmptyVTables vtables;
249 constexpr FlatSchemaBuilder(Type* output,
const uint32_t capacity) : SchemaBuilder(output, capacity) {}
253using Schema = Reflection::SchemaCompiler<FlatSchemaBuilder>;
constexpr void bubbleSort(Iterator first, Iterator last, BinaryPredicate predicate=BinaryPredicate())
Sorts iterator range according to BinaryPredicate (bubble sort).
Definition AlgorithmBubbleSort.h:34
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:37
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
Reflection::SchemaCompiler< FlatSchemaBuilder > Schema
Default schema not building any virtual table.
Definition ReflectionSchemaCompiler.h:253
@ TypeStruct
Type is a struct type.