Sane C++ Libraries
C++ Platform Abstraction Libraries
ReflectionSC.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Containers/Array.h"
5#include "../Containers/Vector.h"
6#include "../Containers/VectorMap.h"
7#include "../Strings/String.h"
8#include "Reflection.h"
9
10//-----------------------------------------------------------------------------------------------------------
11// SC Types Support
12//-----------------------------------------------------------------------------------------------------------
13namespace SC
14{
15namespace Reflection
16{
17
18template <typename MemberVisitor, typename Container, typename ItemType, int N>
20{
21 [[nodiscard]] static constexpr bool build(MemberVisitor&) { return true; }
22};
23
24template <typename T, int N>
25struct ExtendedTypeInfo<SC::Array<T, N>>
26{
27 static constexpr bool IsPacked = false;
28
29 [[nodiscard]] static auto size(const SC::Array<T, N>& object) { return object.size(); }
30 [[nodiscard]] static auto data(SC::Array<T, N>& object) { return object.data(); }
31 [[nodiscard]] static bool resizeWithoutInitializing(SC::Array<T, N>& object, size_t newSize)
32 {
33 return object.resizeWithoutInitializing(min(newSize, static_cast<size_t>(N)));
34 }
35 [[nodiscard]] static bool resize(SC::Array<T, N>& object, size_t newSize)
36 {
37 return object.resize(min(newSize, static_cast<size_t>(N)));
38 }
39};
40
41template <typename T, int N>
42struct Reflect<SC::Array<T, N>>
43{
44 static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; }
45
46 template <typename MemberVisitor>
47 [[nodiscard]] static constexpr bool build(MemberVisitor& builder)
48 {
49 // TODO: Figure out a way to get rid of calling VectorArrayVTable here
50 if (not VectorArrayVTable<MemberVisitor, SC::Array<T, N>, T, N>::build(builder))
51 return false;
52
53 // Add Array type
54 constexpr TypeInfo::ArrayInfo arrayInfo = {false, N}; // false == not packed
55 if (not builder.addType(MemberVisitor::Type::template createArray<SC::Array<T, N>>("SC::Array", 1, arrayInfo)))
56 return false;
57
58 // Add dependent item type
59 return builder.addType(MemberVisitor::Type::template createGeneric<T>());
60 }
61};
62
63template <typename T>
64struct Reflect<SC::Vector<T>>
65{
66 static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; }
67
68 template <typename MemberVisitor>
69 [[nodiscard]] static constexpr bool build(MemberVisitor& builder)
70 {
71 // TODO: Figure out a way to get rid of calling VectorArrayVTable here
72 if (not VectorArrayVTable<MemberVisitor, SC::Vector<T>, T, -1>::build(builder))
73 return false;
74
75 // Add Vector type
76 constexpr TypeInfo::ArrayInfo arrayInfo = {false, 0}; // false == not packed
77 if (not builder.addType(MemberVisitor::Type::template createArray<SC::Vector<T>>("SC::Vector", 1, arrayInfo)))
78 return false;
79
80 // Add dependent item type
81 return builder.addType(MemberVisitor::Type::template createGeneric<T>());
82 }
83};
84
85template <typename T>
86struct ExtendedTypeInfo<SC::Vector<T>>
87{
88 static constexpr bool IsPacked = false;
89
90 [[nodiscard]] static auto size(const SC::Vector<T>& object) { return object.size(); }
91 [[nodiscard]] static auto data(SC::Vector<T>& object) { return object.data(); }
92 [[nodiscard]] static bool resizeWithoutInitializing(SC::Vector<T>& object, size_t newSize)
93 {
94 return object.resizeWithoutInitializing(newSize);
95 }
96 [[nodiscard]] static bool resize(SC::Vector<T>& object, size_t newSize) { return object.resize(newSize); }
97};
98
99template <typename Key, typename Value, typename Container>
100struct Reflect<VectorMap<Key, Value, Container>> : ReflectStruct<VectorMap<Key, Value, Container>>
101{
102 using T = typename SC::VectorMap<Key, Value, Container>;
103
104 template <typename MemberVisitor>
105 [[nodiscard]] static constexpr bool visit(MemberVisitor&& builder)
106 {
107 return builder(0, "items", &T::items, SC_COMPILER_OFFSETOF(T, items));
108 }
109};
110
111// TODO: Rethink if enumerations should not be collapsed to their underlying primitive type
112template <>
113struct Reflect<SC::StringEncoding> : Reflect<uint8_t>
114{
115 static_assert(sizeof(SC::StringEncoding) == sizeof(uint8_t), "size");
116};
117
118} // namespace Reflection
119} // namespace SC
120
121SC_REFLECT_STRUCT_VISIT(SC::String)
122SC_REFLECT_STRUCT_FIELD(0, encoding) // TODO: Maybe encoding should be merged in data header
123SC_REFLECT_STRUCT_FIELD(1, data)
124SC_REFLECT_STRUCT_LEAVE()
constexpr const T & min(const T &t1, const T &t2)
Finds the minimum of two values.
Definition: Compiler.h:300
#define SC_COMPILER_OFFSETOF(Class, Field)
Returns offset of Class::Field in bytes.
Definition: Compiler.h:111
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition: PrimitiveTypes.h:36
TypeCategory
Enumeration of possible category types recognized by Reflection.
Definition: Reflection.h:32
@ TypeVector
Type is a vector type.
StringEncoding
String Encoding (Ascii, Utf8, Utf16)
Definition: StringIterator.h:17
A contiguous sequence of elements kept inside its inline storage.
Definition: Array.h:43
size_t size() const
Gets size of the array.
Definition: Array.h:198
Class template used to check if a given type IsPacked property is true at compile time.
Definition: Reflection.h:334
Definition: ReflectionSC.h:20
A non-modifiable owning string with associated encoding.
Definition: String.h:30
A contiguous sequence of heap allocated elements.
Definition: Vector.h:51
A map holding VectorMapItem key-value pairs in an unsorted Vector.
Definition: VectorMap.h:70