diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-27 19:36:32 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-27 19:36:32 +0200 |
commit | f544cc4c469bd3073e6d78ca05ee70475dfa20cc (patch) | |
tree | 6d1e34ac8e5d586108fd019d4da8f8b043b40cb5 | |
parent | 4dce8e6aeb770fee1a7190526b04d03f3da69cb0 (diff) |
more serializer work
-rw-r--r-- | serialize/binary-serializer.cpp | 10 | ||||
-rw-r--r-- | serialize/binary-serializer.hpp | 36 | ||||
-rw-r--r-- | serialize/binary-serializer.inl | 58 |
3 files changed, 85 insertions, 19 deletions
diff --git a/serialize/binary-serializer.cpp b/serialize/binary-serializer.cpp index 08606768..1a6da0fd 100644 --- a/serialize/binary-serializer.cpp +++ b/serialize/binary-serializer.cpp @@ -74,13 +74,7 @@ static constexpr bool test2() } static_assert(test2()); -template<typename T> -[[maybe_unused]] static constexpr T maybe_byteswap(T x) -{ - if constexpr(std::endian::native == std::endian::big) - return std::byteswap(x); - else - return x; -} +using test3 = binary_reader<std::array<char, 1>::iterator>; +static_assert(std::is_same_v<test3&, decltype( std::declval<test3&>() >> std::declval<int&>() )>); } // namespace floormat::Serialize diff --git a/serialize/binary-serializer.hpp b/serialize/binary-serializer.hpp index 19aa5548..589e437e 100644 --- a/serialize/binary-serializer.hpp +++ b/serialize/binary-serializer.hpp @@ -56,27 +56,49 @@ concept char_sequence = requires(T& x, const T& cx) { requires std::same_as<char, std::decay_t<decltype(*std::cbegin(x))>>; }; -template<std::forward_iterator It> +template<typename It> +concept string_input_iterator = requires(It it) { + requires std::forward_iterator<It>; + requires std::is_same_v<char, std::decay_t<decltype(*it)>>; +}; + +template<typename T> +concept serializable = requires(T x) { + requires std::floating_point<T> || integer<T>; +}; + +template<string_input_iterator It> struct binary_reader final { - fm_DECLARE_DEFAULT_MOVE_COPY_ASSIGNMENTS(binary_reader<It>); - constexpr binary_reader(It begin, It end) noexcept : it{begin}, end{end} {} - template<char_sequence Seq> - explicit constexpr binary_reader(const Seq& seq) noexcept : it{std::begin(seq)}, end{std::end(seq)} {} + template<char_sequence Seq> explicit constexpr binary_reader(const Seq& seq) noexcept; + constexpr binary_reader(It begin, It end) noexcept; constexpr ~binary_reader() noexcept; template<integer T> constexpr value_u read_u() noexcept; template<std::floating_point T> constexpr value_u read_u() noexcept; template<typename T> T read() noexcept; - static_assert(std::is_same_v<char, std::decay_t<decltype(*std::declval<It>())>>); + template<serializable T> + friend binary_reader<It>& operator>>(binary_reader<It>& reader, T& x) noexcept; private: It it, end; }; -template<std::forward_iterator It> binary_reader(It&& begin, It&& end) -> binary_reader<std::decay_t<It>>; +template<string_input_iterator It> binary_reader(It&& begin, It&& end) -> binary_reader<std::decay_t<It>>; template<typename Array> binary_reader(Array&& array) -> binary_reader<std::decay_t<decltype(std::begin(array))>>; +template<std::output_iterator<char> It> +struct binary_writer final { + explicit constexpr binary_writer(It it) noexcept; + template<serializable T> void write(T x) noexcept; + + template<serializable T> + friend binary_writer<It>& operator>>(binary_writer<It>& writer, T x) noexcept; + +private: + It it; +}; + } // namespace floormat::Serialize diff --git a/serialize/binary-serializer.inl b/serialize/binary-serializer.inl index 9e7e58fa..200622f4 100644 --- a/serialize/binary-serializer.inl +++ b/serialize/binary-serializer.inl @@ -4,7 +4,18 @@ namespace floormat::Serialize { -template<std::forward_iterator It> +template<string_input_iterator It> +template<char_sequence Seq> +constexpr binary_reader<It>::binary_reader(const Seq& seq) noexcept + : it{std::begin(seq)}, end{std::end(seq)} +{} + +template<string_input_iterator It> +constexpr binary_reader<It>::binary_reader(It begin, It end) noexcept : + it{begin}, end{end} +{} + +template<string_input_iterator It> template<std::floating_point T> constexpr value_u binary_reader<It>::read_u() noexcept { @@ -16,7 +27,7 @@ constexpr value_u binary_reader<It>::read_u() noexcept return buf; } -template<std::forward_iterator It> +template<string_input_iterator It> template<typename T> T binary_reader<It>::read() noexcept { @@ -24,13 +35,13 @@ T binary_reader<It>::read() noexcept return *reinterpret_cast<T>(buf.bytes); } -template<std::forward_iterator It> +template<string_input_iterator It> constexpr binary_reader<It>::~binary_reader() noexcept { fm_assert(it == end); } -template<std::forward_iterator It> +template<string_input_iterator It> template<integer T> constexpr value_u binary_reader<It>::read_u() noexcept { @@ -49,6 +60,45 @@ constexpr value_u binary_reader<It>::read_u() noexcept return buf; } +template<typename T> +[[maybe_unused]] constexpr inline T maybe_byteswap(T x) +{ + if constexpr(std::endian::native == std::endian::big) + return std::byteswap(x); + else + return x; +} + +template<string_input_iterator It, serializable T> +binary_reader<It>& operator>>(binary_reader<It>& reader, T x) noexcept +{ + value_u u = reader.template read<T>(); + x = *reinterpret_cast<T*>(&u.bytes[0]); + return reader; +} + +template<std::output_iterator<char> It> +constexpr binary_writer<It>::binary_writer(It it) noexcept : it{it} {} + +template<std::output_iterator<char> It> +template<serializable T> +void binary_writer<It>::write(T x) noexcept +{ + union { + T datum; + char bytes[sizeof(T)]; + } buf; + buf.datum = x; + for (std::size_t i = 0; i < sizeof(T); i++) + *it++ = buf.bytes[i]; +}; + +template<std::output_iterator<char> It, serializable T> +binary_writer<It>& operator>>(binary_writer<It>& writer, T x) noexcept +{ + +} + } // namespace floormat::Serialize |