5#include "../Common/CompilerMacrosExport.h"
6#include "../Common/CompilerOffsetOf.h"
7#include "../Common/PrimitiveDefinitions.h"
8#ifndef SC_EXPORT_LIBRARY_REFLECTION
9#define SC_EXPORT_LIBRARY_REFLECTION 0
11#define SC_REFLECTION_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_REFLECTION)
13#include "../Common/TypeTraits.h"
14#include "ReflectionFoundation.h"
76 uint8_t numberOfChildren;
90 uint16_t offsetInBytes;
91 constexpr MemberInfo(uint8_t memberTag, uint16_t offsetInBytes)
92 : memberTag(memberTag), offsetInBytes(offsetInBytes)
100 constexpr StructInfo(
bool isPacked) : isPacked(isPacked) {}
106 uint32_t isPacked : 1;
107 uint32_t numElements : 31;
108 constexpr ArrayInfo(
bool isPacked, uint32_t numElements) : isPacked(isPacked), numElements(numElements) {}
113 MemberInfo memberInfo;
114 StructInfo structInfo;
123 static_assert(
sizeof(TypeInfo) == 8,
"Size must be 8 bytes");
127 constexpr TypeInfo(
TypeCategory type, uint16_t sizeInBytes, StructInfo structInfo)
128 : hasLink(false), type(type), numberOfChildren(0), sizeInBytes(sizeInBytes), structInfo(structInfo)
132 constexpr TypeInfo(
TypeCategory type, uint16_t sizeInBytes, MemberInfo member)
133 : hasLink(true), type(type), linkIndex(0), sizeInBytes(sizeInBytes), memberInfo(member)
137 constexpr TypeInfo(
TypeCategory type, uint16_t sizeInBytes, uint8_t numberOfChildren, ArrayInfo arrayInfo)
138 : hasLink(false), type(type), numberOfChildren(numberOfChildren), sizeInBytes(sizeInBytes), arrayInfo(arrayInfo)
142 constexpr TypeInfo(
TypeCategory type, uint16_t sizeInBytes)
143 : hasLink(true), type(type), linkIndex(0), sizeInBytes(sizeInBytes), emptyInfo()
147 [[nodiscard]]
constexpr auto getNumberOfChildren()
const {
return numberOfChildren; }
152 [[nodiscard]]
constexpr bool setNumberOfChildren(
size_t numChildren)
154 if (numChildren >
static_cast<decltype(numberOfChildren)
>(~0ull))
156 numberOfChildren =
static_cast<decltype(numberOfChildren)
>(numChildren);
161 [[nodiscard]]
constexpr bool hasValidLinkIndex()
const {
return hasLink and linkIndex > 0; }
164 [[nodiscard]]
constexpr bool needsLinking()
const {
return hasLink and linkIndex == 0; }
168 [[nodiscard]]
constexpr auto getLinkIndex()
const {
return linkIndex; }
173 [[nodiscard]]
constexpr bool setLinkIndex(ssize_t newLinkIndex)
175 if (newLinkIndex >
static_cast<decltype(linkIndex)
>(~0ull))
177 linkIndex =
static_cast<decltype(linkIndex)
>(newLinkIndex);
182 [[nodiscard]]
constexpr bool isPrimitiveType()
const {
return isPrimitiveCategory(type); }
185 [[nodiscard]]
constexpr bool isPrimitiveOrPackedStruct()
const
187 if (isPrimitiveType())
192 [[nodiscard]]
static constexpr bool isPrimitiveCategory(
TypeCategory category)
205template <
typename T,
typename SFINAESelector =
void>
206struct ExtendedTypeInfo;
213struct ReflectPrimitive
215 template <
typename TypeVisitor>
216 [[nodiscard]]
static constexpr bool build(TypeVisitor&)
223template <>
struct Reflect<char> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT8;}};
224template <>
struct Reflect<uint8_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeUINT8;}};
225template <>
struct Reflect<uint16_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeUINT16;}};
226template <>
struct Reflect<uint32_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeUINT32;}};
227template <>
struct Reflect<uint64_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeUINT64;}};
228template <>
struct Reflect<int8_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT8;}};
229template <>
struct Reflect<int16_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT16;}};
230template <>
struct Reflect<int32_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT32;}};
231template <>
struct Reflect<int64_t> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT64;}};
232template <>
struct Reflect<float> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeFLOAT32;}};
233template <>
struct Reflect<double> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeDOUBLE64;}};
234template <>
struct Reflect<bool> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeBOOL;}};
237template <
typename T>
struct IsPrimitive {
static constexpr bool value = TypeInfo::isPrimitiveCategory(Reflect<T>::getCategory()); };
238template <
typename T>
struct IsStruct {
static constexpr bool value = Reflect<T>::getCategory() ==
TypeCategory::TypeStruct; };
243struct ExtendedTypeInfo<T, typename SC::TypeTraits::EnableIf<IsPrimitive<T>::value>::type>
246 static constexpr bool IsPacked =
true;
252template <
typename T,
size_t N>
257 template <
typename TypeVisitor>
258 [[nodiscard]]
static constexpr bool build(TypeVisitor& builder)
260 using Type =
typename TypeVisitor::Type;
263 constexpr bool isPacked = ExtendedTypeInfo<T>::IsPacked;
264 if (not builder.addType(Type::template createArray<T[N]>(
"Array", 1, TypeInfo::ArrayInfo{isPacked, N})))
268 if (not builder.addType(Type::template createGeneric<T>()))
275template <
typename T,
int N>
276struct ExtendedTypeInfo<T[N]>
279 static constexpr bool IsPacked = ExtendedTypeInfo<T>::IsPacked;
285template <
typename Type>
292 template <
typename TypeVisitor>
293 [[nodiscard]]
static constexpr bool build(TypeVisitor& builder)
296 if (not builder.addType(TypeVisitor::Type::template createStruct<T>()))
300 if (not Reflect<Type>::visit(builder))
308struct ExtendedStructTypeInfo
310 size_t memberSizeSum = 0;
311 bool IsPacked =
false;
313 constexpr ExtendedStructTypeInfo()
316 if (Reflect<T>::visit(*
this))
320 IsPacked = memberSizeSum ==
sizeof(T);
324 template <
typename R,
int N>
325 constexpr bool operator()(
int memberTag, R T::* member,
const char (&name)[N],
size_t offset)
331 if (not ExtendedTypeInfo<R>().IsPacked)
335 memberSizeSum +=
sizeof(R);
340template <
typename T,
typename SFINAESelector>
341struct ExtendedTypeInfo
344 static constexpr bool IsPacked = ExtendedStructTypeInfo<T>().IsPacked;
347template <
typename MemberVisitor,
typename Container,
typename ItemType,
int N>
348struct VectorArrayVTable
350 static constexpr bool build(MemberVisitor&) {
return true; }
358#define SC_REFLECT_STRUCT_VISIT(StructName) \
360 struct SC::Reflection::Reflect<StructName> : SC::Reflection::ReflectStruct<StructName> \
362 template <typename TypeVisitor> \
363 static constexpr bool visit(TypeVisitor&& builder) \
365 SC_COMPILER_WARNING_PUSH_OFFSETOF \
370#define SC_REFLECT_STRUCT_FIELD(MEMBER_TAG, MEMBER) \
371 and builder(MEMBER_TAG, &T::MEMBER, #MEMBER, SC_COMPILER_OFFSETOF(T, MEMBER))
374#define SC_REFLECT_STRUCT_LEAVE() \
376 SC_COMPILER_WARNING_POP_OFFSETOF \
TypeCategory
Enumeration of possible category types recognized by Reflection.
Definition Reflection.h:39
@ TypeUINT32
Type is uint32_t
@ TypeUINT16
Type is uint16_t
@ TypeUINT64
Type is uint64_t
@ TypeArray
Type is an array type.
@ TypeINT16
Type is int16_t
@ TypeINT64
Type is int64_t
@ TypeINT32
Type is int32_t
@ TypeVector
Type is a vector type.
@ TypeFLOAT32
Type is float
@ TypeUINT8
Type is uint8_t
@ TypeStruct
Type is a struct type.
@ TypeDOUBLE64
Type is double
@ TypeInvalid
Invalid type sentinel.