Added a move constructor and a move assign operator for unpacker and context.

https://github.com/msgpack/msgpack-c/issues/96
This commit is contained in:
Takatoshi Kondo 2014-07-23 21:31:42 +09:00
parent 59b111e026
commit f11a811114
2 changed files with 100 additions and 4 deletions

View File

@ -248,6 +248,10 @@ public:
{
m_stack[0].set_obj(object());
}
#if !defined(MSGPACK_USE_CPP03)
context(context&& other) = default;
context& operator=(context&& other) = default;
#endif // !defined(MSGPACK_USE_CPP03)
void init()
{
@ -721,6 +725,9 @@ private:
unsigned int m_top;
unsigned int m_stack_idx;
unpack_stack m_stack[MSGPACK_EMBED_STACK_SIZE];
private:
context(context const&);
context& operator=(context const&);
};
} // detail
@ -760,6 +767,12 @@ private:
class unpacker {
public:
unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
#if !defined(MSGPACK_USE_CPP03)
unpacker(unpacker&& other);
unpacker& operator=(unpacker&& other);
#endif // !defined(MSGPACK_USE_CPP03)
~unpacker();
public:
@ -925,10 +938,44 @@ inline unpacker::unpacker(size_t initial_buffer_size)
m_ctx.user().set_referenced(false);
}
#if !defined(MSGPACK_USE_CPP03)
// Move constructor and move assignment operator
inline unpacker::unpacker(unpacker&& other)
:m_buffer(other.m_buffer),
m_used(other.m_used),
m_free(other.m_free),
m_off(other.m_off),
m_parsed(other.m_parsed),
m_z(other.m_z),
m_initial_buffer_size(other.m_initial_buffer_size),
m_ctx(msgpack::move(other.m_ctx)) {
other.m_buffer = nullptr;
other.m_z = nullptr;
}
inline unpacker& unpacker::operator=(unpacker&& other) {
m_buffer = other.m_buffer;
m_used = other.m_used;
m_free = other.m_free;
m_off = other.m_off;
m_parsed = other.m_parsed;
m_z = other.m_z;
m_initial_buffer_size = other.m_initial_buffer_size;
m_ctx = msgpack::move(other.m_ctx);
other.m_buffer = nullptr;
other.m_z = nullptr;
return *this;
}
#endif // !defined(MSGPACK_USE_CPP03)
inline unpacker::~unpacker()
{
zone::destroy(m_z);
detail::decl_count(m_buffer);
// These checks are required for move operations.
if (m_z) zone::destroy(m_z);
if (m_buffer) detail::decl_count(m_buffer);
}
@ -1269,4 +1316,3 @@ inline object unpack(const char* data, size_t len, zone* z, size_t* off)
} // namespace msgpack
#endif /* msgpack/unpack.hpp */

View File

@ -48,6 +48,57 @@ TEST(streaming, basic)
}
}
#if !defined(MSGPACK_USE_CPP03)
TEST(streaming, move)
{
msgpack::sbuffer buffer;
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack(1);
pk.pack(2);
pk.pack(3);
const char* input = buffer.data();
const char* const eof = input + buffer.size();
msgpack::unpacker pac;
msgpack::unpacked result;
int count = 0;
while(count < 3) {
msgpack::unpacker pac_in(std::move(pac));
pac_in.reserve_buffer(32*1024);
// read buffer into pac_in.buffer() upto
// pac_in.buffer_capac_inity() bytes.
size_t len = 1;
memcpy(pac_in.buffer(), input, len);
input += len;
pac_in.buffer_consumed(len);
while(pac_in.next(&result)) {
msgpack::object obj = result.get();
switch(count++) {
case 0:
EXPECT_EQ(1, obj.as<int>());
break;
case 1:
EXPECT_EQ(2, obj.as<int>());
break;
case 2:
EXPECT_EQ(3, obj.as<int>());
return;
}
}
EXPECT_TRUE(input < eof);
pac = std::move(pac_in);
}
}
#endif // !defined(MSGPACK_USE_CPP03)
class event_handler {
public:
@ -217,4 +268,3 @@ TEST(streaming, event_compat)
handler.expect = 3;
handler.on_read();
}