1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef MSGPACK_V2_OBJECT_FWD_HPP
12 #define MSGPACK_V2_OBJECT_FWD_HPP
13
14 #include "msgpack/v2/object_fwd_decl.hpp"
15 #include "msgpack/object_fwd.hpp"
16
17 namespace msgpack {
18
19 /// @cond
MSGPACK_API_VERSION_NAMESPACE(v2)20 MSGPACK_API_VERSION_NAMESPACE(v2) {
21 /// @endcond
22
23 struct object : v1::object {
24 object() {}
25 object(v1::object const& o):v1::object(o) {}
26 /// Construct object from T
27 /**
28 * If `v` is the type that is corresponding to MessegePack format str, bin, ext, array, or map,
29 * you need to call `object(const T& v, msgpack::zone& z)` instead of this constructor.
30 *
31 * @tparam T The type of `v`.
32 * @param v The value you want to convert.
33 */
34 template <typename T>
35 explicit object(const T& v) {
36 *this << v;
37 }
38
39 /// Construct object from T
40 /**
41 * The object is constructed on the zone `z`.
42 * See https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_object
43 *
44 * @tparam T The type of `v`.
45 * @param v The value you want to convert.
46 * @param z The zone that is used by the object.
47 */
48 template <typename T>
49 object(const T& v, msgpack::zone& z):v1::object(v, z) {}
50
51 public:
52 /// Convert the object
53 /**
54 * If the object can't be converted to T, msgpack::type_error would be thrown.
55 * @tparam T The type of v.
56 * @param v The value you want to get. `v` is output parameter. `v` is overwritten by converted value from the object.
57 * @return The reference of `v`.
58 */
59 template <typename T>
60 T& convert(T& v) const { return v1::object::convert(v); }
61
62 using v1::object::with_zone;
63 implicit_type convert() const;
64 };
65
66 #if !defined(MSGPACK_USE_CPP03)
67
68 namespace adaptor {
69
70 // If v1 has as specialization for T, then dispatch v1::adaptor::as<T>.
71 // So I call v1::has_as<T> meta function intentionally.
72 template <typename T>
73 struct as<T, typename std::enable_if<v1::has_as<T>::value>::type> : v1::adaptor::as<T> {
74 };
75
76 } // namespace adaptor
77
78 template <typename T>
79 struct has_as {
80 private:
81 template <typename U>
82 static auto check(U*) ->
83 typename std::enable_if<
84 // check v2 specialization
85 std::is_same<
86 decltype(adaptor::as<U>()(std::declval<msgpack::object>())),
87 U
88 >::value
89 ||
90 // check v1 specialization
91 v1::has_as<U>::value,
92 std::true_type
93 >::type;
94 template <typename>
95 static std::false_type check(...);
96 public:
97 using type = decltype(check<T>(MSGPACK_NULLPTR));
98 static constexpr bool value = type::value;
99 };
100
101 #endif // !defined(MSGPACK_USE_CPP03)
102
103 /// @cond
104 } // MSGPACK_API_VERSION_NAMESPACE(v2)
105 /// @endcond
106
107 } // namespace msgpack
108
109 #endif // MSGPACK_V2_OBJECT_FWD_HPP
110