Bond
 
Loading...
Searching...
No Matches
typeid_value.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 <bond/core/blob.h>
9#include <bond/core/reflection.h>
10
11#include <boost/utility/enable_if.hpp>
12
13namespace bond
14{
15
16namespace detail
17{
18// The following control which containers will be preallocated when deserializing
19// and which require incrementally adding items so that a large size in a payload
20// doesn't cause a large memory allocation.
21template <typename TContainer, typename TElement, typename Enable = void>
22struct is_deserialize_direct
23 : std::false_type {};
24
25template <typename TContainer, typename TElement>
26struct is_deserialize_direct<TContainer, TElement,
27 typename boost::enable_if_c<require_modify_element<TContainer>::value
28 && is_element_matching<TElement, TContainer>::value>::type>
29 : std::true_type {};
30
31template <typename TContainer, typename TElement>
32struct is_deserialize_direct<TContainer, TElement,
33 typename boost::enable_if_c<is_list_container<TContainer>::value
34 && !is_nullable<TContainer>::value
35 && is_basic_type<typename remove_bonded_value<TElement>::type>::value
36 && !require_modify_element<TContainer>::value
37 && is_element_matching<TElement, TContainer>::value>::type>
38 : std::true_type {};
39
40template <typename TContainer, typename TElement, typename Enable = void>
41struct is_deserialize_incremental
42 : std::false_type {};
43
44template <typename TElement>
45struct is_deserialize_incremental<nullable<TElement>, TElement>
46 : std::false_type {};
47
48template <typename TContainer, typename TElement>
49struct is_deserialize_incremental<TContainer, TElement,
50 typename boost::enable_if_c<is_list_container<TContainer>::value
51 && !is_basic_type<typename remove_bonded_value<TElement>::type>::value
52 && is_element_matching<TElement, TContainer>::value
53 && !require_modify_element<TContainer>::value>::type>
54 : std::true_type {};
55};
56
57template <typename Protocols, typename X, typename Key, typename T>
58typename boost::enable_if<is_map_key_matching<Key, X> >::type
59inline DeserializeMapElements(X& var, const Key& key, const T& element, uint32_t size);
60
61template <typename Protocols, typename X, typename Key, typename T>
62typename boost::disable_if<is_map_key_matching<Key, X> >::type
63inline DeserializeMapElements(X&, const Key& key, const T& element, uint32_t size);
64
65template <typename Protocols, typename Transform, typename Key, typename T>
66inline void DeserializeMapElements(const Transform& transform, const Key& key, const T& element, uint32_t size);
67
68template <typename Protocols, typename X, typename T>
69typename boost::enable_if_c<detail::is_deserialize_direct<X, T>::value>::type
70inline DeserializeElements(X& var, const T& element, uint32_t size);
71
72template <typename Protocols, typename X, typename T>
73typename boost::enable_if_c<is_matching<T, X>::value>::type
74inline DeserializeElements(nullable<X>& var, const T& element, uint32_t size);
75
76template <typename Protocols, typename X, typename T>
77typename boost::enable_if_c<detail::is_deserialize_incremental<X, T>::value>::type
78inline DeserializeElements(X& var, const T& element, uint32_t size);
79
80template <typename Protocols, typename Reader>
81inline void DeserializeElements(blob& var, const value<blob::value_type, Reader&>& element, uint32_t size);
82
83template <typename Protocols, typename X, typename T>
84typename boost::enable_if_c<is_set_container<X>::value
85 && is_element_matching<T, X>::value>::type
86inline DeserializeElements(X& var, const T& element, uint32_t size);
87
88template <typename Protocols, typename X, typename T>
89typename boost::enable_if_c<!is_element_matching<T, X>::value >::type
90inline DeserializeElements(X&, const T& element, uint32_t size);
91
92template <typename Protocols, typename Transform, typename T>
93void inline DeserializeElements(const Transform& transform, const T& element, uint32_t size);
94
95namespace detail
96{
97
98
99// Sanity check to assert that manually expended switch statement are consistent
100// with the canonical definition of type promotion in is_matching metafunction.
101
102template <typename T>
103bool IsMatching(BondDataType type)
104{
105 switch (type)
106 {
107 case bond::BT_BOOL:
108 return is_matching<bool, T>::value;
109
110 case bond::BT_UINT8:
111 return is_matching<uint8_t, T>::value;
112
113 case bond::BT_UINT16:
114 return is_matching<uint16_t, T>::value;
115
116 case bond::BT_UINT32:
117 return is_matching<uint32_t, T>::value;
118
119 case bond::BT_UINT64:
120 return is_matching<uint64_t, T>::value;
121
122 case bond::BT_FLOAT:
123 return is_matching<float, T>::value;
124
125 case bond::BT_DOUBLE:
126 return is_matching<double, T>::value;
127
128 case bond::BT_STRING:
129 return is_matching<std::string, T>::value;
130
131 case bond::BT_WSTRING:
132 return is_matching<std::wstring, T>::value;
133
134 case bond::BT_INT8:
135 return is_matching<int8_t, T>::value;
136
137 case bond::BT_INT16:
138 return is_matching<int16_t, T>::value;
139
140 case bond::BT_INT32:
141 return is_matching<int32_t, T>::value;
142
143 case bond::BT_INT64:
144 return is_matching<int64_t, T>::value;
145
146 default:
147 BOOST_ASSERT(false);
148 return false;
149 }
150}
151
152
153template <typename Transform, typename Reader>
154inline bool BasicTypeField(uint16_t id, const Metadata& metadata, BondDataType type, const Transform& transform, Reader& input)
155{
156 switch (type)
157 {
158 case bond::BT_BOOL:
159 return transform.Field(id, metadata, value<bool, Reader&>(input));
160
161 case bond::BT_UINT8:
162 return transform.Field(id, metadata, value<uint8_t, Reader&>(input));
163
164 case bond::BT_UINT16:
165 return transform.Field(id, metadata, value<uint16_t, Reader&>(input));
166
167 case bond::BT_UINT32:
168 return transform.Field(id, metadata, value<uint32_t, Reader&>(input));
169
170 case bond::BT_UINT64:
171 return transform.Field(id, metadata, value<uint64_t, Reader&>(input));
172
173 case bond::BT_FLOAT:
174 return transform.Field(id, metadata, value<float, Reader&>(input));
175
176 case bond::BT_DOUBLE:
177 return transform.Field(id, metadata, value<double, Reader&>(input));
178
179 case bond::BT_STRING:
180 return transform.Field(id, metadata, value<std::string, Reader&>(input));
181
182 case bond::BT_WSTRING:
183 return transform.Field(id, metadata, value<std::wstring, Reader&>(input));
184
185 case bond::BT_INT8:
186 return transform.Field(id, metadata, value<int8_t, Reader&>(input));
187
188 case bond::BT_INT16:
189 return transform.Field(id, metadata, value<int16_t, Reader&>(input));
190
191 case bond::BT_INT32:
192 return transform.Field(id, metadata, value<int32_t, Reader&>(input));
193
194 case bond::BT_INT64:
195 return transform.Field(id, metadata, value<int64_t, Reader&>(input));
196
197 default:
198 BOOST_ASSERT(false);
199 return false;
200 }
201}
202
203
204template <typename Reader, typename T = uint8_t>
205inline void CheckInputData(Reader& input, uint32_t size)
206{
207 if (!input.template CanReadArray<T>(size))
208 {
209 OutOfBoundObjectSizeException();
210 }
211}
212
213template <typename Protocols, typename T, typename E, typename Reader>
214inline void DeserializeElementsChecked(T& var, Reader& input, uint32_t size)
215{
216 CheckInputData<Reader, E>(input, size);
217 return DeserializeElements<Protocols>(var, value<E, Reader&>(input, false), size);
218}
219
220
221template <typename Protocols, typename T, typename Reader>
222inline void BasicTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
223{
224 BOOST_STATIC_ASSERT(!is_container<T>::value);
225
226 switch (type)
227 {
228 case bond::BT_BOOL:
229 return DeserializeElementsChecked<Protocols, T, bool, Reader>(var, input, size);
230
231 case bond::BT_UINT8:
232 return DeserializeElementsChecked<Protocols, T, uint8_t, Reader>(var, input, size);
233
234 case bond::BT_UINT16:
235 return DeserializeElementsChecked<Protocols, T, uint16_t, Reader>(var, input, size);
236
237 case bond::BT_UINT32:
238 return DeserializeElementsChecked<Protocols, T, uint32_t, Reader>(var, input, size);
239
240 case bond::BT_UINT64:
241 return DeserializeElementsChecked<Protocols, T, uint64_t, Reader>(var, input, size);
242
243 case bond::BT_FLOAT:
244 return DeserializeElementsChecked<Protocols, T, float, Reader>(var, input, size);
245
246 case bond::BT_DOUBLE:
247 return DeserializeElementsChecked<Protocols, T, double, Reader>(var, input, size);
248
249 case bond::BT_STRING:
250 return DeserializeElementsChecked<Protocols, T, std::string, Reader>(var, input, size);
251
252 case bond::BT_WSTRING:
253 return DeserializeElementsChecked<Protocols, T, std::wstring, Reader>(var, input, size);
254
255 case bond::BT_INT8:
256 return DeserializeElementsChecked<Protocols, T, int8_t, Reader>(var, input, size);
257
258 case bond::BT_INT16:
259 return DeserializeElementsChecked<Protocols, T, int16_t, Reader>(var, input, size);
260
261 case bond::BT_INT32:
262 return DeserializeElementsChecked<Protocols, T, int32_t, Reader>(var, input, size);
263
264 case bond::BT_INT64:
265 return DeserializeElementsChecked<Protocols, T, int64_t, Reader>(var, input, size);
266
267 default:
268 BOOST_ASSERT(false);
269 return;
270 }
271}
272
273
274template <typename E>
275inline void SkipElements(const E& element, uint32_t size)
276{
277 while (size--)
278 element.Skip();
279}
280
281template <typename Reader>
282inline void SkipElements(BondDataType type, Reader& input, uint32_t size)
283{
284 while (size--)
285 input.Skip(type);
286}
287
288// MatchingTypeContainer function are manually expended versions of BasicTypeContainer
289// using the type information about destination container. This helps with compilation speed.
290template <typename Protocols, typename T, typename Reader>
291typename boost::enable_if<is_type_alias<typename element_type<T>::type> >::type
292inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
293{
294 if (type == get_type_id<typename element_type<T>::type>::value)
295 {
296 DeserializeElementsChecked<Protocols, T, typename element_type<T>::type, Reader>(var, input, size);
297 }
298 else
299 {
300 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
301
302 SkipElements(type, input, size);
303 }
304}
305
306
307template <typename Protocols, typename T, typename Reader>
308typename boost::enable_if<std::is_same<bool, typename element_type<T>::type> >::type
309inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
310{
311 switch (type)
312 {
313 case bond::BT_BOOL:
314 return DeserializeElementsChecked<Protocols, T, bool, Reader>(var, input, size);
315
316 default:
317 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
318
319 SkipElements(type, input, size);
320 break;
321 }
322}
323
324
325template <typename Protocols, typename T, typename Reader>
326typename boost::enable_if<is_string<typename element_type<T>::type> >::type
327inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
328{
329 switch (type)
330 {
331 case bond::BT_STRING:
332 return DeserializeElementsChecked < Protocols, T, std::string, Reader > (var, input, size);
333
334 default:
335 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
336
337 SkipElements(type, input, size);
338 break;
339 }
340}
341
342
343template <typename Protocols, typename T, typename Reader>
344typename boost::enable_if<is_wstring<typename element_type<T>::type> >::type
345inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
346{
347 switch (type)
348 {
349 case bond::BT_WSTRING:
350 return DeserializeElementsChecked<Protocols, T, std::wstring, Reader>(var, input, size);
351
352 default:
353 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
354
355 SkipElements(type, input, size);
356 break;
357 }
358}
359
360
361template <typename Protocols, typename T, typename Reader>
362typename boost::enable_if<std::is_floating_point<typename element_type<T>::type> >::type
363inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
364{
365 switch (type)
366 {
367 case bond::BT_FLOAT:
368 return DeserializeElementsChecked<Protocols, T, float, Reader>(var, input, size);
369
370 case bond::BT_DOUBLE:
371 return DeserializeElementsChecked<Protocols, T, double, Reader>(var, input, size);
372
373 default:
374 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
375
376 SkipElements(type, input, size);
377 break;
378 }
379}
380
381
382template <typename Protocols, typename T, typename Reader>
383typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type> >::type
384inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
385{
386 switch (type)
387 {
388 case bond::BT_UINT8:
389 return DeserializeElementsChecked<Protocols, T, uint8_t, Reader>(var, input, size);
390
391 case bond::BT_UINT16:
392 return DeserializeElementsChecked<Protocols, T, uint16_t, Reader>(var, input, size);
393
394 case bond::BT_UINT32:
395 return DeserializeElementsChecked<Protocols, T, uint32_t, Reader>(var, input, size);
396
397 case bond::BT_UINT64:
398 return DeserializeElementsChecked<Protocols, T, uint64_t, Reader>(var, input, size);
399
400 default:
401 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
402
403 SkipElements(type, input, size);
404 break;
405 }
406}
407
408
409template <typename Protocols, typename T, typename Reader>
410typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type> >::type
411inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
412{
413 switch (type)
414 {
415 case bond::BT_INT8:
416 return DeserializeElementsChecked<Protocols, T, int8_t, Reader>(var, input, size);
417
418 case bond::BT_INT16:
419 return DeserializeElementsChecked<Protocols, T, int16_t, Reader>(var, input, size);
420
421 case bond::BT_INT32:
422 return DeserializeElementsChecked<Protocols, T, int32_t, Reader>(var, input, size);
423
424 case bond::BT_INT64:
425 return DeserializeElementsChecked<Protocols, T, int64_t, Reader>(var, input, size);
426
427 default:
428 BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
429
430 SkipElements(type, input, size);
431 break;
432 }
433}
434
435
436// MatchingMapByKey function are manually expended versions of MapByKey using the type
437// information about destination container. This helps with compilation speed.
438
439template <typename E, typename Reader>
440inline void SkipElements(BondDataType keyType, const E& element, Reader& input, uint32_t size)
441{
442 while (size--)
443 {
444 input.Skip(keyType);
445 element.Skip();
446 }
447}
448
449template <typename Protocols, typename T, typename E, typename Reader>
450typename boost::enable_if<is_type_alias<typename element_type<T>::type::first_type> >::type
451inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
452{
453 if (keyType == get_type_id<typename element_type<T>::type::first_type>::value)
454 {
455 return DeserializeMapElements<Protocols>(var, value<typename element_type<T>::type::first_type, Reader&>(input, false), element, size);
456 }
457 else
458 {
459 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
460
461 SkipElements(keyType, element, input, size);
462 }
463}
464
465
466template <typename Protocols, typename T, typename E, typename Reader>
467typename boost::enable_if<std::is_same<bool, typename element_type<T>::type::first_type> >::type
468inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
469{
470 switch (keyType)
471 {
472 case bond::BT_BOOL:
473 return DeserializeMapElements<Protocols>(var, value<bool, Reader&>(input, false), element, size);
474
475 default:
476 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
477
478 SkipElements(keyType, element, input, size);
479 break;
480 }
481}
482
483
484template <typename Protocols, typename T, typename E, typename Reader>
485typename boost::enable_if<is_string<typename element_type<T>::type::first_type> >::type
486inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
487{
488 switch (keyType)
489 {
490 case bond::BT_STRING:
491 return DeserializeMapElements<Protocols>(var, value<std::string, Reader&>(input, false), element, size);
492
493 default:
494 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
495
496 SkipElements(keyType, element, input, size);
497 break;
498 }
499}
500
501
502template <typename Protocols, typename T, typename E, typename Reader>
503typename boost::enable_if<is_wstring<typename element_type<T>::type::first_type> >::type
504inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
505{
506 switch (keyType)
507 {
508 case bond::BT_WSTRING:
509 return DeserializeMapElements<Protocols>(var, value<std::wstring, Reader&>(input, false), element, size);
510
511 default:
512 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
513
514 SkipElements(keyType, element, input, size);
515 break;
516 }
517}
518
519
520template <typename Protocols, typename T, typename E, typename Reader>
521typename boost::enable_if<std::is_floating_point<typename element_type<T>::type::first_type> >::type
522inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
523{
524 switch (keyType)
525 {
526 case bond::BT_FLOAT:
527 return DeserializeMapElements<Protocols>(var, value<float, Reader&>(input, false), element, size);
528
529 case bond::BT_DOUBLE:
530 return DeserializeMapElements<Protocols>(var, value<double, Reader&>(input, false), element, size);
531
532 default:
533 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
534
535 SkipElements(keyType, element, input, size);
536 break;
537 }
538}
539
540
541template <typename Protocols, typename T, typename E, typename Reader>
542typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type::first_type> >::type
543inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
544{
545 switch (keyType)
546 {
547 case bond::BT_UINT8:
548 return DeserializeMapElements<Protocols>(var, value<uint8_t, Reader&>(input, false), element, size);
549
550 case bond::BT_UINT16:
551 return DeserializeMapElements<Protocols>(var, value<uint16_t, Reader&>(input, false), element, size);
552
553 case bond::BT_UINT32:
554 return DeserializeMapElements<Protocols>(var, value<uint32_t, Reader&>(input, false), element, size);
555
556 case bond::BT_UINT64:
557 return DeserializeMapElements<Protocols>(var, value<uint64_t, Reader&>(input, false), element, size);
558
559 default:
560 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
561
562 SkipElements(keyType, element, input, size);
563 break;
564 }
565}
566
567
568template <typename Protocols, typename T, typename E, typename Reader>
569typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type::first_type> >::type
570inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
571{
572 switch (keyType)
573 {
574 case bond::BT_INT8:
575 return DeserializeMapElements<Protocols>(var, value<int8_t, Reader&>(input, false), element, size);
576
577 case bond::BT_INT16:
578 return DeserializeMapElements<Protocols>(var, value<int16_t, Reader&>(input, false), element, size);
579
580 case bond::BT_INT32:
581 return DeserializeMapElements<Protocols>(var, value<int32_t, Reader&>(input, false), element, size);
582
583 case bond::BT_INT64:
584 return DeserializeMapElements<Protocols>(var, value<int64_t, Reader&>(input, false), element, size);
585
586 default:
587 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
588
589 SkipElements(keyType, element, input, size);
590 break;
591 }
592}
593
594
595
596template <typename Protocols, typename T, typename E, typename Reader>
597typename boost::disable_if<is_map_container<T> >::type
598inline MapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
599{
600 switch (keyType)
601 {
602 case bond::BT_BOOL:
603 return DeserializeMapElements<Protocols>(var, value<bool, Reader&>(input, false), element, size);
604
605 case bond::BT_UINT8:
606 return DeserializeMapElements<Protocols>(var, value<uint8_t, Reader&>(input, false), element, size);
607
608 case bond::BT_UINT16:
609 return DeserializeMapElements<Protocols>(var, value<uint16_t, Reader&>(input, false), element, size);
610
611 case bond::BT_UINT32:
612 return DeserializeMapElements<Protocols>(var, value<uint32_t, Reader&>(input, false), element, size);
613
614 case bond::BT_UINT64:
615 return DeserializeMapElements<Protocols>(var, value<uint64_t, Reader&>(input, false), element, size);
616
617 case bond::BT_FLOAT:
618 return DeserializeMapElements<Protocols>(var, value<float, Reader&>(input, false), element, size);
619
620 case bond::BT_DOUBLE:
621 return DeserializeMapElements<Protocols>(var, value<double, Reader&>(input, false), element, size);
622
623 case bond::BT_STRING:
624 return DeserializeMapElements<Protocols>(var, value<std::string, Reader&>(input, false), element, size);
625
626 case bond::BT_WSTRING:
627 return DeserializeMapElements<Protocols>(var, value<std::wstring, Reader&>(input, false), element, size);
628
629 case bond::BT_INT8:
630 return DeserializeMapElements<Protocols>(var, value<int8_t, Reader&>(input, false), element, size);
631
632 case bond::BT_INT16:
633 return DeserializeMapElements<Protocols>(var, value<int16_t, Reader&>(input, false), element, size);
634
635 case bond::BT_INT32:
636 return DeserializeMapElements<Protocols>(var, value<int32_t, Reader&>(input, false), element, size);
637
638 case bond::BT_INT64:
639 return DeserializeMapElements<Protocols>(var, value<int64_t, Reader&>(input, false), element, size);
640
641 default:
642 BOOST_ASSERT(false);
643 return;
644 }
645}
646
647
648template <typename Protocols, typename T, typename E, typename Reader>
649typename boost::enable_if<is_map_element_matching<E, T> >::type
650inline MapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
651{
652 return MatchingMapByKey<Protocols>(var, keyType, element, input, size);
653}
654
655
656template <typename Protocols, typename T, typename E, typename Reader>
657typename boost::disable_if_c<!is_map_container<T>::value || is_map_element_matching<E, T>::value>::type
658inline MapByKey(T&, BondDataType keyType, const E& element, Reader& input, uint32_t size)
659{
660 while (size--)
661 {
662 input.Skip(keyType);
663 element.Skip();
664 }
665}
666
667
668template <typename Protocols, typename T, typename Reader>
669inline void MapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
670{
671 switch (elementType)
672 {
673 case bond::BT_BOOL:
674 return MapByKey<Protocols>(var, keyType, value<bool, Reader&>(input, false), input, size);
675
676 case bond::BT_UINT8:
677 return MapByKey<Protocols>(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
678
679 case bond::BT_UINT16:
680 return MapByKey<Protocols>(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
681
682 case bond::BT_UINT32:
683 return MapByKey<Protocols>(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
684
685 case bond::BT_UINT64:
686 return MapByKey<Protocols>(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
687
688 case bond::BT_FLOAT:
689 return MapByKey<Protocols>(var, keyType, value<float, Reader&>(input, false), input, size);
690
691 case bond::BT_DOUBLE:
692 return MapByKey<Protocols>(var, keyType, value<double, Reader&>(input, false), input, size);
693
694 case bond::BT_STRING:
695 return MapByKey<Protocols>(var, keyType, value<std::string, Reader&>(input, false), input, size);
696
697 case bond::BT_WSTRING:
698 return MapByKey<Protocols>(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
699
700 case bond::BT_INT8:
701 return MapByKey<Protocols>(var, keyType, value<int8_t, Reader&>(input, false), input, size);
702
703 case bond::BT_INT16:
704 return MapByKey<Protocols>(var, keyType, value<int16_t, Reader&>(input, false), input, size);
705
706 case bond::BT_INT32:
707 return MapByKey<Protocols>(var, keyType, value<int32_t, Reader&>(input, false), input, size);
708
709 case bond::BT_INT64:
710 return MapByKey<Protocols>(var, keyType, value<int64_t, Reader&>(input, false), input, size);
711
712 default:
713 BOOST_ASSERT(false);
714 break;
715 }
716}
717
718
719// MatchingMapByElement function are manually expended versions of MapByElement using
720// the type information about destination container. This helps with compilation speed.
721
722template <typename Reader>
723inline void SkipElements(BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
724{
725 while (size--)
726 {
727 input.Skip(keyType);
728 input.Skip(elementType);
729 }
730}
731
732template <typename Protocols, typename T, typename Reader>
733typename boost::enable_if<is_type_alias<typename element_type<T>::type::second_type> >::type
734inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
735{
736 if (elementType == get_type_id<typename element_type<T>::type::second_type>::value)
737 {
738 MapByKey<Protocols>(var, keyType, value<typename element_type<T>::type::second_type, Reader&>(input, false), input, size);
739 }
740 else
741 {
742 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
743
744 SkipElements(keyType, elementType, input, size);
745 }
746}
747
748
749template <typename Protocols, typename T, typename Reader>
750typename boost::enable_if<std::is_same<bool, typename element_type<T>::type::second_type> >::type
751inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
752{
753 switch (elementType)
754 {
755 case bond::BT_BOOL:
756 return MapByKey<Protocols>(var, keyType, value<bool, Reader&>(input, false), input, size);
757
758 default:
759 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
760
761 SkipElements(keyType, elementType, input, size);
762 break;
763 }
764}
765
766
767template <typename Protocols, typename T, typename Reader>
768typename boost::enable_if<is_string<typename element_type<T>::type::second_type> >::type
769inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
770{
771 switch (elementType)
772 {
773 case bond::BT_STRING:
774 return MapByKey<Protocols>(var, keyType, value<std::string, Reader&>(input, false), input, size);
775
776 default:
777 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
778
779 SkipElements(keyType, elementType, input, size);
780 break;
781 }
782}
783
784
785template <typename Protocols, typename T, typename Reader>
786typename boost::enable_if<is_wstring<typename element_type<T>::type::second_type> >::type
787inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
788{
789 switch (elementType)
790 {
791 case bond::BT_WSTRING:
792 return MapByKey<Protocols>(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
793
794 default:
795 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
796
797 SkipElements(keyType, elementType, input, size);
798 break;
799 }
800}
801
802
803template <typename Protocols, typename T, typename Reader>
804typename boost::enable_if<std::is_floating_point<typename element_type<T>::type::second_type> >::type
805inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
806{
807 switch (elementType)
808 {
809 case bond::BT_FLOAT:
810 return MapByKey<Protocols>(var, keyType, value<float, Reader&>(input, false), input, size);
811
812 case bond::BT_DOUBLE:
813 return MapByKey<Protocols>(var, keyType, value<double, Reader&>(input, false), input, size);
814
815 default:
816 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
817
818 SkipElements(keyType, elementType, input, size);
819 break;
820 }
821}
822
823
824template <typename Protocols, typename T, typename Reader>
825typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type::second_type> >::type
826inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
827{
828 switch (elementType)
829 {
830 case bond::BT_UINT8:
831 return MapByKey<Protocols>(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
832
833 case bond::BT_UINT16:
834 return MapByKey<Protocols>(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
835
836 case bond::BT_UINT32:
837 return MapByKey<Protocols>(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
838
839 case bond::BT_UINT64:
840 return MapByKey<Protocols>(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
841
842 default:
843 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
844
845 SkipElements(keyType, elementType, input, size);
846 break;
847 }
848}
849
850
851template <typename Protocols, typename T, typename Reader>
852typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type::second_type> >::type
853inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
854{
855 switch (elementType)
856 {
857 case bond::BT_INT8:
858 return MapByKey<Protocols>(var, keyType, value<int8_t, Reader&>(input, false), input, size);
859
860 case bond::BT_INT16:
861 return MapByKey<Protocols>(var, keyType, value<int16_t, Reader&>(input, false), input, size);
862
863 case bond::BT_INT32:
864 return MapByKey<Protocols>(var, keyType, value<int32_t, Reader&>(input, false), input, size);
865
866 case bond::BT_INT64:
867 return MapByKey<Protocols>(var, keyType, value<int64_t, Reader&>(input, false), input, size);
868
869 default:
870 BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
871
872 SkipElements(keyType, elementType, input, size);
873 break;
874 }
875}
876
877
878} // namespace detail
879
880} // namespace bond
881
882
883#ifdef BOND_LIB_TYPE
884#if BOND_LIB_TYPE != BOND_LIB_TYPE_HEADER
885#include "typeid_value_extern.h"
886#endif
887#else
888#error BOND_LIB_TYPE is undefined
889#endif
Memory blob.
Definition blob.h:24
namespace bond
Definition apply.h:17