5#include "../Foundation/Compiler.h"
6#ifndef SC_EXPORT_LIBRARY_REFLECTION
7#define SC_EXPORT_LIBRARY_REFLECTION 0
9#define SC_REFLECTION_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_REFLECTION)
11#include "../Foundation/TypeTraits.h"
12#include "ReflectionFoundation.h"
90 : memberTag(memberTag), offsetInBytes(offsetInBytes)
98 constexpr StructInfo(
bool isPacked) : isPacked(isPacked) {}
106 constexpr ArrayInfo(
bool isPacked,
uint32_t numElements) : isPacked(isPacked), numElements(numElements) {}
111 MemberInfo memberInfo;
112 StructInfo structInfo;
121 static_assert(
sizeof(TypeInfo) == 8,
"Size must be 8 bytes");
126 : hasLink(false), type(type), numberOfChildren(0), sizeInBytes(sizeInBytes), structInfo(structInfo)
131 : hasLink(true), type(type), linkIndex(0), sizeInBytes(sizeInBytes), memberInfo(member)
136 : hasLink(false), type(type), numberOfChildren(numberOfChildren), sizeInBytes(sizeInBytes), arrayInfo(arrayInfo)
141 : hasLink(true), type(type), linkIndex(0), sizeInBytes(sizeInBytes), emptyInfo()
145 [[nodiscard]]
constexpr auto getNumberOfChildren()
const {
return numberOfChildren; }
150 [[nodiscard]]
constexpr bool setNumberOfChildren(
size_t numChildren)
152 if (numChildren >
static_cast<decltype(numberOfChildren)
>(~0ull))
154 numberOfChildren =
static_cast<decltype(numberOfChildren)
>(numChildren);
159 [[nodiscard]]
constexpr bool hasValidLinkIndex()
const {
return hasLink and linkIndex > 0; }
162 [[nodiscard]]
constexpr bool needsLinking()
const {
return hasLink and linkIndex == 0; }
166 [[nodiscard]]
constexpr auto getLinkIndex()
const {
return linkIndex; }
171 [[nodiscard]]
constexpr bool setLinkIndex(
ssize_t newLinkIndex)
173 if (newLinkIndex >
static_cast<decltype(linkIndex)
>(~0ull))
175 linkIndex =
static_cast<decltype(linkIndex)
>(newLinkIndex);
180 [[nodiscard]]
constexpr bool isPrimitiveType()
const {
return isPrimitiveCategory(type); }
183 [[nodiscard]]
constexpr bool isPrimitiveOrPackedStruct()
const
185 if (isPrimitiveType())
190 [[nodiscard]]
static constexpr bool isPrimitiveCategory(
TypeCategory category)
203template <
typename T,
typename SFINAESelector =
void>
204struct ExtendedTypeInfo;
211struct ReflectPrimitive
213 template <
typename TypeVisitor>
214 [[nodiscard]]
static constexpr bool build(TypeVisitor&)
221template <>
struct Reflect<char> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeINT8;}};
230template <>
struct Reflect<float> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeFLOAT32;}};
231template <>
struct Reflect<double> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeDOUBLE64;}};
232template <>
struct Reflect<bool> :
public ReflectPrimitive {
static constexpr auto getCategory(){
return TypeCategory::TypeBOOL;}};
235template <
typename T>
struct IsPrimitive {
static constexpr bool value = TypeInfo::isPrimitiveCategory(Reflect<T>::getCategory()); };
236template <
typename T>
struct IsStruct {
static constexpr bool value = Reflect<T>::getCategory() ==
TypeCategory::TypeStruct; };
241struct ExtendedTypeInfo<T, typename SC::TypeTraits::EnableIf<IsPrimitive<T>::value>::type>
244 static constexpr bool IsPacked =
true;
250template <
typename T,
size_t N>
255 template <
typename TypeVisitor>
256 [[nodiscard]]
static constexpr bool build(TypeVisitor& builder)
258 using Type =
typename TypeVisitor::Type;
261 constexpr bool isPacked = ExtendedTypeInfo<T>::IsPacked;
262 if (not builder.addType(Type::template createArray<T[N]>(
"Array", 1, TypeInfo::ArrayInfo{isPacked, N})))
266 if (not builder.addType(Type::template createGeneric<T>()))
273template <
typename T,
int N>
274struct ExtendedTypeInfo<T[N]>
277 static constexpr bool IsPacked = ExtendedTypeInfo<T>::IsPacked;
283template <
typename Type>
290 template <
typename TypeVisitor>
291 [[nodiscard]]
static constexpr bool build(TypeVisitor& builder)
294 if (not builder.addType(TypeVisitor::Type::template createStruct<T>()))
298 if (not Reflect<Type>::visit(builder))
306struct ExtendedStructTypeInfo
308 size_t memberSizeSum = 0;
309 bool IsPacked =
false;
311 constexpr ExtendedStructTypeInfo()
314 if (Reflect<T>::visit(*
this))
318 IsPacked = memberSizeSum ==
sizeof(T);
322 template <
typename R,
int N>
323 constexpr bool operator()(
int memberTag, R T::* member,
const char (&name)[N],
size_t offset)
329 if (not ExtendedTypeInfo<R>().IsPacked)
333 memberSizeSum +=
sizeof(R);
338template <
typename T,
typename SFINAESelector>
339struct ExtendedTypeInfo
342 static constexpr bool IsPacked = ExtendedStructTypeInfo<T>().IsPacked;
345template <
typename MemberVisitor,
typename Container,
typename ItemType,
int N>
346struct VectorArrayVTable
348 static constexpr bool build(MemberVisitor&) {
return true; }
356#define SC_REFLECT_STRUCT_VISIT(StructName) \
358 struct SC::Reflection::Reflect<StructName> : SC::Reflection::ReflectStruct<StructName> \
360 template <typename TypeVisitor> \
361 static constexpr bool visit(TypeVisitor&& builder) \
363 SC_COMPILER_WARNING_PUSH_OFFSETOF \
368#define SC_REFLECT_STRUCT_FIELD(MEMBER_TAG, MEMBER) \
369 and builder(MEMBER_TAG, &T::MEMBER, #MEMBER, SC_COMPILER_OFFSETOF(T, MEMBER))
372#define SC_REFLECT_STRUCT_LEAVE() \
374 SC_COMPILER_WARNING_POP \
#define SC_COMPILER_UNUSED(param)
Silence an unused variable or unused parameter warning.
Definition Compiler.h:148
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 long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
short int16_t
Platform independent (2) bytes signed int.
Definition PrimitiveTypes.h:45
long long int64_t
Platform independent (8) bytes signed int.
Definition PrimitiveTypes.h:50
signed char int8_t
Platform independent (1) byte signed int.
Definition PrimitiveTypes.h:44
signed long ssize_t
Platform independent signed size type.
Definition PrimitiveTypes.h:57
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:46
TypeCategory
Enumeration of possible category types recognized by Reflection.
Definition Reflection.h:37
@ 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.