[+] ByteBuf: support for T::Serialize and T::Deserialize detection

This commit is contained in:
Reece Wilson 2023-10-24 11:46:09 +01:00
parent 6acf21009d
commit cef8259bb1
2 changed files with 128 additions and 3 deletions

View File

@ -529,6 +529,9 @@ namespace Aurora::Memory
template<typename T> template<typename T>
bool Write(const T &in); bool Write(const T &in);
template<typename T>
bool Write(T &in);
template<typename T> template<typename T>
bool Read(T &out); bool Read(T &out);

View File

@ -17,6 +17,54 @@ namespace Aurora::Memory
namespace __detail namespace __detail
{ {
template <class T>
struct AuHasSerializeBool
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(ByteBuffer &)>(&C::Serialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasSerializeBool2
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(ByteBuffer &) const>(&C::Serialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasDeserializeBool
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<bool (C:: *)(ByteBuffer &)>(&C::Deserialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasSerialize
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(ByteBuffer &)>(&C::Serialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasSerialize2
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(ByteBuffer &) const>(&C::Serialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasDeserialize
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void (C:: *)(ByteBuffer &)>(&C::Deserialize)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class> template <class>
static constexpr AuUInt8 TypeID_v = (AuUInt8)Data::EDataType::kTypeEND; static constexpr AuUInt8 TypeID_v = (AuUInt8)Data::EDataType::kTypeEND;
@ -53,7 +101,16 @@ namespace Aurora::Memory
template <typename T> template <typename T>
static constexpr AuUInt8 TypeToID() static constexpr AuUInt8 TypeToID()
{ {
if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>) if constexpr (__detail::AuHasDeserializeBool<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasDeserialize<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerializeBool<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerialize<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerializeBool2<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerialize2<AuRemoveReference_t<T>>::type::value)
{
return (AuUInt8)Data::EDataType::kTypeSpecialReserved1; //obj+1
}
else if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>)
{ {
return (AuUInt8)Data::EDataType::kTypeSpecialReserved4; return (AuUInt8)Data::EDataType::kTypeSpecialReserved4;
} }
@ -88,7 +145,24 @@ namespace Aurora::Memory
{ {
if constexpr (AuIsClass_v<T>) if constexpr (AuIsClass_v<T>)
{ {
if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>) if constexpr (__detail::AuHasDeserializeBool<AuRemoveReference_t<T>>::type::value)
{
if (!out.Deserialize(*this))
{
this->flagReadError = true;
return false;
}
else
{
return !this->flagReadError;
}
}
else if constexpr (__detail::AuHasDeserialize<AuRemoveReference_t<T>>::type::value)
{
out.Deserialize(*this);
return !this->flagReadError;
}
else if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>)
{ {
if (this->ReadTagged<AuUInt16> != if (this->ReadTagged<AuUInt16> !=
AuTupleCountOf_v<AuRemoveReference_t<T>>) AuTupleCountOf_v<AuRemoveReference_t<T>>)
@ -247,12 +321,60 @@ namespace Aurora::Memory
return a; return a;
} }
template<typename T>
bool ByteBuffer::Write(T &in)
{
if constexpr (AuIsClass_v<T>)
{
if constexpr (__detail::AuHasSerializeBool<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerializeBool2<AuRemoveReference_t<T>>::type::value)
{
if (!in.Serialize(*this))
{
this->flagWriteError = true;
return false;
}
else
{
return !this->flagWriteError;
}
}
else if constexpr (__detail::AuHasSerialize<AuRemoveReference_t<T>>::type::value ||
__detail::AuHasSerialize2<AuRemoveReference_t<T>>::type::value)
{
in.Serialize(*this);
return !this->flagReadError;
}
}
else
{
return this->Write(AuConstReference<T>(in));
}
}
template<typename T> template<typename T>
bool ByteBuffer::Write(const T &in) bool ByteBuffer::Write(const T &in)
{ {
if constexpr (AuIsClass_v<T>) if constexpr (AuIsClass_v<T>)
{ {
if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>) if constexpr (__detail::AuHasSerializeBool2<AuRemoveReference_t<T>>::type::value)
{
if (!in.Serialize(*this))
{
this->flagWriteError = true;
return false;
}
else
{
return !this->flagWriteError;
}
}
else if constexpr (__detail::AuHasSerialize2<AuRemoveReference_t<T>>::type::value)
{
in.Serialize(*this);
return !this->flagReadError;
}
else if constexpr (AuIsTuple_v<AuRemoveReference_t<T>>)
{ {
this->WriteTagged<AuUInt16>(AuTupleCountOf_v<AuRemoveReference_t<T>>); this->WriteTagged<AuUInt16>(AuTupleCountOf_v<AuRemoveReference_t<T>>);