summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-27 19:36:32 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-27 19:36:32 +0200
commitf544cc4c469bd3073e6d78ca05ee70475dfa20cc (patch)
tree6d1e34ac8e5d586108fd019d4da8f8b043b40cb5
parent4dce8e6aeb770fee1a7190526b04d03f3da69cb0 (diff)
more serializer work
-rw-r--r--serialize/binary-serializer.cpp10
-rw-r--r--serialize/binary-serializer.hpp36
-rw-r--r--serialize/binary-serializer.inl58
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