summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-27 19:46:44 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-27 19:46:44 +0200
commitfd19f2e15313fba83e971f49092f5511ac610584 (patch)
treee5c75e247db4b89627ffbfced0024d936d825eac
parentf544cc4c469bd3073e6d78ca05ee70475dfa20cc (diff)
more serializer work
-rw-r--r--serialize/binary-serializer.cpp3
-rw-r--r--serialize/binary-serializer.hpp15
-rw-r--r--serialize/binary-serializer.inl44
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