diff --git a/include/msgpack/cpp_config.hpp b/include/msgpack/cpp_config.hpp index 6c392799..f9cf3f3f 100644 --- a/include/msgpack/cpp_config.hpp +++ b/include/msgpack/cpp_config.hpp @@ -63,9 +63,9 @@ T& move(T& t) } template -T& move(T const& t) +T const& move(T const& t) { - return const_cast(t); + return t; } template diff --git a/include/msgpack/object.hpp b/include/msgpack/object.hpp index 8e893b92..9fcaf130 100644 --- a/include/msgpack/object.hpp +++ b/include/msgpack/object.hpp @@ -56,6 +56,39 @@ public: const msgpack::unique_ptr& zone() const { return m_zone; } +#if defined(MSGPACK_USE_CPP03) + struct object_handle_ref { + object_handle_ref(object_handle* oh):m_oh(oh) {} + object_handle* m_oh; + }; + + object_handle(object_handle& other): + m_obj(other.m_obj), + m_zone(msgpack::move(other.m_zone)) { + } + + object_handle(object_handle_ref ref): + m_obj(ref.m_oh->m_obj), + m_zone(msgpack::move(ref.m_oh->m_zone)) { + } + + object_handle& operator=(object_handle& other) { + m_obj = other.m_obj; + m_zone = msgpack::move(other.m_zone); + return *this; + } + + object_handle& operator=(object_handle_ref ref) { + m_obj = ref.m_oh->m_obj; + m_zone = msgpack::move(ref.m_oh->m_zone); + return *this; + } + + operator object_handle_ref() { + return object_handle_ref(this); + } +#endif // defined(MSGPACK_USE_CPP03) + private: msgpack::object m_obj; msgpack::unique_ptr m_zone; @@ -110,13 +143,8 @@ inline std::size_t aligned_zone_size(msgpack::object const& obj) { inline object_handle clone(msgpack::object const& obj) { std::size_t size = msgpack::aligned_zone_size(obj); msgpack::unique_ptr z(size == 0 ? nullptr : new msgpack::zone(size)); -#if defined(MSGPACK_USE_CPP03) - msgpack::object newobj = z.get() ? msgpack::move(msgpack::object(obj, *z)) : msgpack::move(obj); - return msgpack::move(object_handle(newobj, msgpack::move(z))); -#else // defined(MSGPACK_USE_CPP03) - msgpack::object newobj = z ? msgpack::object(obj, *z) : obj; + msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj; return object_handle(newobj, msgpack::move(z)); -#endif // defined(MSGPACK_USE_CPP03) } struct object::implicit_type { diff --git a/test/object.cpp b/test/object.cpp index be929695..046ef7a8 100644 --- a/test/object.cpp +++ b/test/object.cpp @@ -346,11 +346,13 @@ TEST(object, clone_int) int v = 0; msgpack::object obj(v); std::size_t sz1 = msgpack::aligned_zone_size(obj); -#if defined(MSGPACK_USE_CPP03) - msgpack::object_handle h = msgpack::move(msgpack::clone(obj)); -#else // defined(MSGPACK_USE_CPP03) msgpack::object_handle h = msgpack::clone(obj); -#endif // defined(MSGPACK_USE_CPP03) + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = msgpack::clone(obj); + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = h; EXPECT_EQ(h.get(), obj); EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); } @@ -361,11 +363,13 @@ TEST(object, clone_str) std::string v = "123456789"; msgpack::object obj(v, z); std::size_t sz1 = msgpack::aligned_zone_size(obj); -#if defined(MSGPACK_USE_CPP03) - msgpack::object_handle h = msgpack::move(msgpack::clone(obj)); -#else // defined(MSGPACK_USE_CPP03) msgpack::object_handle h = msgpack::clone(obj); -#endif // defined(MSGPACK_USE_CPP03) + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = msgpack::clone(obj); + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = h; EXPECT_EQ(h.get(), obj); EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); } @@ -379,11 +383,13 @@ TEST(object, clone_bin) v.push_back('C'); msgpack::object obj(v, z); std::size_t sz1 = msgpack::aligned_zone_size(obj); -#if defined(MSGPACK_USE_CPP03) - msgpack::object_handle h = msgpack::move(msgpack::clone(obj)); -#else // defined(MSGPACK_USE_CPP03) msgpack::object_handle h = msgpack::clone(obj); -#endif // defined(MSGPACK_USE_CPP03) + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = msgpack::clone(obj); + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = h; EXPECT_EQ(h.get(), obj); EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); } @@ -397,11 +403,13 @@ TEST(object, clone_array) v.push_back(3); msgpack::object obj(v, z); std::size_t sz1 = msgpack::aligned_zone_size(obj); -#if defined(MSGPACK_USE_CPP03) - msgpack::object_handle h = msgpack::move(msgpack::clone(obj)); -#else // defined(MSGPACK_USE_CPP03) msgpack::object_handle h = msgpack::clone(obj); -#endif // defined(MSGPACK_USE_CPP03) + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = msgpack::clone(obj); + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = h; EXPECT_EQ(h.get(), obj); EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); } @@ -415,11 +423,13 @@ TEST(object, clone_map) v.insert(std::map::value_type(3, "GHI")); msgpack::object obj(v, z); std::size_t sz1 = msgpack::aligned_zone_size(obj); -#if defined(MSGPACK_USE_CPP03) - msgpack::object_handle h = msgpack::move(msgpack::clone(obj)); -#else // defined(MSGPACK_USE_CPP03) msgpack::object_handle h = msgpack::clone(obj); -#endif // defined(MSGPACK_USE_CPP03) + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = msgpack::clone(obj); + EXPECT_EQ(h.get(), obj); + EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); + h = h; EXPECT_EQ(h.get(), obj); EXPECT_EQ(sz1, msgpack::aligned_zone_size(h.get())); }