Take advantage of unique_ptr and move construction for Buffer

Since Buffer has always implemented its copy constructor with a deep
copy, its Members object will never have multiple owners. Change to unique_ptr.

Also implement move constructors for Buffer, since there may be cases
where a deep copy is not needed.
This commit is contained in:
James R. Barlow 2022-09-04 14:48:25 -07:00
parent 952b00aecd
commit 12967bdf8a
3 changed files with 35 additions and 2 deletions

View File

@ -49,6 +49,10 @@ class Buffer
QPDF_DLL
Buffer& operator=(Buffer const&);
QPDF_DLL
Buffer(Buffer &&) noexcept;
QPDF_DLL
Buffer& operator=(Buffer &&) noexcept;
QPDF_DLL
size_t getSize() const;
QPDF_DLL
unsigned char const* getBuffer() const;
@ -75,7 +79,7 @@ class Buffer
void copy(Buffer const&);
std::shared_ptr<Members> m;
std::unique_ptr<Members> m;
};
#endif // BUFFER_HH

View File

@ -48,12 +48,24 @@ Buffer::operator=(Buffer const& rhs)
return *this;
}
Buffer::Buffer(Buffer&& rhs) noexcept :
m(std::move(rhs.m))
{
}
Buffer&
Buffer::operator=(Buffer&& rhs) noexcept
{
std::swap(this->m, rhs.m);
return *this;
}
void
Buffer::copy(Buffer const& rhs)
{
if (this != &rhs) {
this->m =
std::shared_ptr<Members>(new Members(rhs.m->size, nullptr, true));
std::unique_ptr<Members>(new Members(rhs.m->size, nullptr, true));
if (this->m->size) {
memcpy(this->m->buf, rhs.m->buf, this->m->size);
}

View File

@ -37,6 +37,23 @@ main()
assert(bc2p[1] == 'W');
}
{
// Test that buffers can be moved.
Buffer bm1(2);
unsigned char* bm1p = bm1.getBuffer();
bm1p[0] = 'Q';
bm1p[1] = 'W';
Buffer bm2(std::move(bm1));
bm1p[0] = 'R';
unsigned char* bm2p = bm2.getBuffer();
assert(bm2p == bm1p);
assert(bm2p[0] == 'R');
Buffer bm3 = std::move(bm2);
unsigned char* bm3p = bm3.getBuffer();
assert(bm3p == bm2p);
}
try {
Pl_Discard discard;
Pl_Count count("count", &discard);