Bond
 
Loading...
Searching...
No Matches
metadata.h
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#pragma once
5
6#include <bond/core/config.h>
7
8#include "sdl.h"
9#include "tags.h"
10
11#include <bond/core/bond_types.h>
12
13namespace bond
14{
15
16
17// Variant operator==
18
21template <typename SignedT>
22inline
23typename boost::enable_if<is_signed_int_or_enum<SignedT>, bool>::type
24operator==(const Variant& variant, SignedT value)
25{
26 BOOST_ASSERT(!variant.nothing);
27 return value == static_cast<SignedT>(variant.int_value);
28}
29
30
33template <typename UnsignedT>
34inline
35typename boost::enable_if<std::is_unsigned<UnsignedT>, bool>::type
36operator==(const Variant& variant, UnsignedT value)
37{
38 BOOST_ASSERT(!variant.nothing);
39 return value == static_cast<UnsignedT>(variant.uint_value);
40}
41
42
45inline bool
46operator==(const Variant& variant, bool value)
47{
48 BOOST_ASSERT(!variant.nothing);
49 BOOST_STATIC_ASSERT((std::is_unsigned<bool>::value));
50
51 return value == !!variant.uint_value;
52}
53
54
57inline bool
58operator==(const Variant& variant, double value)
59{
60 BOOST_ASSERT(!variant.nothing);
61 return value == variant.double_value;
62}
63
64
67inline bool
68operator==(const Variant& variant, const char* value)
69{
70 BOOST_ASSERT(!variant.nothing);
71 return value == variant.string_value;
72}
73
74
77inline bool
78operator==(const Variant& variant, const std::string& value)
79{
80 BOOST_ASSERT(!variant.nothing);
81 return value == variant.string_value;
82}
83
84
87inline bool
88operator==(const Variant& variant, const wchar_t* value)
89{
90 BOOST_ASSERT(!variant.nothing);
91 return value == variant.wstring_value;
92}
93
94
97inline bool
98operator==(const Variant& variant, const std::wstring& value)
99{
100 BOOST_ASSERT(!variant.nothing);
101 return value == variant.wstring_value;
102}
103
104
105namespace detail
106{
107
108
109// VariantSet
110template <typename T>
111inline
112typename boost::enable_if<std::is_unsigned<T> >::type
113VariantSet(bond::Variant& variant, const T& value)
114{
115 variant.uint_value = value;
116}
117
118
119template <typename T>
120inline
121typename boost::enable_if<is_signed_int_or_enum<T> >::type
122VariantSet(bond::Variant& variant, const T& value)
123{
124 variant.int_value = static_cast<int64_t>(value);
125}
126
127
128inline void
129VariantSet(bond::Variant& variant, const char* value)
130{
131 variant.string_value = value;
132}
133
134
135inline void
136VariantSet(bond::Variant& variant, const wchar_t* value)
137{
138 variant.wstring_value = value;
139}
140
141inline void
142VariantSet(bond::Variant& variant, const double& value)
143{
144 variant.double_value = value;
145}
146
147
148// VariantGet
149inline
150void
151VariantGet(const bond::Variant& variant, bool& var)
152{
153 BOOST_ASSERT(!variant.nothing);
154 var = !!variant.uint_value;
155}
156
157
158template <typename T>
159inline
160typename boost::enable_if<std::is_unsigned<T> >::type
161VariantGet(const bond::Variant& variant, T& var)
162{
163 BOOST_ASSERT(!variant.nothing);
164 var = static_cast<T>(variant.uint_value);
165}
166
167
168template <typename T>
169inline
170typename boost::enable_if<is_signed_int_or_enum<T> >::type
171VariantGet(const bond::Variant& variant, T& var)
172{
173 BOOST_ASSERT(!variant.nothing);
174 var = static_cast<T>(variant.int_value);
175}
176
177
178template <typename T>
179inline
180typename boost::enable_if<std::is_floating_point<T> >::type
181VariantGet(const bond::Variant& variant, T& var)
182{
183 BOOST_ASSERT(!variant.nothing);
184 var = static_cast<T>(variant.double_value);
185}
186
187
188template <typename T>
189inline
190typename boost::enable_if<is_string<T> >::type
191VariantGet(const bond::Variant& variant, T& var)
192{
193 BOOST_ASSERT(!variant.nothing);
194
195 const size_t size = variant.string_value.size();
196 resize_string(var, static_cast<uint32_t>(size));
197
198 std::copy(
199 variant.string_value.begin(),
200 variant.string_value.end(),
201 detail::make_checked_array_iterator(string_data(var), size));
202}
203
204
205template <typename T>
206inline
207typename boost::enable_if<is_wstring<T> >::type
208VariantGet(const bond::Variant& variant, T& var)
209{
210 BOOST_ASSERT(!variant.nothing);
211
212 const size_t size = variant.wstring_value.size();
213 resize_string(var, static_cast<uint32_t>(size));
214
215 std::copy(
216 variant.wstring_value.begin(),
217 variant.wstring_value.end(),
218 detail::make_checked_array_iterator(string_data(var), size));
219}
220
221
222// Returns name for basic types, overloaded by generated code for enums
223template <typename T>
224inline
225typename boost::disable_if<std::is_enum<T>, const char*>::type
226GetTypeName(T, const qualified_name_tag&)
227{
228 switch (get_type_id<T>::value)
229 {
230 case BT_BOOL: return "bool";
231 case BT_UINT8: return "uint8";
232 case BT_UINT16: return "uint16";
233 case BT_UINT32: return "uint32";
234 case BT_UINT64: return "uint64";
235 case BT_FLOAT: return "float";
236 case BT_DOUBLE: return "double";
237 case BT_INT8: return "int8";
238 case BT_INT16: return "int16";
239 case BT_INT32: return "int32";
240 case BT_INT64: return "int64";
241 default: BOOST_ASSERT(false);
242 return "unknown_type";
243 }
244}
245
246
247template <typename T>
248inline
249typename boost::enable_if<std::is_enum<T>, const char*>::type
250GetTypeName(T e, const qualified_name_tag&)
251{
252 // In the older versions of generated code we didn't have the overload of
253 // GetTypeName for qualified names; delegating to the old GetTypeName.
254 return GetTypeName(e);
255}
256
257
258// basic types and enums
259template <typename T, typename Enable = void>
260struct type
261{
262 static std::string name()
263 {
264 return GetTypeName(T(), qualified_name);
265 }
266};
267
268// service
269template <typename T>
270struct type<T, typename boost::enable_if<std::is_class<typename T::Schema::methods> >::type>
271{
272 static std::string name()
273 {
274 return T::Schema().metadata.qualified_name;
275 }
276};
277
278// string
279template <typename T>
280struct type<T, typename boost::enable_if<is_string<T> >::type>
281{
282 static std::string name()
283 {
284 return "string";
285 }
286};
287
288
289// wstring
290template <typename T>
291struct type<T, typename boost::enable_if<is_wstring<T> >::type>
292{
293 static std::string name()
294 {
295 return "wstring";
296 }
297};
298
299
300// blob
301template <>
302struct type<blob, void>
303{
304 static std::string name()
305 {
306 return "blob";
307 }
308};
309
310
311// list
312template <typename T>
313struct type<T, typename boost::enable_if<is_list_container<T> >::type>
314{
315 static std::string name()
316 {
317 return "list<" + type<typename element_type<T>::type>::name() + ">";
318 }
319};
320
321
322// set
323template <typename T>
324struct type<T, typename boost::enable_if<is_set_container<T> >::type>
325{
326 static std::string name()
327 {
328 return "set<" + type<typename element_type<T>::type>::name() + ">";
329 }
330};
331
332
333// map
334template <typename T>
335struct type<T, typename boost::enable_if<is_map_container<T> >::type>
336{
337 static std::string name()
338 {
339 return "map<" + type<typename element_type<T>::type::first_type>::name() + ", "
340 + type<typename element_type<T>::type::second_type>::name() + ">";
341 }
342};
343
344
345// bonded
346template <typename T>
347struct type<bonded<T> >
348{
349 static std::string name()
350 {
351 return "bonded<" + type<T>::name() + ">";
352 }
353};
354
355
356// maybe
357template <typename T>
358struct type<maybe<T> >
359{
360 static std::string name()
361 {
362 return type<T>::name();
363 }
364};
365
366
367// struct
368template <typename T>
369struct type<T, typename boost::enable_if<has_schema<T> >::type>
370{
371 static std::string name()
372 {
373 // We can't assume that the dependent type's Schema::metadata static
374 // member is initialized, so instead we call GetMetadata() method.
375 return schema<T>::type::GetMetadata().qualified_name;
376 }
377};
378
379
380// TypeListBuilder
381class TypeListBuilder
382{
383public:
384 TypeListBuilder(std::string& name)
385 : _name(name)
386 {}
387
388 template <typename T>
389 void operator()(const T*)
390 {
391 if (!_name.empty())
392 _name += ", ";
393
394 _name += type<T>::name();
395 }
396
397private:
398 TypeListBuilder& operator=(const TypeListBuilder&);
399
400 std::string& _name;
401};
402
403
404} // namespace detail
405
406
407} // namespace bond
namespace bond
Definition: apply.h:17
boost::enable_if< is_signed_int_or_enum< SignedT >, bool >::type operator==(const Variant &variant, SignedT value)
Compares variant for equality against the provided signed integer or enum value.
Definition: metadata.h:24