(original) (raw)
//---------------------------------------------------------------------------------------------------------------------- // SaneCppContainersReflection.h - Sane C++ ContainersReflection Library (single file build) //---------------------------------------------------------------------------------------------------------------------- // Dependencies: SaneCppContainers.h, SaneCppFoundation.h, SaneCppMemory.h, SaneCppReflection.h // Version: release/2025/11 (cf7313e5) // LOC header: 213 (code) + 98 (comments) // LOC implementation: 0 (code) + 0 (comments) // Documentation: https://pagghiu.github.io/SaneCppLibraries // Source Code: https://github.com/pagghiu/SaneCppLibraries //---------------------------------------------------------------------------------------------------------------------- // All copyrights and SPDX information for this library (each amalgamated section has its own copyright attributions): // Copyright (c) Stefano Cristiano // SPDX-License-Identifier: MIT //---------------------------------------------------------------------------------------------------------------------- #include "SaneCppContainers.h" #include "SaneCppFoundation.h" #include "SaneCppMemory.h" #include "SaneCppReflection.h" #if !defined(SANE_CPP_CONTAINERSREFLECTION_HEADER) #define SANE_CPP_CONTAINERSREFLECTION_HEADER 1 //---------------------------------------------------------------------------------------------------------------------- // ContainersReflection/ContainersReflection.h //---------------------------------------------------------------------------------------------------------------------- // Copyright (c) Stefano Cristiano // SPDX-License-Identifier: MIT namespace SC { namespace Reflection { // Forward Declarations (to avoid depending on Reflection) template struct ExtendedTypeInfo; template struct Reflect; template struct ExtendedTypeInfo<sc::array<t, n="">, void> { static constexpr bool IsPacked = false; static auto size(const SC::Array<t, n="">& object) { return object.size(); } static auto data(SC::Array<t, n="">& object) { return object.data(); } static bool resizeWithoutInitializing(SC::Array<t, n="">& object, size_t newSize) { return object.resizeWithoutInitializing(min(newSize, static_cast(N))); } static bool resize(SC::Array<t, n="">& object, size_t newSize) { return object.resize(min(newSize, static_cast(N))); } }; template struct Reflect<sc::array<t, n="">> { static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; } template static constexpr bool build(MemberVisitor& builder) { // TODO: Figure out a way to get rid of calling VectorArrayVTable here if (not VectorArrayVTable<membervisitor, sc::array<t,="" n="">, T, N>::build(builder)) return false; // Add Array type constexpr TypeInfo::ArrayInfo arrayInfo = {false, N}; // false == not packed if (not builder.addType(MemberVisitor::Type::template createArray<sc::array<t, n="">>("SC::Array", 1, arrayInfo))) return false; // Add dependent item type return builder.addType(MemberVisitor::Type::template createGeneric()); } }; template struct Reflectsc::vector\ { static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; } template static constexpr bool build(MemberVisitor& builder) { // TODO: Figure out a way to get rid of calling VectorArrayVTable here if (not VectorArrayVTable<membervisitor, sc::vector<t="">, T, -1>::build(builder)) return false; // Add Vector type constexpr TypeInfo::ArrayInfo arrayInfo = {false, 0}; // false == not packed if (not builder.addType(MemberVisitor::Type::template createArraysc::vector\("SC::Vector", 1, arrayInfo))) return false; // Add dependent item type return builder.addType(MemberVisitor::Type::template createGeneric()); } }; template struct ExtendedTypeInfo<sc::vector, void> { static constexpr bool IsPacked = false; static auto size(const SC::Vector& object) { return object.size(); } static auto data(SC::Vector& object) { return object.data(); } static bool resizeWithoutInitializing(SC::Vector& object, size_t newSize) { return object.resizeWithoutInitializing(newSize); } static bool resize(SC::Vector& object, size_t newSize) { return object.resize(newSize); } }; template struct Reflect<vectormap<key, value,="" container="">> : ReflectStruct<vectormap<key, value,="" container="">> { using T = typename SC::VectorMap<key, value,="" container="">; template static constexpr bool visit(MemberVisitor&& builder) { return builder(0, "items", &T::items, SC_COMPILER_OFFSETOF(T, items)); } }; } // namespace Reflection } // namespace SC //---------------------------------------------------------------------------------------------------------------------- // ContainersReflection/ContainersSerialization.h //---------------------------------------------------------------------------------------------------------------------- // Copyright (c) Stefano Cristiano // SPDX-License-Identifier: MIT namespace SC { namespace Serialization { // Forward Declarations (to avoid depending on SerializationBinary) template struct SerializerBinaryReadWriteExact; template struct SerializerBinaryExactVector; template struct SerializerBinaryReadVersioned; template struct SerializationBinaryVersionedVector; // Forward Declarations (to avoid depending on SerializationText) template struct SerializationTextVersionedVector; template struct SerializationTextReadWriteExact; template struct SerializationTextExactVector; template struct SerializationTextReadVersioned; // clang-format off /// @brief Specialization for `SC::Vector` types template struct SerializerBinaryReadWriteExact<binarystream, sc::vector<t="">, void> : public SerializerBinaryExactVector<binarystream, sc::vector<t="">, T> { }; /// @brief Specialization for `SC::Array<t, n="">` types template struct SerializerBinaryReadWriteExact<binarystream, sc::array<t,="" n="">, void> : public SerializerBinaryExactVector<binarystream, sc::array<t,="" n="">, T> { }; template struct SerializerBinaryReadVersioned<binarystream, sc::vector<t="">, void> : public SerializationBinaryVersionedVector<binarystream, sc::vector<t="">, T, 0xffffffff> { }; template struct SerializerBinaryReadVersioned<binarystream, sc::array<t,="" n="">, void> : public SerializationBinaryVersionedVector<binarystream, sc::array<t,="" n="">, T, N> { }; template struct SerializationTextReadWriteExact<textstream, sc::vector<t="">, void> : public SerializationTextExactVector<textstream, sc::vector<t="">, T> { }; template struct SerializationTextReadWriteExact<textstream, sc::array<t,="" n="">, void> : public SerializationTextExactVector<textstream, sc::array<t,="" n="">, T> { }; template struct SerializationTextReadVersioned<serializerstream, sc::vector<t="">, void> : public SerializationTextVersionedVector<serializerstream, sc::vector<t="">, T> { }; template struct SerializationTextReadVersioned<serializerstream, sc::array<t,="" n="">, void> : public SerializationTextVersionedVector<serializerstream, sc::array<t,="" n="">, T> { }; // clang-format on } // namespace Serialization } // namespace SC //---------------------------------------------------------------------------------------------------------------------- // ContainersReflection/MemoryReflection.h //---------------------------------------------------------------------------------------------------------------------- // Copyright (c) Stefano Cristiano // SPDX-License-Identifier: MIT namespace SC { namespace Reflection { // Forward Declarations (to avoid depending on Reflection) template struct ExtendedTypeInfo; template struct Reflect; template <> struct Reflect{ static constexpr TypeCategory getCategory() { return TypeCategory::TypeVector; } template static constexpr bool build(MemberVisitor& builder) { // TODO: Figure out a way to get rid of calling VectorArrayVTable here if (not VectorArrayVTable<membervisitor, sc::buffer,="" char,="" -1="">::build(builder)) return false; // Add Vector type constexpr TypeInfo::ArrayInfo arrayInfo = {false, 0}; // false == not packed if (not builder.addType(MemberVisitor::Type::template createArray("SC::Buffer", 1, arrayInfo))) return false; // Add dependent item type return builder.addType(MemberVisitor::Type::template createGeneric()); } }; template <> struct ExtendedTypeInfo<sc::buffer, void=""> { static constexpr bool IsPacked = false; static auto size(const Buffer& object) { return object.size(); } static auto data(Buffer& object) { return object.data(); } static bool resizeWithoutInitializing(Buffer& object, size_t newSize) { return object.resizeWithoutInitializing(newSize); } static bool resize(Buffer& object, size_t newSize) { return object.resize(newSize, 0); } }; // TODO: Rethink if enumerations should not be collapsed to their underlying primitive type template <> struct Reflect : Reflect{ static_assert(sizeof(SC::StringEncoding) == sizeof(uint8_t), "size"); }; } // namespace Reflection } // namespace SC SC_REFLECT_STRUCT_VISIT(SC::String) SC_REFLECT_STRUCT_FIELD(0, encoding) // TODO: Maybe encoding should be merged in data header SC_REFLECT_STRUCT_FIELD(1, data) SC_REFLECT_STRUCT_LEAVE() //---------------------------------------------------------------------------------------------------------------------- // ContainersReflection/MemorySerialization.h //---------------------------------------------------------------------------------------------------------------------- // Copyright (c) Stefano Cristiano // SPDX-License-Identifier: MIT namespace SC { namespace Serialization { // Forward Declarations (to avoid depending on SerializationBinary) template struct SerializerBinaryReadWriteExact; template struct SerializerBinaryExactVector; template struct SerializerBinaryReadVersioned; template struct SerializationBinaryVersionedVector; // Forward Declarations (to avoid depending on SerializationText) template struct SerializationTextReadWriteExact; template struct SerializationTextExactVector; template struct SerializationTextReadVersioned; // clang-format off /// @brief Specialization for `SC::Buffer` type template struct SerializerBinaryReadWriteExact<binarystream, sc::buffer,="" void=""> : public SerializerBinaryExactVector<binarystream, sc::buffer,="" char=""> { }; template struct SerializerBinaryReadVersioned<binarystream, sc::buffer,="" void=""> : public SerializationBinaryVersionedVector<binarystream, sc::buffer,="" char,="" 0xffffffff=""> { }; template struct SerializationTextReadWriteExact<textstream, string,="" void=""> { [[nodiscard]] static constexpr bool serialize(uint32_t index, String& object, TextStream& stream) { return stream.serialize(index, object); } }; template struct SerializationTextReadVersioned<serializerstream, string,="" void=""> { [[nodiscard]] static constexpr bool loadVersioned(uint32_t index, String& object, SerializerStream& stream) { return stream.serialize(index, object); } }; // clang-format on } // namespace Serialization } // namespace SC #endif // SANE_CPP_CONTAINERSREFLECTION_HEADER </serializerstream,></textstream,></binarystream,></binarystream,></binarystream,></binarystream,></sc::buffer,></membervisitor,></serializerstream,></serializerstream,></serializerstream,></serializerstream,></textstream,></textstream,></textstream,></textstream,></binarystream,></binarystream,></binarystream,></binarystream,></binarystream,></binarystream,></t,></binarystream,></binarystream,></key,></vectormap<key,></vectormap<key,></sc::vector</sc::vector</membervisitor,></sc::vector</sc::array<t,></membervisitor,></sc::array<t,></t,></t,></t,></t,></sc::array<t,>