From 04653742243e4bb6452108cfd0fef2f4afd8f23b Mon Sep 17 00:00:00 2001 From: rtk0c Date: Mon, 6 Sep 2021 00:15:35 -0700 Subject: Fix all compile errors, remove OperateIOProxy requirement from DataStream api --- core/src/Utils/IO/Archive.cpp | 5 +++ core/src/Utils/IO/Archive.hpp | 4 ++ core/src/Utils/IO/DataStream.hpp | 70 +++++++++---------------------- core/src/Utils/IO/Helper.hpp | 43 +++++++++++++++++++ core/src/Utils/IO/StringIntegration.hpp | 18 ++++---- core/src/Utils/IO/TslArrayIntegration.hpp | 26 ++++-------- core/src/Utils/IO/TslRobinIntegration.hpp | 54 +++++++----------------- core/src/Utils/IO/UuidIntegration.hpp | 8 ++-- core/src/Utils/IO/VectorIntegration.hpp | 21 ++++------ core/src/Utils/Vector.hpp | 50 +++++++++++++++------- 10 files changed, 150 insertions(+), 149 deletions(-) create mode 100644 core/src/Utils/IO/Helper.hpp (limited to 'core/src/Utils') diff --git a/core/src/Utils/IO/Archive.cpp b/core/src/Utils/IO/Archive.cpp index 6c4084f..aa47b67 100644 --- a/core/src/Utils/IO/Archive.cpp +++ b/core/src/Utils/IO/Archive.cpp @@ -10,6 +10,11 @@ constexpr uint8_t kByteOrderMark = []() { } }(); +std::span DataArchive::GetMagicNumbers() +{ + return std::span{ kMagicNumbers }; +} + std::optional DataArchive::LoadFile(const std::filesystem::path& path) { auto stream = InputDataStream(InputFileStream(path)); diff --git a/core/src/Utils/IO/Archive.hpp b/core/src/Utils/IO/Archive.hpp index 28e7c99..1bb8b59 100644 --- a/core/src/Utils/IO/Archive.hpp +++ b/core/src/Utils/IO/Archive.hpp @@ -2,12 +2,16 @@ #include "Utils/IO/DataStream.hpp" +#include #include #include +#include class DataArchive { public: + static std::span GetMagicNumbers(); + // TODO more complete impl static std::optional LoadFile(const std::filesystem::path& path); static std::optional SaveFile(const std::filesystem::path& path); diff --git a/core/src/Utils/IO/DataStream.hpp b/core/src/Utils/IO/DataStream.hpp index 58fae7d..3c00f4c 100644 --- a/core/src/Utils/IO/DataStream.hpp +++ b/core/src/Utils/IO/DataStream.hpp @@ -72,29 +72,7 @@ public: template void ReadObject(TObject& obj) { - if constexpr (requires(TObject t) { t.ReadFromDataStream(std::declval()); }) { - obj.ReadFromDataStream(*this); - } else if constexpr (requires(TObject t) { t.OperateIOProxy(std::declval()); }) { - obj.OperateIOProxy(*this); - } else { - static_assert(false && sizeof(TObject), "This type does not have integration with InputDataStream."); - } - } - - /// Helper to invoke either Read() or ReadObject(). Note that this function doesn't account for types that needs and adapter. - /// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. - template - void ReadGeneric(T& t) - { - if constexpr (requires(T tt, InputDataStream ss) { ss.Read(tt); }) { - Read(t); - } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadEnum(tt); }) { - ReadEnum(t); - } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadObject(tt); }) { - ReadObject(t); - } else { - static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); - } + obj.ReadFromDataStream(*this); } template @@ -104,7 +82,7 @@ public: } public: - // Proxy functions for OperateIOProxy + // Proxy functions for writing templated IO functions template void Bytes(size_t byteCount, T* buffer) @@ -118,6 +96,12 @@ public: Read(t); } + template + void Enum(T& t) + { + ReadEnum(t); + } + template void Object(T& obj) { @@ -180,41 +164,19 @@ public: } template - void WriteObject(TObject& obj) - { - if constexpr (requires(TObject t) { t.WriteToDataStream(std::declval()); }) { - obj.WriteToDataStream(*this); - } else if constexpr (requires(TObject t) { t.OperateIOProxy(std::declval()); }) { - obj.OperateIOProxy(*this); - } else { - static_assert(false && sizeof(TObject), "This type does not have integration with OutputDataStream."); - } - } - - /// Helper to invoke either Write() or WriteObject(). Note that this function doesn't account for types that needs and adapter. - /// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. - template - void WriteGeneric(T& t) - { - if constexpr (requires(T tt, OutputDataStream ss) { ss.Write(tt); }) { - Write(t); - } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteEnum(tt); }) { - WriteEnum(t); - } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteObject(tt); }) { - WriteObject(t); - } else { - static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); - } + void WriteObject(const TObject& obj) + { + obj.WriteToDataStream(*this); } template - void WriteObjectAdapted(TObject& obj) + void WriteObjectAdapted(const TObject& obj) { TAdapter::WriteToDataStream(*this, obj); } public: - // Proxy functions for OperateIOProxy + // Proxy functions for writing templated IO functions template void Bytes(size_t byteCount, T* buffer) @@ -228,6 +190,12 @@ public: Write(t); } + template + void Enum(T t) + { + WriteEnum(t); + } + template void Object(T& obj) { diff --git a/core/src/Utils/IO/Helper.hpp b/core/src/Utils/IO/Helper.hpp new file mode 100644 index 0000000..ebd47a7 --- /dev/null +++ b/core/src/Utils/IO/Helper.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "Utils/IO/DataStream.hpp" + +namespace DataStreamAdapters { + +/// Helper to invoke either Read() or ReadObject(). +/// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. +template +void ReadHelper(InputDataStream& stream, T& t) +{ + if constexpr (!std::is_same_v) { + stream.ReadObjectAdapted(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.Read(tt); }) { + stream.Read(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadEnum(tt); }) { + stream.ReadEnum(t); + } else if constexpr (requires(T tt, InputDataStream ss) { ss.ReadObject(tt); }) { + stream.ReadObject(t); + } else { + static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); + } +} + +/// Helper to invoke either Write() or WriteObject(). +/// This is intended for writing IO adapters, users that's writing IO logic shouldn't using this - it increases compile time while reducing readability. +template +void WriteHelper(OutputDataStream& stream, T& t) +{ + if constexpr (!std::is_same_v) { + stream.WriteObjectAdapted(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.Write(tt); }) { + stream.Write(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteEnum(tt); }) { + stream.WriteEnum(t); + } else if constexpr (requires(T tt, OutputDataStream ss) { ss.WriteObject(tt); }) { + stream.WriteObject(t); + } else { + static_assert(false && sizeof(T), "This type is neither a 'value' nor an 'object'."); + } +} + +} // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/StringIntegration.hpp b/core/src/Utils/IO/StringIntegration.hpp index 20dc882..536cb83 100644 --- a/core/src/Utils/IO/StringIntegration.hpp +++ b/core/src/Utils/IO/StringIntegration.hpp @@ -9,29 +9,29 @@ namespace DataStreamAdapters { struct String { - static void ReadFromDataStream(InputDataStream& s, std::string& str) + static void ReadFromDataStream(InputDataStream& stream, std::string& str) { uint64_t size; - s.Read(size); + stream.Read(size); str = {}; str.reserve(size); - s.ReadBytes(size, std::back_inserter(str)); + stream.ReadBytes(size, std::back_inserter(str)); } - static void WriteToDataStream(OutputDataStream& s, const std::string& str) + static void WriteToDataStream(OutputDataStream& stream, const std::string& str) { - s.Write((uint64_t)str.size()); - s.WriteBytes(str.size(), str.data()); + stream.Write((uint64_t)str.size()); + stream.WriteBytes(str.size(), str.data()); } }; struct StringView { - static void WriteToDataStream(OutputDataStream& s, const std::string_view& str) + static void WriteToDataStream(OutputDataStream& stream, const std::string_view& str) { - s.Write((uint64_t)str.size()); - s.WriteBytes(str.size(), str.data()); + stream.Write((uint64_t)str.size()); + stream.WriteBytes(str.size(), str.data()); } }; } // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/TslArrayIntegration.hpp b/core/src/Utils/IO/TslArrayIntegration.hpp index eebea02..af1197c 100644 --- a/core/src/Utils/IO/TslArrayIntegration.hpp +++ b/core/src/Utils/IO/TslArrayIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include "Utils/IO/StringIntegration.hpp" #include @@ -15,43 +16,34 @@ template struct TslArrayMap { template - static void ReadFromDataStream(InputDataStream& s, tsl::robin_map& map) + static void ReadFromDataStream(InputDataStream& stream, tsl::array_map& map) { static_assert(std::is_default_constructible_v); static_assert(std::is_move_constructible_v); uint64_t size; - s.Read(size); + stream.Read(size); map.reserve(size); for (uint64_t i = 0; i < size; ++i) { std::string key; - s.ReadObjectAdapted(key); + stream.ReadObjectAdapted(key); TValue value; - if constexpr (std::is_same_v) { - s.ReadGeneric(value); - } else { - s.ReadObjectAdapted(value); - } + ReadHelper(stream, value); map.insert(key, std::move(value)); } } template - static void WriteToDataStream(OutputDataStream& s, const tsl::robin_map& map) + static void WriteToDataStream(OutputDataStream& stream, const tsl::array_map& map) { - s.Write((uint64_t)map.size()); + stream.Write((uint64_t)map.size()); for (auto it = map.begin(); it != map.end(); ++it) { - s.WriteObjectAdapted(it.key_sv()); - - if constexpr (std::is_same_v) { - s.WriteGeneric(it.value()); - } else { - s.WriteObjectAdapted(it.value()); - } + stream.WriteObjectAdapted(it.key_sv()); + WriteHelper(stream, it.value()); } } }; diff --git a/core/src/Utils/IO/TslRobinIntegration.hpp b/core/src/Utils/IO/TslRobinIntegration.hpp index c800e52..50775fe 100644 --- a/core/src/Utils/IO/TslRobinIntegration.hpp +++ b/core/src/Utils/IO/TslRobinIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include #include @@ -11,51 +12,34 @@ template struct TslRobinMap { template - static void ReadFromDataStream(InputDataStream& s, tsl::robin_map& map) + static void ReadFromDataStream(InputDataStream& stream, tsl::robin_map& map) { static_assert(std::is_default_constructible_v); static_assert(std::is_move_constructible_v); uint64_t size; - s.Read(size); + stream.Read(size); map.reserve(size); for (uint64_t i = 0; i < size; ++i) { TKey key; - if constexpr (std::is_same_v) { - s.ReadGeneric(key); - } else { - s.ReadObjectAdapted(key); - } + ReadHelper(stream, key); TValue value; - if constexpr (std::is_same_v) { - s.ReadGeneric(value); - } else { - s.ReadObjectAdapted(value); - } + ReadHelper(stream, value); map.insert(std::move(key), std::move(value)); } } template - static void WriteToDataStream(OutputDataStream& s, const tsl::robin_map& map) + static void WriteToDataStream(OutputDataStream& stream, const tsl::robin_map& map) { - s.Write((uint64_t)map.size()); + stream.Write((uint64_t)map.size()); for (auto it = map.begin(); it != map.end(); ++it) { - if constexpr (std::is_same_v) { - s.WriteGeneric(it.key()); - } else { - s.WriteObjectAdapted(it.key()); - } - - if constexpr (std::is_same_v) { - s.WriteGeneric(it.value()); - } else { - s.WriteObjectAdapted(it.value()); - } + WriteHelper(stream, it.key()); + WriteHelper(stream, it.value()); } } }; @@ -64,38 +48,30 @@ template struct TslRobinSet { template - static void ReadFromDataStream(InputDataStream& s, tsl::robin_set& set) + static void ReadFromDataStream(InputDataStream& stream, tsl::robin_set& set) { static_assert(std::is_default_constructible_v); static_assert(std::is_move_constructible_v); uint64_t size; - s.Read(size); + stream.Read(size); set.reserve(size); for (uint64_t i = 0; i < size; ++i) { TElement element; - if constexpr (std::is_same_v) { - s.ReadGeneric(element); - } else { - s.ReadObjectAdapted(element); - } + ReadHelper(stream, element); set.insert(std::move(element)); } } template - static void WriteToDataStream(OutputDataStream& s, const tsl::array_set& set) + static void WriteToDataStream(OutputDataStream& stream, const tsl::robin_set& set) { - s.Write((uint64_t)set.size()); + stream.Write((uint64_t)set.size()); for (auto& element : set) { - if constexpr (std::is_same_v) { - s.WriteGeneric(element); - } else { - s.WriteObjectAdapted(element); - } + WriteHelper(stream, element); } } }; diff --git a/core/src/Utils/IO/UuidIntegration.hpp b/core/src/Utils/IO/UuidIntegration.hpp index d8a0304..d028c50 100644 --- a/core/src/Utils/IO/UuidIntegration.hpp +++ b/core/src/Utils/IO/UuidIntegration.hpp @@ -10,18 +10,18 @@ namespace DataStreamAdapters { struct Uuid { - static void ReadFromDataStream(InputDataStream& s, uuids::uuid& uuid) + static void ReadFromDataStream(InputDataStream& stream, uuids::uuid& uuid) { uint8_t buffer[16]; - s.ReadBytes(16, buffer); + stream.ReadBytes(16, buffer); uuid = uuids::uuid(gsl::span{ buffer }); } - static void WriteToDataStream(OutputDataStream& s, const uuids::uuid& uuid) + static void WriteToDataStream(OutputDataStream& stream, const uuids::uuid& uuid) { auto gslSpan = uuid.as_bytes(); - s.WriteBytes(gslSpan.size(), gslSpan.data()); + stream.WriteBytes(gslSpan.size(), gslSpan.data()); } }; } // namespace DataStreamAdapters diff --git a/core/src/Utils/IO/VectorIntegration.hpp b/core/src/Utils/IO/VectorIntegration.hpp index da663a4..3689505 100644 --- a/core/src/Utils/IO/VectorIntegration.hpp +++ b/core/src/Utils/IO/VectorIntegration.hpp @@ -1,6 +1,7 @@ #pragma once #include "Utils/IO/DataStream.hpp" +#include "Utils/IO/Helper.hpp" #include #include @@ -10,39 +11,31 @@ template struct Vector { template - static void ReadFromDataStream(InputDataStream& s, std::vector& vec) + static void ReadFromDataStream(InputDataStream& stream, std::vector& vec) { static_assert(std::is_default_constructible_v); static_assert(std::is_move_constructible_v); uint64_t size; - s.Read(size); + stream.Read(size); vec.clear(); vec.reserve(size); for (uint64_t i = 0; i < size; ++i) { TElement element; - if constexpr (std::is_same_v) { - s.ReadGeneric(element); - } else { - s.ReadObjectAdapted(element); - } + ReadHelper(stream, element); vec.push_back(std::move(element)); } } template - static void WriteToDataStream(OutputDataStream& s, const std::vector& vec) + static void WriteToDataStream(OutputDataStream& stream, const std::vector& vec) { - s.Write((uint64_t)vec.size()); + stream.Write((uint64_t)vec.size()); for (auto& element : vec) { - if constexpr (std::is_same_v) { - s.WriteGeneric(element); - } else { - s.WriteObjectAdapted(element); - } + WriteHelper(stream, element); } } }; diff --git a/core/src/Utils/Vector.hpp b/core/src/Utils/Vector.hpp index 3d4d251..4d3f3b3 100644 --- a/core/src/Utils/Vector.hpp +++ b/core/src/Utils/Vector.hpp @@ -1,5 +1,7 @@ #pragma once +#include "Utils/IO/DataStream.hpp" + template struct Vec2 { @@ -15,11 +17,16 @@ struct Vec2 }; } - template - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) { - proxy.Value(x); - proxy.Value(y); + stream.Value(x); + stream.Value(y); + } + + void WriteToDataStream(OutputDataStream& stream) const + { + stream.Value(x); + stream.Value(y); } friend constexpr bool operator==(const Vec2& a, const Vec2& b) = default; @@ -55,12 +62,18 @@ struct Vec3 }; } - template - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) + { + stream.Value(x); + stream.Value(y); + stream.Value(z); + } + + void WriteToDataStream(OutputDataStream& stream) const { - proxy.Value(x); - proxy.Value(y); - proxy.Value(z); + stream.Value(x); + stream.Value(y); + stream.Value(z); } friend constexpr bool operator==(const Vec3& a, const Vec3& b) = default; @@ -98,13 +111,20 @@ struct Vec4 }; } - template - void OperateIOProxy(TProxy& proxy) + void ReadFromDataStream(InputDataStream& stream) + { + stream.Value(x); + stream.Value(y); + stream.Value(z); + stream.Value(w); + } + + void WriteToDataStream(OutputDataStream& stream) const { - proxy.Value(x); - proxy.Value(y); - proxy.Value(z); - proxy.Value(w); + stream.Value(x); + stream.Value(y); + stream.Value(z); + stream.Value(w); } friend constexpr bool operator==(const Vec4& a, const Vec4& b) = default; -- cgit v1.2.3-70-g09d2