Skip to content

Commit b5599ef

Browse files
committed
Support to-object conversions for std::reference_wrapper<const T>.
Previously the conversion would fail because struct object is not generally provided for the const version of the type, but because the wrapper would pass down the type unchanged, it would look for exactly that missing template specialization unsuccessfully. This is specifically an issue for std::reference_wrapper because std::cref() returns an std::reference_wrapper<const T>.
1 parent 0a261fc commit b5599ef

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

include/msgpack/adaptor/cpp11/reference_wrapper.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "msgpack/adaptor/check_container_size.hpp"
2525

2626
#include <memory>
27+
#include <type_traits>
2728

2829
namespace msgpack {
2930

@@ -53,14 +54,14 @@ struct pack<std::reference_wrapper<T>> {
5354
template <typename T>
5455
struct object<std::reference_wrapper<T> > {
5556
void operator()(msgpack::object& o, const std::reference_wrapper<T>& v) const {
56-
msgpack::adaptor::object<T>()(o, v.get());
57+
msgpack::adaptor::object<typename std::remove_const<T>::type>()(o, v.get());
5758
}
5859
};
5960

6061
template <typename T>
6162
struct object_with_zone<std::reference_wrapper<T>> {
6263
void operator()(msgpack::object::with_zone& o, const std::reference_wrapper<T>& v) const {
63-
msgpack::adaptor::object_with_zone<T>()(o, v.get());
64+
msgpack::adaptor::object_with_zone<typename std::remove_const<T>::type>()(o, v.get());
6465
}
6566
};
6667

test/reference_wrapper_cpp11.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,20 @@ TEST(MSGPACK_REFERENCE_WRAPPER, pack_convert)
1717
msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size());
1818
int i2 = 0;
1919
std::reference_wrapper<int> val2(i2);
20-
oh.get().convert(val2);;
20+
oh.get().convert(val2);
21+
EXPECT_EQ(i1, i2);
22+
}
23+
24+
TEST(MSGPACK_REFERENCE_WRAPPER, pack_convert_const)
25+
{
26+
const int i1 = 42;
27+
std::reference_wrapper<const int> val1(i1);
28+
std::stringstream ss;
29+
msgpack::pack(ss, val1);
30+
msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size());
31+
int i2 = 0;
32+
std::reference_wrapper<int> val2(i2);
33+
oh.get().convert(val2);
2134
EXPECT_EQ(i1, i2);
2235
}
2336

@@ -44,6 +57,17 @@ TEST(MSGPACK_REFERENCE_WRAPPER, object)
4457
EXPECT_EQ(i1, i2);
4558
}
4659

60+
TEST(MSGPACK_REFERENCE_WRAPPER, object_const)
61+
{
62+
const int i1 = 42;
63+
std::reference_wrapper<const int> val1(i1);
64+
msgpack::object o(val1);
65+
int i2 = 0;
66+
std::reference_wrapper<int> val2(i2);
67+
o.convert(val2);
68+
EXPECT_EQ(i1, i2);
69+
}
70+
4771
TEST(MSGPACK_REFERENCE_WRAPPER, object_with_zone)
4872
{
4973
std::string s1 = "ABC";
@@ -56,4 +80,16 @@ TEST(MSGPACK_REFERENCE_WRAPPER, object_with_zone)
5680
EXPECT_EQ(s1, s2);
5781
}
5882

83+
TEST(MSGPACK_REFERENCE_WRAPPER, object_with_zone_const)
84+
{
85+
const std::string s1 = "ABC";
86+
std::reference_wrapper<const std::string> val1(s1);
87+
msgpack::zone z;
88+
msgpack::object o(val1, z);
89+
std::string s2 = "DE";
90+
std::reference_wrapper<std::string> val2(s2);
91+
o.convert(val2);
92+
EXPECT_EQ(s1, s2);
93+
}
94+
5995
#endif // !defined(MSGPACK_USE_CPP03)

0 commit comments

Comments
 (0)