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