1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2014 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_V1_OBJECT_FWD_HPP
12 #define MSGPACK_V1_OBJECT_FWD_HPP
13 
14 #include "msgpack/object_fwd_decl.hpp"
15 
16 namespace msgpack {
17 
18 /// @cond
MSGPACK_API_VERSION_NAMESPACE(v1)19 MSGPACK_API_VERSION_NAMESPACE(v1) {
20 /// @endcond
21 
22 struct object_array {
23     uint32_t size;
24     msgpack::object* ptr;
25 };
26 
27 struct object_map {
28     uint32_t size;
29     msgpack::object_kv* ptr;
30 };
31 
32 struct object_str {
33     uint32_t size;
34     const char* ptr;
35 };
36 
37 struct object_bin {
38     uint32_t size;
39     const char* ptr;
40 };
41 
42 struct object_ext {
43     int8_t type() const { return static_cast<int8_t>(ptr[0]); }
44     const char* data() const { return &ptr[1]; }
45     uint32_t size;
46     const char* ptr;
47 };
48 
49 
50 #if !defined(MSGPACK_USE_CPP03)
51 
52 template <typename T>
53 struct has_as {
54 private:
55     template <typename U>
56     static auto check(U*) ->
57         // Check v1 specialization
58         typename std::is_same<
59             decltype(adaptor::as<U>()(std::declval<msgpack::object>())),
60             T
61         >::type;
62     template <typename...>
63     static std::false_type check(...);
64 public:
65     using type = decltype(check<T>(MSGPACK_NULLPTR));
66     static constexpr bool value = type::value;
67 };
68 
69 #endif // !defined(MSGPACK_USE_CPP03)
70 
71 /// Object class that corresponding to MessagePack format object
72 /**
73  * See https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_object
74  */
75 struct object {
76     union union_type {
77         bool boolean;
78         uint64_t u64;
79         int64_t  i64;
80 #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
81         MSGPACK_DEPRECATED("please use f64 instead")
82         double   dec; // obsolete
83 #endif // MSGPACK_USE_LEGACY_NAME_AS_FLOAT
84         double   f64;
85         msgpack::object_array array;
86         msgpack::object_map map;
87         msgpack::object_str str;
88         msgpack::object_bin bin;
89         msgpack::object_ext ext;
90     };
91 
92     msgpack::type::object_type type;
93     union_type via;
94 
95     /// Cheking nil
96     /**
97      * @return If the object is nil, then return true, else return false.
98      */
99     bool is_nil() const { return type == msgpack::type::NIL; }
100 
101 #if defined(MSGPACK_USE_CPP03)
102 
103     /// Get value as T
104     /**
105      * If the object can't be converted to T, msgpack::type_error would be thrown.
106      * @tparam T The type you want to get.
107      * @return The converted object.
108      */
109     template <typename T>
110     T as() const;
111 
112 #else  // defined(MSGPACK_USE_CPP03)
113 
114     /// Get value as T
115     /**
116      * If the object can't be converted to T, msgpack::type_error would be thrown.
117      * @tparam T The type you want to get.
118      * @return The converted object.
119      */
120     template <typename T>
121     typename std::enable_if<msgpack::has_as<T>::value, T>::type as() const;
122 
123     /// Get value as T
124     /**
125      * If the object can't be converted to T, msgpack::type_error would be thrown.
126      * @tparam T The type you want to get.
127      * @return The converted object.
128      */
129     template <typename T>
130     typename std::enable_if<!msgpack::has_as<T>::value, T>::type as() const;
131 
132 #endif // defined(MSGPACK_USE_CPP03)
133 
134     /// Convert the object
135     /**
136      * If the object can't be converted to T, msgpack::type_error would be thrown.
137      * @tparam T The type of v.
138      * @param v The value you want to get. `v` is output parameter. `v` is overwritten by converted value from the object.
139      * @return The reference of `v`.
140      */
141     template <typename T>
142     typename msgpack::enable_if<
143         !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
144         T&
145     >::type
146     convert(T& v) const;
147 
148     template <typename T, std::size_t N>
149     T (&convert(T(&v)[N]) const)[N];
150 
151 
152 #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
153     /// Convert the object (obsolete)
154     /**
155      * If the object can't be converted to T, msgpack::type_error would be thrown.
156      * @tparam T The type of v.
157      * @param v The pointer of the value you want to get. `v` is output parameter. `*v` is overwritten by converted value from the object.
158      * @return The pointer of `v`.
159      */
160     template <typename T>
161     MSGPACK_DEPRECATED("please use reference version instead")
162     typename msgpack::enable_if<
163         msgpack::is_pointer<T>::value,
164         T
165     >::type
166     convert(T v) const;
167 #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
168 
169     /// Convert the object if not nil
170     /**
171      * If the object is not nil and can't be converted to T, msgpack::type_error would be thrown.
172      * @tparam T The type of v.
173      * @param v The value you want to get. `v` is output parameter. `v` is overwritten by converted value from the object if the object is not nil.
174      * @return If the object is nil, then return false, else return true.
175      */
176     template <typename T>
177     bool convert_if_not_nil(T& v) const;
178 
179     /// Default constructor. The object is set to nil.
180     object();
181 
182     /// Copy constructor. Object is shallow copied.
183     object(const msgpack_object& o);
184 
185     /// Construct object from T
186     /**
187      * If `v` is the type that is corresponding to MessegePack format str, bin, ext, array, or map,
188      * you need to call `object(const T& v, msgpack::zone& z)` instead of this constructor.
189      *
190      * @tparam T The type of `v`.
191      * @param v The value you want to convert.
192      */
193     template <typename T>
194     explicit object(const T& v);
195 
196     /// Construct object from T
197     /**
198      * The object is constructed on the zone `z`.
199      * See https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_object
200      *
201      * @tparam T The type of `v`.
202      * @param v The value you want to convert.
203      * @param z The zone that is used by the object.
204      */
205     template <typename T>
206     object(const T& v, msgpack::zone& z);
207 
208     /// Construct object from T (obsolete)
209     /**
210      * The object is constructed on the zone `z`.
211      * Use `object(const T& v, msgpack::zone& z)` instead of this constructor.
212      * See https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_object
213      *
214      * @tparam T The type of `v`.
215      * @param v The value you want to convert.
216      * @param z The pointer to the zone that is used by the object.
217      */
218     template <typename T>
219     MSGPACK_DEPRECATED("please use zone reference version instead of the pointer version")
220     object(const T& v, msgpack::zone* z);
221 
222     template <typename T>
223     object& operator=(const T& v);
224 
225     operator msgpack_object() const;
226 
227     struct with_zone;
228 
229 protected:
230     struct implicit_type;
231 
232 public:
233     implicit_type convert() const;
234 };
235 
236 class type_error : public std::bad_cast { };
237 
238 struct object::implicit_type {
239     implicit_type(object const& o) : obj(o) { }
240     ~implicit_type() { }
241 
242     template <typename T>
243     operator T();
244 
245 private:
246     object const& obj;
247 };
248 
249 /// @cond
250 } // MSGPACK_API_VERSION_NAMESPACE(v1)
251 /// @endcond
252 
253 } // namespace msgpack
254 
255 #endif // MSGPACK_V1_OBJECT_FWD_HPP
256