Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 7 additions & 43 deletions framework/global/serialization/textstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ TextStream& TextStream::operator<<(char ch)
return *this;
}

TextStream& TextStream::operator<<(const int32_t val)
template<size_t MaxDigits, typename T>
TextStream& TextStream::writeInt(T val)
{
// ceil(log_10(2^31)) = 10 (+ sign)
std::array<char, 11> buf{};
std::array<char, MaxDigits> buf{};
const auto [last, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), val);
IF_ASSERT_FAILED(ec == std::errc {}) {
return *this;
Expand All @@ -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<char, 10> 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<size_t>(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)
{
Expand Down Expand Up @@ -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<char, 21> 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<size_t>(last - buf.data()));

return *this;
}

TextStream& TextStream::operator<<(const uint64_t val)
{
// ceil(log_10(2^64)) = 20
std::array<char, 20> 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<size_t>(last - buf.data()));

return *this;
}

TextStream& TextStream::operator<<(const char* s)
{
return operator<<(std::string_view { s });
Expand Down
44 changes: 40 additions & 4 deletions framework/global/serialization/textstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
*/
#pragma once

#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
#include <vector>

#ifndef NO_QT_SUPPORT
Expand All @@ -37,6 +39,18 @@ namespace io {
class IODevice;
}

template<typename T>
struct IsNonCharInteger : std::bool_constant<
std::is_integral_v<T>
&& !std::is_same_v<std::remove_cv_t<T>, char>
&& !std::is_same_v<std::remove_cv_t<T>, signed char>
&& !std::is_same_v<std::remove_cv_t<T>, unsigned char>
&& !std::is_same_v<std::remove_cv_t<T>, wchar_t>
&& !std::is_same_v<std::remove_cv_t<T>, char8_t>
&& !std::is_same_v<std::remove_cv_t<T>, char16_t>
&& !std::is_same_v<std::remove_cv_t<T>, char32_t>
> {};

class TextStream
{
public:
Expand All @@ -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<char>(ch); }
TextStream& operator<<(unsigned char ch) { return *this << static_cast<char>(ch); }

template<typename T, std::enable_if_t<IsNonCharInteger<T>::value, int> = 0>
TextStream& operator<<(T val)
{
if constexpr (sizeof(T) <= 4) {
if constexpr (std::is_signed_v<T>) {
return writeInt<11>(static_cast<int32_t>(val)); // ceil(log_10(2^31)) = 10 (+ sign)
} else {
return writeInt<10>(static_cast<uint32_t>(val)); // ceil(log_10(2^32)) = 10
}
} else {
if constexpr (std::is_signed_v<T>) {
return writeInt<21>(static_cast<int64_t>(val)); // ceil(log_10(2^63)) = 20 (+ sign)
} else {
return writeInt<20>(static_cast<uint64_t>(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);
Expand All @@ -65,6 +97,10 @@ class TextStream

private:
void write(const char* ch, size_t len);

template<size_t MaxDigits, typename T>
TextStream& writeInt(T val);

io::IODevice* m_device = nullptr;
std::vector<uint8_t> m_buf;
};
Expand Down
Loading