ReflectedDynArray.h

// ReflectedDynArray.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2022

@import "IObject.h"
@import "ReflectedType.h"

namespace ceda
{
struct ReflectedDynArray
{
    inline void* GetArrayElement(void* data, ssize_t index) const
    {
        cxAssert(data);
        cxAssert(0 <= index);
        const TypeOps* elementOps = GetTypeOps(element);
        cxAssert(elementOps);
        auto elementSize = elementOps->size;
        cxAssert(elementSize > 0);
        auto n = elementSize * index;
        VectorOfByte& V = *reinterpret_cast<VectorOfByte*>(data);
        if (V.size() <= n)
        {
            V.resize(n + elementSize);
        }
        return &V[n];
    }
    inline const void* GetArrayElement(const void* data, ssize_t index) const
    {
        return GetArrayElement(const_cast<void*>(data), index);
    }

    const TypeOps& ops;
    ReflectedType element;
};

@api xostream& operator<<(xostream& os, const ReflectedDynArray& r);

template<typename T> struct is_DynArray { constexpr static bool value = false; };
template<typename T> struct is_DynArray<DynArray<T>> { constexpr static bool value = true; };

template<typename T>
inline const ReflectedDynArray& GetReflectedDynArray()
{
    static ReflectedDynArray s =
    {
        GetTypeOpsX<DynArray<T>>(),
        GetReflectedType<T>()
    };
    return s;
}

template<typename T>
struct GetReflectedType_class<DynArray<T>> 
{
    static inline ReflectedType get()
    {
        ReflectedType r;
        r.tag = EReflectedTypeTag::DynArray;
        r.DynArray = &GetReflectedDynArray<T>();
        return r;
    }
};
} // namespace ceda