@@ -19,9 +19,9 @@ namespace Rfx
1919// / that avoids the usual value initialization (see std::make_unique_for_overwrite())
2020class Blob
2121{
22- std::unique_ptr<std::byte[]> m_storage;
2322 size_t m_size = 0 ;
2423 size_t m_capacity = 0 ;
24+ std::unique_ptr<std::byte[]> m_storage;
2525
2626public:
2727 using iterator = std::byte*;
@@ -48,11 +48,10 @@ class Blob
4848 template <std::input_iterator It> Blob (It begin, It end) requires std::is_same_v<std::iter_value_t<It>, std::byte>;
4949 template <std::convertible_to<std::string_view> TString> Blob (TString&& str);
5050 Blob (const Blob& other);
51- Blob (Blob&& other) noexcept ;
52- ~Blob () = default ;
51+ Blob (Blob&& other) noexcept = default ;
5352
5453 Blob& operator =(const Blob&);
55- Blob& operator =(Blob&&) noexcept ;
54+ Blob& operator =(Blob&&) noexcept = default ;
5655
5756 auto operator <=>(const Blob& rhs) const noexcept ;
5857 bool operator ==(const Blob& rhs) const noexcept ;
@@ -71,17 +70,18 @@ class Blob
7170// /////////////////////////////////////////////////////////////////////////////
7271
7372inline Blob::Blob (size_t size)
74- : Blob()
73+ : m_size(size)
74+ , m_capacity(std::max(std::bit_ceil(size), size_t(1024 )))
75+ , m_storage(std::make_unique_for_overwrite<std::byte[]>(m_capacity))
7576{
76- grow (size);
7777}
7878
7979template <std::input_iterator It>
8080inline Blob::Blob (It begin, It end)
8181 requires std::is_same_v<std::iter_value_t<It>, std::byte>
8282{
8383 for (; begin != end; ++begin)
84- * grow ( 1 ) = *begin;
84+ push_back ( *begin) ;
8585}
8686
8787template <std::convertible_to<std::string_view> TString>
@@ -98,37 +98,20 @@ inline Blob::Blob(const Blob& other)
9898 std::copy (other.begin (), other.end (), begin ());
9999}
100100
101- inline Blob::Blob (Blob&& other) noexcept
102- : m_storage(std::move(other.m_storage))
103- , m_size(other.m_size)
104- , m_capacity(other.m_capacity)
101+ inline Blob& Blob::operator =(const Blob& other)
105102{
106- other.m_size = 0 ;
107- other.m_capacity = 0 ;
108- }
109-
110- inline Blob& Blob::operator = (const Blob& other)
111- {
112- if (&other != this )
103+ if (!m_storage || other.m_size > m_capacity)
113104 {
114- if (other.size () > m_size)
115- grow (other.size () - m_size);
116-
117- std::copy (other.begin (), other.end (), begin ());
105+ Blob cpy { other };
106+ return operator =(std::move (cpy));
118107 }
119- return *this ;
120- }
121108
122- inline Blob& Blob::operator =(Blob&& other) noexcept
123- {
124109 if (&other != this )
125110 {
126- m_storage = std::move (other.m_storage );
111+ std::copy (other.begin (), other. end (), begin () );
127112 m_size = other.m_size ;
128- m_capacity = other.m_capacity ;
129- other.m_size = 0 ;
130- other.m_capacity = 0 ;
131113 }
114+
132115 return *this ;
133116}
134117
@@ -148,28 +131,25 @@ inline bool Blob::operator==(const Blob& rhs) const noexcept
148131
149132inline Blob::iterator Blob::grow (size_t size)
150133{
151- auto newSize = size + m_size;
152- auto start = m_size;
153- reserve (newSize);
154- m_size = newSize;
155- return m_storage.get () + start;
134+ auto s = m_size;
135+ resize (m_size + size);
136+ return begin () + s;
156137}
157138
158139inline void Blob::resize (size_t size)
159140{
160- if (m_size < size)
161- reserve (size);
141+ reserve (size);
162142 m_size = size;
163143}
164144
165145inline void Blob::reserve (size_t capacity)
166146{
167147 if (m_capacity < capacity)
168148 {
169- m_capacity = std::max ( std::bit_ceil ( capacity), size_t ( 1024 ) );
170- auto storage = std::move (m_storage) ;
171- m_storage = std::make_unique_for_overwrite<std::byte[]>(m_capacity );
172- std::copy (storage. get (), storage. get () + m_size, begin ( ));
149+ Blob cpy ( capacity);
150+ cpy. m_size = m_size ;
151+ std::copy ( begin (), end (), cpy. begin () );
152+ operator =( std::move (cpy ));
173153 }
174154}
175155
0 commit comments