Skip to content

Commit b559187

Browse files
committed
Merge pull request #302 from redboltz/add_no_defcon_support
Added no default constructible classes support.
2 parents 9e7564c + 45b57c2 commit b559187

File tree

3 files changed

+155
-0
lines changed

3 files changed

+155
-0
lines changed

include/msgpack/object.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ inline T* object::convert(T* v) const
511511
return v;
512512
}
513513

514+
#if defined(MSGPACK_USE_CPP03)
515+
514516
template <typename T>
515517
inline T object::as() const
516518
{
@@ -519,6 +521,21 @@ inline T object::as() const
519521
return v;
520522
}
521523

524+
#else // defined(MSGPACK_USE_CPP03)
525+
526+
template <typename T>
527+
inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
528+
return msgpack::adaptor::as<T>()(*this);
529+
}
530+
531+
template <typename T>
532+
inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
533+
T v;
534+
convert(v);
535+
return v;
536+
}
537+
538+
#endif // defined(MSGPACK_USE_CPP03)
522539

523540
inline object::object()
524541
{

include/msgpack/object_fwd.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,33 @@ struct object_ext {
8181
const char* ptr;
8282
};
8383

84+
85+
#if !defined(MSGPACK_USE_CPP03)
86+
struct object;
87+
88+
namespace adaptor {
89+
template <typename T>
90+
struct as;
91+
} // namespace adaptor
92+
93+
template <typename T>
94+
struct has_as {
95+
private:
96+
template <typename U>
97+
static auto check(U*) ->
98+
typename std::is_same<
99+
decltype(msgpack::adaptor::as<U>()(std::declval<msgpack::object>())),
100+
T>::type;
101+
template <typename>
102+
static std::false_type check(...);
103+
using type = decltype(check<T>(nullptr));
104+
public:
105+
static constexpr bool value = type::value;
106+
};
107+
108+
#endif // !defined(MSGPACK_USE_CPP03)
109+
110+
84111
struct object {
85112
union union_type {
86113
bool boolean;
@@ -102,9 +129,21 @@ struct object {
102129

103130
bool is_nil() const { return type == msgpack::type::NIL; }
104131

132+
#if defined(MSGPACK_USE_CPP03)
133+
105134
template <typename T>
106135
T as() const;
107136

137+
#else // defined(MSGPACK_USE_CPP03)
138+
139+
template <typename T>
140+
typename std::enable_if<msgpack::has_as<T>::value, T>::type as() const;
141+
142+
template <typename T>
143+
typename std::enable_if<!msgpack::has_as<T>::value, T>::type as() const;
144+
145+
#endif // defined(MSGPACK_USE_CPP03)
146+
108147
template <typename T>
109148
T& convert(T& v) const;
110149
template <typename T>

test/msgpack_cpp11.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,103 @@ TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_class_member)
185185
EXPECT_EQ(val1.t3, val2.t3);
186186
}
187187

188+
struct no_def_con {
189+
no_def_con() = delete;
190+
no_def_con(int i):i(i) {}
191+
int i;
192+
MSGPACK_DEFINE(i);
193+
};
194+
195+
namespace msgpack {
196+
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
197+
namespace adaptor {
198+
template <>
199+
struct as<no_def_con> {
200+
no_def_con operator()(msgpack::object const& o) const {
201+
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
202+
if (o.via.array.size != 1) throw msgpack::type_error();
203+
return no_def_con(o.via.array.ptr[0].as<int>());
204+
}
205+
};
206+
} // adaptor
207+
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
208+
} // msgpack
209+
210+
TEST(MSGPACK_NO_DEF_CON, simple_buffer)
211+
{
212+
no_def_con val1(42);
213+
msgpack::sbuffer sbuf;
214+
msgpack::pack(sbuf, val1);
215+
msgpack::unpacked ret;
216+
msgpack::unpack(ret, sbuf.data(), sbuf.size());
217+
218+
no_def_con val2 = ret.get().as<no_def_con>();
219+
EXPECT_EQ(val1.i, val2.i);
220+
}
221+
222+
struct no_def_con_composite {
223+
no_def_con_composite() = delete;
224+
no_def_con_composite(no_def_con const& a):ndc(a) {}
225+
no_def_con ndc;
226+
MSGPACK_DEFINE(ndc);
227+
};
228+
229+
namespace msgpack {
230+
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
231+
namespace adaptor {
232+
template <>
233+
struct as<no_def_con_composite> {
234+
no_def_con_composite operator()(msgpack::object const& o) const {
235+
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
236+
if (o.via.array.size != 1) throw msgpack::type_error();
237+
return no_def_con_composite(o.via.array.ptr[0].as<no_def_con>());
238+
}
239+
};
240+
} // adaptor
241+
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
242+
} // msgpack
243+
244+
TEST(MSGPACK_NO_DEF_CON_COMPOSITE, simple_buffer)
245+
{
246+
no_def_con_composite val1(42);
247+
msgpack::sbuffer sbuf;
248+
msgpack::pack(sbuf, val1);
249+
msgpack::unpacked ret;
250+
msgpack::unpack(ret, sbuf.data(), sbuf.size());
251+
no_def_con_composite val2 = ret.get().as<no_def_con_composite>();
252+
EXPECT_EQ(val1.ndc.i, val2.ndc.i);
253+
}
254+
255+
struct no_def_con_inherit : no_def_con {
256+
no_def_con_inherit() = delete;
257+
no_def_con_inherit(no_def_con const& a):no_def_con(a) {}
258+
MSGPACK_DEFINE(MSGPACK_BASE(no_def_con));
259+
};
260+
261+
namespace msgpack {
262+
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
263+
namespace adaptor {
264+
template <>
265+
struct as<no_def_con_inherit> {
266+
no_def_con_inherit operator()(msgpack::object const& o) const {
267+
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
268+
if (o.via.array.size != 1) throw msgpack::type_error();
269+
return no_def_con_inherit(o.via.array.ptr[0].as<no_def_con>());
270+
}
271+
};
272+
} // adaptor
273+
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
274+
} // msgpack
275+
276+
TEST(MSGPACK_NO_DEF_CON_INHERIT, simple_buffer)
277+
{
278+
no_def_con_inherit val1(42);
279+
msgpack::sbuffer sbuf;
280+
msgpack::pack(sbuf, val1);
281+
msgpack::unpacked ret;
282+
msgpack::unpack(ret, sbuf.data(), sbuf.size());
283+
no_def_con_inherit val2 = ret.get().as<no_def_con_inherit>();
284+
EXPECT_EQ(val1.i, val2.i);
285+
}
286+
188287
#endif // !defined(MSGPACK_USE_CPP03)

0 commit comments

Comments
 (0)