refl support ctor list

This commit is contained in:
ouczbs 2024-06-12 22:07:45 +08:00
parent 0cdc1d1948
commit a5bfccc1d8
11 changed files with 243 additions and 105 deletions

View File

@ -12,9 +12,7 @@ namespace refl {
} }
inline bool Convert::Construct(Any& dst, const Any& src) inline bool Convert::Construct(Any& dst, const Any& src)
{ {
if (dst.Check(src.cls)) { if (dst.cls->CtorObject((void*)dst.ptr, src)) {
dst.cls->parent->InitObject((void*)dst.ptr);
dst.cls->parent->CopyObject((void*)dst.ptr, src.ptr);
return true; return true;
} }
auto it = ClassMap.find(dst.cls); auto it = ClassMap.find(dst.cls);

View File

@ -36,7 +36,9 @@ namespace refl {
FIELD_MEMBER_FLAG = 1 << 0, FIELD_MEMBER_FLAG = 1 << 0,
FIELD_ATTRIBUTE_FLAG = 1 << 1, FIELD_ATTRIBUTE_FLAG = 1 << 1,
FIELD_METHOD_FLAG = 1 << 2, FIELD_METHOD_FLAG = 1 << 2,
FIELD_METHOD_VALUE_FLAG = 1 << 3 FIELD_METHOD_VALUE_FLAG = 1 << 3,
FIELD_CTOR_FLAG = 1 << 4,
FIELD_CTOR_VALUE_FLAG = 1 << 5,
}; };
using enum FieldFlag; using enum FieldFlag;
struct FieldPtr { struct FieldPtr {
@ -61,6 +63,9 @@ namespace refl {
//safe //safe
bool Invoke(svector<Any>& ArgsList)const; bool Invoke(svector<Any>& ArgsList)const;
template<typename TArgsList>
bool Invokes(TArgsList& ArgsList)const;
template<typename Func, typename... Args> template<typename Func, typename... Args>
auto Call(Func func, Args&&... args)const; auto Call(Func func, Args&&... args)const;

View File

@ -34,7 +34,7 @@ namespace refl {
if (argsSize < paramsSize) { if (argsSize < paramsSize) {
return false; return false;
} }
Any* a = ArgsList.front(); auto a = ArgsList.front();
auto p = params.front(); auto p = params.front();
for (auto e = params.back(); p < e; ++p, ++a) { for (auto e = params.back(); p < e; ++p, ++a) {
if (a->cls != *p && !a->Check(*p)) { if (a->cls != *p && !a->Check(*p)) {
@ -45,6 +45,25 @@ namespace refl {
} }
return Call; return Call;
} }
template<typename TArgsList>
inline bool FieldPtr::Invokes(TArgsList& ArgsList)const {
auto Call = type->vtable.Call;
if (Call) {
sarray<const UClass*> params = GetParams();
if (params.size() != ArgsList.size()) {
return false;
}
auto a = ArgsList.front();
auto p = params.front();
for (auto e = params.back(); p < e; ++p, ++a) {
if (a->cls != *p && !a->Check(*p)) {
return false;
}
}
Call(this, ArgsList);
}
return false;
}
inline sarray<const UClass*> FieldPtr::GetParams() const { inline sarray<const UClass*> FieldPtr::GetParams() const {
auto GetParams = type->vtable.GetParams; auto GetParams = type->vtable.GetParams;
if (GetParams) { if (GetParams) {

View File

@ -31,6 +31,9 @@ namespace refl {
class UClass; class UClass;
class Meta { class Meta {
public: public:
template<typename T, typename... Args>
static FieldPtr CtorField(char*& memory, const MemberData& data = {});
template<typename T, typename Obj> template<typename T, typename Obj>
static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {}); static FieldPtr MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data = {});

View File

@ -3,7 +3,29 @@
#include "uclass.h" #include "uclass.h"
#include "convert.h" #include "convert.h"
namespace refl { namespace refl {
template<typename T, typename ...Args>
inline FieldPtr Meta::CtorField(char*& memory, const MemberData& data)
{
MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_CTOR_FLAG;
constexpr auto cls = &TypeInfo<void(*)(const void*, real_type_t<Args>...)>::StaticClass;
if (data.value.IsValid()) {
flag |= FIELD_CTOR_VALUE_FLAG;
AnyArgs args(data.value, cls->GetParams(), memory);
method.value = args.ToSArray();
memory += args.Size();
}
if (data.meta.IsValid()) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
}
static auto ptr = [](void* mem, Args... args) {
new (mem) T(std::forward<Args>(args)...);
};
method.fptr = { *(Method*)&ptr };
return { FName("Ctor"), cls, method,flag};
}
template<typename T, typename Obj> template<typename T, typename Obj>
inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data) inline FieldPtr Meta::MemberField(T Obj::* ptr, const Name& name, char*& memory, const MemberData& data)
{ {
@ -29,7 +51,7 @@ namespace refl {
MethodData method; MethodData method;
uint32_t flag = FIELD_METHOD_FLAG; uint32_t flag = FIELD_METHOD_FLAG;
constexpr auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass; constexpr auto cls = &TypeInfo<real_type_t<R>(*)(real_type_t<Args>...)>::StaticClass;
if (data.value.IsValid()) { if (data.value.valid()) {
flag |= FIELD_METHOD_VALUE_FLAG; flag |= FIELD_METHOD_VALUE_FLAG;
AnyArgs args(data.value, cls->GetParams(), memory); AnyArgs args(data.value, cls->GetParams(), memory);
method.value = args.ToSArray(); method.value = args.ToSArray();
@ -49,7 +71,7 @@ namespace refl {
MethodData method; MethodData method;
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG; uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
constexpr auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass; constexpr auto cls = &TypeInfo<real_type_t<R>(*)(const void*, real_type_t<Args>...)>::StaticClass;
if (data.value.IsValid()) { if (data.value.valid()) {
flag |= FIELD_METHOD_VALUE_FLAG; flag |= FIELD_METHOD_VALUE_FLAG;
AnyArgs args(data.value, cls->GetParams(), memory); AnyArgs args(data.value, cls->GetParams(), memory);
method.value = args.ToSArray(); method.value = args.ToSArray();

View File

@ -2,6 +2,7 @@
#include "field.h" #include "field.h"
#include "view.h" #include "view.h"
#include "meta.h" #include "meta.h"
#include "convert.h"
namespace refl { namespace refl {
enum ClassFlag :uint32_t { enum ClassFlag :uint32_t {
CLASS_NONE_FLAG = 0, CLASS_NONE_FLAG = 0,
@ -10,10 +11,20 @@ namespace refl {
CLASS_ARRAY_FLAG = 1 << 2, CLASS_ARRAY_FLAG = 1 << 2,
}; };
using enum ClassFlag; using enum ClassFlag;
enum EFieldFind :uint32_t {
FIND_ALL_FIELD = 0,
FIND_ALL_MEMBER,
FIND_ALL_METHOD,
FIND_FIELD,
FIND_CTOR,
FIND_MEMBER,
FIND_METHOD,
FIND_METHODS,//函数重载 特别是构造函数
};
struct vtable_uclass struct vtable_uclass
{ {
//class //class
const FieldPtr* (*GetField)(const UClass*, const Name&, int); const sarray<const FieldPtr> (*GetFields)(const UClass*, EFieldFind find, const Name& name);
//function //function
sarray<const UClass*>(*GetParams)(const UClass*); sarray<const UClass*>(*GetParams)(const UClass*);
//function //function
@ -21,9 +32,8 @@ namespace refl {
//meta //meta
const UClass* (*GetMeta)(const Name&); const UClass* (*GetMeta)(const Name&);
//object //object
void (*InitObject)(void*); bool (*CtorObject)(void* ptr,const UClass* cls, const sarray<Any>& ArgsList);
void (*CopyObject)(void*, const void*); bool (*DestObject)(void*);
void (*DestObject)(void*);
}; };
class UClass{ class UClass{
public: public:
@ -35,22 +45,22 @@ namespace refl {
public: public:
constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr) constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
:name(name), size(size), parent(parent){} :name(name), size(size), parent(parent){}
AnyView New(void* ptr = nullptr) const{ AnyView New(void* ptr = nullptr, const sarray<Any>& ArgsList = {}) const {
if (ptr == nullptr) { if (ptr == nullptr) {
ptr = malloc(size); ptr = malloc(size);
InitObject(ptr); CtorObject(ptr, ArgsList);
} }
return { ptr , this }; return { ptr , this };
} }
template<typename T> template<typename T>
T* New(T* ptr = nullptr) const{ T* New(T* ptr = nullptr, const sarray<Any>& ArgsList = {}) const{
if (!IsChildOf<T>()) { if (!IsChildOf<T>()) {
return nullptr; return nullptr;
} }
if (ptr == nullptr) { if (ptr == nullptr) {
ptr = (T*)malloc(size); ptr = (T*)malloc(size);
} }
InitObject(ptr); CtorObject(ptr, ArgsList);
return ptr; return ptr;
} }
bool IsChildOf(const UClass* cls) const { bool IsChildOf(const UClass* cls) const {
@ -68,27 +78,33 @@ namespace refl {
return IsChildOf(&TypeInfo<T>::StaticClass); return IsChildOf(&TypeInfo<T>::StaticClass);
} }
public: public:
const FieldPtr* GetField(const Name& name, int index)const { const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name)const {
if (vtable.GetField) { if (vtable.GetFields) {
return vtable.GetField(this, name, index); return vtable.GetFields(this, find, name);
} }
return nullptr; return {};
} }
void InitObject(void* ptr)const { bool CtorObject(void* ptr, const sarray<Any>& ArgsList = {})const {
if (vtable.InitObject) { if (vtable.CtorObject) {
vtable.InitObject(ptr); if (vtable.CtorObject(ptr, this, ArgsList)) {
} return true;
else { }
memset(ptr, 0, size); auto& fieldList = GetFields(EFieldFind::FIND_CTOR, FName("Ctor"));
} if (fieldList.empty()) {
} return false;
void CopyObject(void* dst, const void* src)const { }
if (vtable.CopyObject) { if (fieldList.size() == 1) {
vtable.CopyObject(dst, src); return fieldList[0]->Invoke(ArgsList);
} }
else { for (auto& field : fieldList) {
memcpy(dst, src, size); if (field.Invokes(ArgsList)) {
return true;
}
}
return false;
} }
memset(ptr, 0, size);
return true;
} }
void DestObject(void* ptr)const { void DestObject(void* ptr)const {
if (vtable.DestObject) { if (vtable.DestObject) {
@ -96,30 +112,23 @@ namespace refl {
} }
} }
public: public:
template<_ReflCheck_Ctor T>
static void InitObject(void* ptr) {
T obj{};
std::construct_at((T*)ptr, obj);
}
template<typename T> template<typename T>
static void CopyObject(void* dst, const void* src) { static bool CtorObject(void* ptr, const UClass* cls, const sarray<Any>& ArgsList = {}) {
*(T*)dst = *(T*)src; int size = ArgsList.size();
} if (size == 0) {
template<_ReflCheck_Ctor T, int N> if constexpr (std::is_trivially_constructible_v<T>) {
static void InitObject(void* ptr) { std::construct_at((T*)ptr);
T* tptr = (T*)ptr; return true;
T obj{}; }
for (int i = 0; i < N; i++) { else {
std::construct_at(tptr++, obj); throw "refl::error:: no default construct function!!!";
}
} }
} if (size == 1 && ArgsList[0]->Check(cls)) {
template<typename T, int N> *(T*)ptr = *(const T*)ArgsList[0]->ptr;
static void CopyObject(void* dst, const void* src) { return true;
T* tdst = (T*)dst;
const T* tsrc = (const T*)src;
for (int i = 0; i < N; i++) {
*tdst++ = *tsrc++;
} }
return false;
} }
}; };
} }

View File

@ -10,20 +10,14 @@ namespace refl {
public: public:
consteval static MyUClass BuildClass() { consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T>().View(), sizeof(T)); MyUClass cls(type_name<T>().View(), sizeof(T));
if constexpr (!std::is_trivially_copyable_v<T>) { cls.vtable.CtorObject = &MyUClass::CtorObject<T>;
cls.vtable.InitObject = &MyUClass::InitObject<T>; if constexpr (std::is_pointer_v<T>){
cls.vtable.CopyObject = &MyUClass::CopyObject<T>;
}
else if constexpr (std::is_pointer_v<T>){
using RawT = std::remove_pointer_t<T>; using RawT = std::remove_pointer_t<T>;
cls.flag = CLASS_POINTER_FLAG; cls.flag = CLASS_POINTER_FLAG;
if constexpr (!std::is_same_v<RawT, void>) { if constexpr (!std::is_same_v<RawT, void>) {
cls.parent = &TypeInfo<RawT>::StaticClass; cls.parent = &TypeInfo<RawT>::StaticClass;
} }
} }
else {
cls.flag = CLASS_TRIVIAL_FLAG;
}
if constexpr (requires {typename T::MyMetas; }) { if constexpr (requires {typename T::MyMetas; }) {
cls.vtable.GetMeta = &T::MyMetas::GetMeta; cls.vtable.GetMeta = &T::MyMetas::GetMeta;
} }
@ -44,15 +38,11 @@ namespace refl {
public: public:
consteval static MyUClass BuildClass() { consteval static MyUClass BuildClass() {
MyUClass cls(type_name<T[N]>().View(), sizeof(T) * N, &TypeInfo<T>::StaticClass); MyUClass cls(type_name<T[N]>().View(), sizeof(T) * N, &TypeInfo<T>::StaticClass);
if constexpr (!std::is_trivially_copyable_v<T>) { if constexpr (std::is_pointer_v<T>) {
cls.vtable.InitObject = &MyUClass::InitObject<T, N>;
cls.vtable.CopyObject = &MyUClass::CopyObject<T, N>;
}
else if constexpr (std::is_pointer_v<T>) {
cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG; cls.flag = CLASS_POINTER_FLAG | CLASS_ARRAY_FLAG;
} }
else { else {
cls.flag = CLASS_TRIVIAL_FLAG | CLASS_ARRAY_FLAG; cls.flag = CLASS_ARRAY_FLAG;
} }
return cls; return cls;
} }
@ -133,32 +123,72 @@ namespace refl {
if constexpr (!std::is_same_v<P, void>) { if constexpr (!std::is_same_v<P, void>) {
parent = &TypeInfo<P>::StaticClass; parent = &TypeInfo<P>::StaticClass;
} }
if constexpr (requires(void* ptr) {T::__InitObject(ptr);}) {
vtable.InitObject = &T::__InitObject;
}
else {
vtable.InitObject = &UClass::InitObject<T>;
}
if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) { if constexpr (requires(const Name & name) { T::MyMetas::GetMeta(name); }) {
vtable.GetMeta = &T::MyMetas::GetMeta; vtable.GetMeta = &T::MyMetas::GetMeta;
} }
vtable.GetField = &UClass_Meta::GetField; vtable.GetFields = &UClass_Meta::GetFields;
} }
const FieldPtr* GetField(int index) const { const FieldPtr* GetField(int index) const {
return &Fields[index]; return &Fields[index];
} }
static const FieldPtr* GetField(const UClass* _cls,const Name& name, int index = 0){ const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name) const {
auto cls = static_cast<const UClass_Meta*>(_cls);
auto& Fields = cls->Fields;
constexpr int length = std::tuple_size<FieldsType>::value; constexpr int length = std::tuple_size<FieldsType>::value;
auto ptr = index < length ? &Fields[index] : nullptr; constexpr int MemberCount = MyMeta::MyStatic::MemberCount();
for (int i = index; i < length; i++, ptr++) { constexpr int CtorCount = MyMeta::MyStatic::CtorCount();
if (name == ptr->name) { switch (find) {
return ptr; case EFieldFind::FIND_ALL_FIELD:
return sarray<const FieldPtr>(&Fields[0], length);
case EFieldFind::FIND_ALL_MEMBER:
return sarray<const FieldPtr>(&Fields[0], MemberCount);
case EFieldFind::FIND_ALL_METHOD:
return sarray<const FieldPtr>(&Fields[MemberCount + CtorCount], length - MemberCount - CtorCount);
case EFieldFind::FIND_CTOR:
return sarray<const FieldPtr>(&Fields[MemberCount], CtorCount);
case EFieldFind::FIND_FIELD:
for (int i = 0; i < length; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&Fields[i], 1);
}
} }
return {};
case EFieldFind::FIND_MEMBER:
for (int i = 0; i < MemberCount; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_METHOD:
for (int i = MemberCount + CtorCount; i < length; i++) {
if (name == Fields[i].name) {
return sarray<const FieldPtr>(&Fields[i], 1);
}
}
return {};
case EFieldFind::FIND_METHODS:
{
int first = 0,count = 0;
for (int i = MemberCount + CtorCount; i < length; i++) {
if (name == Fields[i].name) {
if (!count) {
first = i;
}
count++;
}
else if (count) {
return sarray<const FieldPtr>(&Fields[first], count);
}
}
return {};
} }
return nullptr; default:
} return {};
}
}
static const sarray<const FieldPtr> GetFields(const UClass* _cls, EFieldFind find, const Name& name) {
auto cls = static_cast<const UClass_Meta*>(_cls);
return cls->GetFields(find, name);
}
}; };
//基础类型的偏特化 //基础类型的偏特化

View File

@ -29,6 +29,8 @@ namespace refl {
bool Invoke(const Name& name,svector<Any>& ArgsList); bool Invoke(const Name& name,svector<Any>& ArgsList);
bool Invokes(const Name& name, const sarray<Any>& ArgsList);
bool Invokes(const Name& name, svector<Any>& ArgsList);
AnyView Parent(); AnyView Parent();
}; };
} }

View File

@ -12,13 +12,7 @@ namespace refl {
auto p2 = toClass->parent; auto p2 = toClass->parent;
assert(p1 && p2); assert(p1 && p2);
//子类转父类 //子类转父类
if (p1->IsChildOf(p2)) { return p1->IsChildOf(p2);
return true;
}
if (p1->flag & CLASS_TRIVIAL_FLAG && p2->flag & CLASS_TRIVIAL_FLAG && p1->size >= p2->size) {
return true;
}
return false;
} }
inline constexpr int Any::Size()const inline constexpr int Any::Size()const
{ {
@ -94,9 +88,9 @@ namespace refl {
} }
return isChild; return isChild;
} }
auto field = cls->GetField(name, 0); auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name);
if (field) { if (fieldList.valid()) {
cache = field; cache = fieldList.front();
goto _cache_get; goto _cache_get;
} }
if (cls->parent) { if (cls->parent) {
@ -114,9 +108,9 @@ namespace refl {
} }
return isChild; return isChild;
} }
auto field = cls->GetField(name, 0); auto& fieldList = cls->GetFields(EFieldFind::FIND_MEMBER, name);
if (field) { if (fieldList.valid()) {
cache = field; cache = fieldList.front();
goto _cache_set; goto _cache_set;
} }
if (cls->parent) { if (cls->parent) {
@ -126,25 +120,61 @@ namespace refl {
} }
inline bool AnyView::Invoke(const Name& name,const sarray<Any>& ArgsList) inline bool AnyView::Invoke(const Name& name,const sarray<Any>& ArgsList)
{ {
auto field = cls->GetField(name, 0); auto& fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (!field) { if (fieldList.empty()) {
if (cls->parent) { if (cls->parent) {
return Parent().Invoke(name, ArgsList); return Parent().Invoke(name, ArgsList);
} }
return false; return false;
} }
return field->Invoke(ArgsList); return fieldList[0]->Invoke(ArgsList);
} }
inline bool AnyView::Invoke(const Name& name, svector<Any>& ArgsList) inline bool AnyView::Invoke(const Name& name, svector<Any>& ArgsList)
{ {
auto field = cls->GetField(name, 0); auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (!field) { if (fieldList.empty()) {
if (cls->parent) { if (cls->parent) {
return Parent().Invoke(name, ArgsList); return Parent().Invoke(name, ArgsList);
} }
return false; return false;
} }
return field->Invoke(ArgsList); return fieldList[0]->Invoke(ArgsList);
}
inline bool AnyView::Invokes(const Name& name, const sarray<Any>& ArgsList)
{
auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
if(fieldList.size() == 1)
return fieldList[0]->Invoke(ArgsList);
for (auto& field : fieldList) {
if (field.Invokes(ArgsList)) {
return true;
}
}
return false;
}
inline bool AnyView::Invokes(const Name& name, svector<Any>& ArgsList)
{
auto fieldList = cls->GetFields(EFieldFind::FIND_METHOD, name);
if (fieldList.empty()) {
if (cls->parent) {
return Parent().Invoke(name, ArgsList);
}
return false;
}
if (fieldList.size() == 1)
return fieldList[0]->Invoke(ArgsList);
for (auto& field : fieldList) {
if (field.Invokes(ArgsList)) {
return true;
}
}
return false;
} }
inline AnyView AnyView::Parent() { inline AnyView AnyView::Parent() {
return { ptr, cls ? cls->parent : nullptr }; return { ptr, cls ? cls->parent : nullptr };

View File

@ -6,6 +6,17 @@
#include "detail/meta.inl" #include "detail/meta.inl"
#include "macro.h" #include "macro.h"
namespace refl { namespace refl {
template<typename T, typename... Args>
consteval FieldPtr StaticCtorField(const MemberData& data = {}) {
uint32_t flag = FIELD_CTOR_FLAG;
auto cls = &TypeInfo<void(*)(void*, real_type_t<Args>...)>::StaticClass;
Offset offset = AnyArgs::GetArgsSize(data.value, cls->GetParams());
if (data.meta.IsValid()) {
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
return {FName("Ctor"),cls,method, flag};
}
template<typename T, typename Obj> template<typename T, typename Obj>
consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) { consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) {
Offset offset = data.value.IsValid() ? sizeof(T) : 0; Offset offset = data.value.IsValid() ? sizeof(T) : 0;
@ -38,6 +49,7 @@ namespace refl {
FieldPtr::Data method(offset); FieldPtr::Data method(offset);
return { name, cls,method,flag }; return { name, cls,method,flag };
} }
/*
//用处不大---------------begin //用处不大---------------begin
template<_ReflCheck_Meta T> template<_ReflCheck_Meta T>
consteval int GetStaticFieldID(const Name& name) { consteval int GetStaticFieldID(const Name& name) {
@ -74,4 +86,5 @@ namespace refl {
} }
} }
//用处不大---------------end //用处不大---------------end
*/
} }

View File

@ -8,6 +8,7 @@ namespace zstd {
const T* m_ptr; const T* m_ptr;
int m_count; int m_count;
public: public:
constexpr sarray(const T& ptr) : m_ptr(&ptr), m_count(1) {}
constexpr sarray(const T* ptr, int count) : m_ptr(ptr), m_count(count) {} constexpr sarray(const T* ptr, int count) : m_ptr(ptr), m_count(count) {}
constexpr sarray(const svector<T>& vec) : m_ptr(vec.front()), m_count(vec.size()) {} constexpr sarray(const svector<T>& vec) : m_ptr(vec.front()), m_count(vec.size()) {}
constexpr sarray() : m_ptr(nullptr), m_count(0) {} constexpr sarray() : m_ptr(nullptr), m_count(0) {}
@ -24,7 +25,13 @@ namespace zstd {
} }
return nullptr; return nullptr;
} }
constexpr bool IsValid() const noexcept { constexpr const T* operator[](int i) const noexcept {
if (i < m_count) {
return m_ptr + i;
}
return nullptr;
}
constexpr bool valid() const noexcept {
return m_count > 0; return m_count > 0;
} }
constexpr bool empty() const noexcept { constexpr bool empty() const noexcept {