diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-27 19:46:44 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-27 19:46:44 +0200 |
commit | fd19f2e15313fba83e971f49092f5511ac610584 (patch) | |
tree | e5c75e247db4b89627ffbfced0024d936d825eac | |
parent | f544cc4c469bd3073e6d78ca05ee70475dfa20cc (diff) |
more serializer work
-rw-r--r-- | serialize/binary-serializer.cpp | 3 | ||||
-rw-r--r-- | serialize/binary-serializer.hpp | 15 | ||||
-rw-r--r-- | serialize/binary-serializer.inl | 44 |
3 files changed, 40 insertions, 22 deletions
diff --git a/serialize/binary-serializer.cpp b/serialize/binary-serializer.cpp index 1a6da0fd..2444b403 100644 --- a/serialize/binary-serializer.cpp +++ b/serialize/binary-serializer.cpp @@ -77,4 +77,7 @@ static_assert(test2()); using test3 = binary_reader<std::array<char, 1>::iterator>; static_assert(std::is_same_v<test3&, decltype( std::declval<test3&>() >> std::declval<int&>() )>); +using test4 = binary_writer<std::array<char, sizeof(int)>::iterator>; +static_assert(std::is_same_v<test4&, decltype( std::declval<test4&>() << int() )>); + } // namespace floormat::Serialize diff --git a/serialize/binary-serializer.hpp b/serialize/binary-serializer.hpp index 589e437e..bab729f4 100644 --- a/serialize/binary-serializer.hpp +++ b/serialize/binary-serializer.hpp @@ -77,13 +77,13 @@ struct binary_reader final { template<std::floating_point T> constexpr value_u read_u() noexcept; template<typename T> T read() noexcept; - template<serializable T> - friend binary_reader<It>& operator>>(binary_reader<It>& reader, T& x) noexcept; - private: It it, end; }; +template<string_input_iterator It, serializable T> +binary_reader<It>& operator>>(binary_reader<It>& reader, T& x) noexcept; + template<string_input_iterator It> binary_reader(It&& begin, It&& end) -> binary_reader<std::decay_t<It>>; template<typename Array> @@ -92,13 +92,14 @@ binary_reader(Array&& array) -> binary_reader<std::decay_t<decltype(std::begin(a 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; + template<integer T> void write(T x) noexcept; + template<std::floating_point T> void write(T x) noexcept; private: It it; }; +template<std::output_iterator<char> It, serializable T> +binary_writer<It>& operator<<(binary_writer<It>& writer, T x) noexcept; + } // namespace floormat::Serialize diff --git a/serialize/binary-serializer.inl b/serialize/binary-serializer.inl index 200622f4..35b7ddc7 100644 --- a/serialize/binary-serializer.inl +++ b/serialize/binary-serializer.inl @@ -60,8 +60,8 @@ constexpr value_u binary_reader<It>::read_u() noexcept return buf; } -template<typename T> -[[maybe_unused]] constexpr inline T maybe_byteswap(T x) +template<integer T> +constexpr inline T maybe_byteswap(T x) { if constexpr(std::endian::native == std::endian::big) return std::byteswap(x); @@ -69,34 +69,48 @@ template<typename T> 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> +template<integer T> void binary_writer<It>::write(T x) noexcept { union { T datum; char bytes[sizeof(T)]; } buf; - buf.datum = x; + buf.datum = maybe_byteswap(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 +template<std::output_iterator<char> It> +template<std::floating_point T> +void binary_writer<It>::write(T x) noexcept { + union { + T datum; + char bytes[sizeof(T)]; + } buf; + buf.datum = maybe_byteswap(x); + for (std::size_t i = 0; i < sizeof(T); i++) + *it++ = buf.bytes[i]; +} +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, serializable T> +binary_writer<It>& operator<<(binary_writer<It>& writer, T x) noexcept +{ + writer.template write<T>(x); + return writer; } } // namespace floormat::Serialize |