Skip to content

Commit 494712e

Browse files
committed
buffer: implement move semantics properly
Default implementations of move semantics are not suitable because buffer owns resources - let's implement proper ones. Note that the move cannot be implemented as a swap here because allocator, that is stored in the buffer, shouldn't be used after it is moved. Part of #110
1 parent 60700f5 commit 494712e

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

src/Buffer/Buffer.hpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ class Buffer
116116
* to the next byte after the last valid byte in block.
117117
* */
118118
bool isEndOfBlock(const char *ptr);
119+
/** Delete blocks and release occupied memory. */
120+
void releaseBlocks(void)
121+
{
122+
while (!m_blocks.isEmpty())
123+
delBlock(&m_blocks.first());
124+
}
119125

120126
public:
121127
/** =============== Convenient wrappers =============== */
@@ -269,8 +275,32 @@ class Buffer
269275
Buffer(allocator &&all = allocator());
270276
Buffer(const Buffer& buf) = delete;
271277
Buffer& operator = (const Buffer& buf) = delete;
272-
Buffer(Buffer &&buf) noexcept = default;
273-
Buffer &operator=(Buffer &&buf) noexcept = default;
278+
Buffer(Buffer &&other) noexcept
279+
{
280+
/* Call move assignment operator. */
281+
*this = std::forward<Buffer>(other);
282+
}
283+
Buffer &operator=(Buffer &&other) noexcept
284+
{
285+
if (this == &other)
286+
return *this;
287+
288+
m_blocks = std::move(other.m_blocks);
289+
/*
290+
* Release blocks of `other` right on the move because
291+
* we are going to move its allocator as well and we
292+
* must not use it after it is moved.
293+
*/
294+
other.releaseBlocks();
295+
m_all = std::move(other.m_all);
296+
297+
m_iterators = std::move(other.m_iterators);
298+
m_begin = other.m_begin;
299+
other.m_begin = nullptr;
300+
m_end = other.m_end;
301+
other.m_end = nullptr;
302+
return *this;
303+
}
274304
~Buffer() noexcept;
275305

276306
/**
@@ -667,9 +697,7 @@ Buffer<N, allocator>::Buffer(allocator &&all) : m_all(std::forward<allocator>(al
667697
template <size_t N, class allocator>
668698
Buffer<N, allocator>::~Buffer() noexcept
669699
{
670-
/* Delete blocks and release occupied memory. */
671-
while (!m_blocks.isEmpty())
672-
delBlock(&m_blocks.first());
700+
releaseBlocks();
673701
}
674702

675703
template <size_t N, class allocator>

0 commit comments

Comments
 (0)