diff --git a/framework/global/serialization/textstream.cpp b/framework/global/serialization/textstream.cpp index 8573084dd4..75fb75fd7e 100644 --- a/framework/global/serialization/textstream.cpp +++ b/framework/global/serialization/textstream.cpp @@ -64,10 +64,10 @@ TextStream& TextStream::operator<<(char ch) return *this; } -TextStream& TextStream::operator<<(const int32_t val) +template +TextStream& TextStream::writeInt(T val) { - // ceil(log_10(2^31)) = 10 (+ sign) - std::array buf{}; + std::array buf{}; const auto [last, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), val); IF_ASSERT_FAILED(ec == std::errc {}) { return *this; @@ -78,18 +78,10 @@ TextStream& TextStream::operator<<(const int32_t val) return *this; } -TextStream& TextStream::operator<<(const uint32_t val) -{ - // ceil(log_10(2^32)) = 10 - std::array buf{}; - const auto [last, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), val); - IF_ASSERT_FAILED(ec == std::errc {}) { - return *this; - } - - write(buf.data(), static_cast(last - buf.data())); - return *this; -} +template TextStream& TextStream::writeInt<11, int32_t>(int32_t val); +template TextStream& TextStream::writeInt<10, uint32_t>(uint32_t val); +template TextStream& TextStream::writeInt<21, int64_t>(int64_t val); +template TextStream& TextStream::writeInt<20, uint64_t>(uint64_t val); TextStream& TextStream::operator<<(double val) { @@ -120,34 +112,6 @@ TextStream& TextStream::operator<<(double val) return *this; } -TextStream& TextStream::operator<<(const int64_t val) -{ - // ceil(log_10(2^63)) = 20 (+ sign) - std::array buf{}; - const auto [last, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), val); - IF_ASSERT_FAILED(ec == std::errc {}) { - return *this; - } - - write(buf.data(), static_cast(last - buf.data())); - - return *this; -} - -TextStream& TextStream::operator<<(const uint64_t val) -{ - // ceil(log_10(2^64)) = 20 - std::array buf{}; - const auto [last, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), val); - IF_ASSERT_FAILED(ec == std::errc {}) { - return *this; - } - - write(buf.data(), static_cast(last - buf.data())); - - return *this; -} - TextStream& TextStream::operator<<(const char* s) { return operator<<(std::string_view { s }); diff --git a/framework/global/serialization/textstream.h b/framework/global/serialization/textstream.h index f88f2b88f0..61b57b8b8d 100644 --- a/framework/global/serialization/textstream.h +++ b/framework/global/serialization/textstream.h @@ -21,8 +21,10 @@ */ #pragma once +#include #include #include +#include #include #ifndef NO_QT_SUPPORT @@ -37,6 +39,18 @@ namespace io { class IODevice; } +template +struct IsNonCharInteger : std::bool_constant< + std::is_integral_v + && !std::is_same_v, char> + && !std::is_same_v, signed char> + && !std::is_same_v, unsigned char> + && !std::is_same_v, wchar_t> + && !std::is_same_v, char8_t> + && !std::is_same_v, char16_t> + && !std::is_same_v, char32_t> + > {}; + class TextStream { public: @@ -49,11 +63,29 @@ class TextStream void flush(); TextStream& operator<<(char ch); - TextStream& operator<<(int32_t); - TextStream& operator<<(uint32_t); + TextStream& operator<<(signed char ch) { return *this << static_cast(ch); } + TextStream& operator<<(unsigned char ch) { return *this << static_cast(ch); } + + template::value, int> = 0> + TextStream& operator<<(T val) + { + if constexpr (sizeof(T) <= 4) { + if constexpr (std::is_signed_v) { + return writeInt<11>(static_cast(val)); // ceil(log_10(2^31)) = 10 (+ sign) + } else { + return writeInt<10>(static_cast(val)); // ceil(log_10(2^32)) = 10 + } + } else { + if constexpr (std::is_signed_v) { + return writeInt<21>(static_cast(val)); // ceil(log_10(2^63)) = 20 (+ sign) + } else { + return writeInt<20>(static_cast(val)); // ceil(log_10(2^64)) = 20 + } + } + } + TextStream& operator<<(double); - TextStream& operator<<(int64_t); - TextStream& operator<<(uint64_t); + TextStream& operator<<(const char* s); TextStream& operator<<(std::string_view); TextStream& operator<<(const ByteArray& b); @@ -65,6 +97,10 @@ class TextStream private: void write(const char* ch, size_t len); + + template + TextStream& writeInt(T val); + io::IODevice* m_device = nullptr; std::vector m_buf; };