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 "../Foundation/Buffer.h"
8#include "../Strings/String.h"
9#include "Reflection.h"
10
11//-----------------------------------------------------------------------------------------------------------
12// SC Types Support
13//-----------------------------------------------------------------------------------------------------------
14namespace SC
15{
16namespace Reflection
17{
18
19template <typename MemberVisitor, typename Container, typename ItemType, int N>
21{
22 [[nodiscard]] static constexpr bool build(MemberVisitor&) { return true; }
23};
24
25template <typename T, int N>
26struct ExtendedTypeInfo<SC::Array<T, N>>
27{
28 static constexpr bool IsPacked = false;
29
30 [[nodiscard]] static auto size(const SC::Array<T, N>& object) { return object.size(); }
31 [[nodiscard]] static auto data(SC::Array<T, N>& object) { return object.data(); }
32 [[nodiscard]] static bool resizeWithoutInitializing(SC::Array<T, N>& object, size_t newSize)
33 {
34 return object.resizeWithoutInitializing(min(newSize, static_cast<size_t>(N)));
35 }
36 [[nodiscard]] static bool resize(SC::Array<T, N>& object, size_t newSize)
37 {
38 return object.resize(min(newSize, static_cast<size_t>(N)));
39 }
40};
41
42template <typename T, int N>
43struct Reflect<SC::Array<T, N>>
44{
45 static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; }
46
47 template <typename MemberVisitor>
48 [[nodiscard]] static constexpr bool build(MemberVisitor& builder)
49 {
50 // TODO: Figure out a way to get rid of calling VectorArrayVTable here
51 if (not VectorArrayVTable<MemberVisitor, SC::Array<T, N>, T, N>::build(builder))
52 return false;
53
54 // Add Array type
55 constexpr TypeInfo::ArrayInfo arrayInfo = {false, N}; // false == not packed
56 if (not builder.addType(MemberVisitor::Type::template createArray<SC::Array<T, N>>("SC::Array", 1, arrayInfo)))
57 return false;
58
59 // Add dependent item type
60 return builder.addType(MemberVisitor::Type::template createGeneric<T>());
61 }
62};
63
64template <typename T>
65struct Reflect<SC::Vector<T>>
66{
67 static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; }
68
69 template <typename MemberVisitor>
70 [[nodiscard]] static constexpr bool build(MemberVisitor& builder)
71 {
72 // TODO: Figure out a way to get rid of calling VectorArrayVTable here
73 if (not VectorArrayVTable<MemberVisitor, SC::Vector<T>, T, -1>::build(builder))
74 return false;
75
76 // Add Vector type
77 constexpr TypeInfo::ArrayInfo arrayInfo = {false, 0}; // false == not packed
78 if (not builder.addType(MemberVisitor::Type::template createArray<SC::Vector<T>>("SC::Vector", 1, arrayInfo)))
79 return false;
80
81 // Add dependent item type
82 return builder.addType(MemberVisitor::Type::template createGeneric<T>());
83 }
84};
85
86template <typename T>
87struct ExtendedTypeInfo<SC::Vector<T>>
88{
89 static constexpr bool IsPacked = false;
90
91 [[nodiscard]] static auto size(const SC::Vector<T>& object) { return object.size(); }
92 [[nodiscard]] static auto data(SC::Vector<T>& object) { return object.data(); }
93 [[nodiscard]] static bool resizeWithoutInitializing(SC::Vector<T>& object, size_t newSize)
94 {
95 return object.resizeWithoutInitializing(newSize);
96 }
97 [[nodiscard]] static bool resize(SC::Vector<T>& object, size_t newSize) { return object.resize(newSize); }
98};
99
100template <>
101struct Reflect<SC::Buffer>
102{
103 static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; }
104
105 template <typename MemberVisitor>
106 [[nodiscard]] static constexpr bool build(MemberVisitor& builder)
107 {
108 // TODO: Figure out a way to get rid of calling VectorArrayVTable here
109 if (not VectorArrayVTable<MemberVisitor, SC::Buffer, char, -1>::build(builder))
110 return false;
111
112 // Add Vector type
113 constexpr TypeInfo::ArrayInfo arrayInfo = {false, 0}; // false == not packed
114 if (not builder.addType(MemberVisitor::Type::template createArray<SC::Buffer>("SC::Buffer", 1, arrayInfo)))
115 return false;
116
117 // Add dependent item type
118 return builder.addType(MemberVisitor::Type::template createGeneric<char>());
119 }
120};
121template <>
122struct ExtendedTypeInfo<SC::Buffer>
123{
124 static constexpr bool IsPacked = false;
125
126 [[nodiscard]] static auto size(const Buffer& object) { return object.size(); }
127 [[nodiscard]] static auto data(Buffer& object) { return object.data(); }
128 [[nodiscard]] static bool resizeWithoutInitializing(Buffer& object, size_t newSize)
129 {
130 return object.resizeWithoutInitializing(newSize);
131 }
132 [[nodiscard]] static bool resize(Buffer& object, size_t newSize) { return object.resize(newSize, 0); }
133};
134
135template <typename Key, typename Value, typename Container>
136struct Reflect<VectorMap<Key, Value, Container>> : ReflectStruct<VectorMap<Key, Value, Container>>
137{
138 using T = typename SC::VectorMap<Key, Value, Container>;
139
140 template <typename MemberVisitor>
141 [[nodiscard]] static constexpr bool visit(MemberVisitor&& builder)
142 {
143 return builder(0, "items", &T::items, SC_COMPILER_OFFSETOF(T, items));
144 }
145};
146
147// TODO: Rethink if enumerations should not be collapsed to their underlying primitive type
148template <>
149struct Reflect<SC::StringEncoding> : Reflect<uint8_t>
150{
151 static_assert(sizeof(SC::StringEncoding) == sizeof(uint8_t), "size");
152};
153
154} // namespace Reflection
155} // namespace SC
156
157SC_REFLECT_STRUCT_VISIT(SC::String)
158SC_REFLECT_STRUCT_FIELD(0, encoding) // TODO: Maybe encoding should be merged in data header
159SC_REFLECT_STRUCT_FIELD(1, data)
160SC_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:23
size_t size() const
Returns the size of the array.
Definition: Array.h:181
Class template used to check if a given type IsPacked property is true at compile time.
Definition: Reflection.h:334
Definition: ReflectionSC.h:21
A non-modifiable owning string with associated encoding.
Definition: String.h:29
A contiguous sequence of heap allocated elements.
Definition: Vector.h:259
A map holding VectorMapItem key-value pairs in an unsorted Vector.
Definition: VectorMap.h:35