mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-20 22:33:02 +01:00
Use char_traits for length
This commit is contained in:
@@ -24,13 +24,14 @@
|
|||||||
|
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
template<typename T, size_t (*LenFn)(const T*), size_t StackSize = 256> class FormatBufferBase
|
template<typename T, size_t StackSize = 256, typename TTraits = std::char_traits<T>> class FormatBufferBase
|
||||||
{
|
{
|
||||||
T _storage[StackSize];
|
T _storage[StackSize];
|
||||||
T* _buffer;
|
T* _buffer;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
// NOTE: Capacity is on purpose uint32_t to have a fixed position for the flag on each architecture.
|
// NOTE: Capacity is on purpose uint32_t to have a fixed position for the flag on each architecture.
|
||||||
uint32_t _capacity;
|
uint32_t _capacity;
|
||||||
|
TTraits _traits;
|
||||||
|
|
||||||
static constexpr uint32_t FlagLocalStorage = (1u << 31);
|
static constexpr uint32_t FlagLocalStorage = (1u << 31);
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ namespace OpenRCT2
|
|||||||
: _storage{}
|
: _storage{}
|
||||||
, _buffer(_storage)
|
, _buffer(_storage)
|
||||||
, _size{}
|
, _size{}
|
||||||
, _capacity(FlagLocalStorage | static_cast<uint32_t>(std::size(_storage)))
|
, _capacity(FlagLocalStorage | static_cast<uint32_t>(StackSize))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,12 +77,9 @@ namespace OpenRCT2
|
|||||||
return _buffer;
|
return _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& operator<<(const T* v)
|
template<size_t N> auto& operator<<(T const (&v)[N])
|
||||||
{
|
{
|
||||||
if (!v)
|
append(v, N);
|
||||||
return *this;
|
|
||||||
|
|
||||||
append(v, LenFn(v));
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,13 +89,27 @@ namespace OpenRCT2
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& operator<<(const T* v)
|
||||||
|
{
|
||||||
|
if (!v)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
append(v, _traits.length(v));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
auto& operator<<(const std::basic_string_view<T> v)
|
auto& operator<<(const std::basic_string_view<T> v)
|
||||||
{
|
{
|
||||||
append(v.data(), v.size());
|
append(v.data(), v.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
auto& operator<<(const std::basic_string<T>& v)
|
||||||
|
{
|
||||||
|
append(v.data(), v.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void append(const T* buf, size_t len)
|
void append(const T* buf, size_t len)
|
||||||
{
|
{
|
||||||
ensure_capacity(len);
|
ensure_capacity(len);
|
||||||
@@ -108,6 +120,7 @@ namespace OpenRCT2
|
|||||||
_buffer[_size] = T{};
|
_buffer[_size] = T{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void ensure_capacity(size_t additionalSize)
|
void ensure_capacity(size_t additionalSize)
|
||||||
{
|
{
|
||||||
const size_t curSize = size();
|
const size_t curSize = size();
|
||||||
@@ -130,7 +143,7 @@ namespace OpenRCT2
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using FormatBuffer = FormatBufferBase<char, strlen>;
|
using FormatBuffer = FormatBufferBase<char>;
|
||||||
|
|
||||||
using FormatArg_t = std::variant<uint16_t, int32_t, const char*, std::string>;
|
using FormatArg_t = std::variant<uint16_t, int32_t, const char*, std::string>;
|
||||||
|
|
||||||
|
|||||||
@@ -607,7 +607,7 @@ TEST_F(FormattingTests, format_number_comma2dp32_large_value_negative)
|
|||||||
|
|
||||||
TEST_F(FormattingTests, buffer_storage_swap)
|
TEST_F(FormattingTests, buffer_storage_swap)
|
||||||
{
|
{
|
||||||
FormatBufferBase<char, strlen, 16> ss;
|
FormatBufferBase<char, 16> ss;
|
||||||
ss << "Hello World";
|
ss << "Hello World";
|
||||||
ASSERT_STREQ(ss.data(), "Hello World");
|
ASSERT_STREQ(ss.data(), "Hello World");
|
||||||
ss << ", Exceeding local storage";
|
ss << ", Exceeding local storage";
|
||||||
|
|||||||
Reference in New Issue
Block a user