6#include <bond/core/config.h>
11#include "detail/typeid_value.h"
13#include <boost/static_assert.hpp>
21template <
typename X,
typename T>
22typename boost::disable_if<is_type_alias<X> >::type
23inline set(X& var,
const T& value)
25 BOOST_STATIC_ASSERT((is_matching_basic<T, X>::value));
26 var =
static_cast<X
>(value);
30template <
typename X,
typename T>
31typename boost::enable_if<is_type_alias<X> >::type
32inline set(X& var,
const T& value)
34 BOOST_STATIC_ASSERT((is_matching_basic<T, X>::value));
35 set_aliased_value(var, value);
42template <
typename X,
typename T>
43inline X cast(
const T& value)
46 detail::set(x, value);
52template <
typename T,
typename Reader>
53typename boost::enable_if<is_basic_type<T> >::type
54inline Skip(Reader& input)
56 input.template Skip<T>();
61template <
typename T,
typename Reader>
62typename boost::enable_if<is_bond_type<T> >::type
63inline Skip(Reader& input)
65 bonded<T, Reader&>(input).Skip();
70template <
typename T,
typename Reader>
71typename boost::enable_if_c<is_container<T>::value &&
72 uses_static_parser<Reader>::value>::type
73inline Skip(Reader& input)
75 SkipContainer(value<
typename element_type<T>::type, Reader&>(input,
false), input);
80template <
typename Reader>
81typename boost::enable_if<uses_static_parser<Reader> >::type
82inline Skip(Reader& input,
const RuntimeSchema& schema)
84 switch (schema.GetTypeId())
90 value<void, Reader&>(input, element_schema(schema),
false), input);
94 return SkipMap(key_schema(schema).GetTypeId(),
95 value<void, Reader&>(input, element_schema(schema),
false), input);
99 return bonded<void, Reader&>(input, schema).Skip();
103 return input.Skip(schema.GetTypeId());
108template <
typename Reader>
109typename boost::enable_if<uses_static_parser<Reader> >::type
110inline Skip(Reader&, BondDataType)
117template <
typename T,
typename Reader>
118typename boost::enable_if_c<is_container<T>::value &&
119 !uses_static_parser<Reader>::value>::type
120inline Skip(Reader& input)
124 input.template Skip<T>();
129template <
typename Reader>
130typename boost::disable_if<uses_static_parser<Reader> >::type
131inline Skip(Reader& input,
const RuntimeSchema& schema)
133 input.Skip(schema.GetTypeId());
136template <
typename Reader>
137typename boost::disable_if<uses_static_parser<Reader> >::type
138inline Skip(Reader& input, BondDataType type)
144template <
typename T,
typename Reader>
145BOND_NO_INLINE
void Skip(Reader& input,
const std::nothrow_t&) BOND_NOEXCEPT
155template <
typename T,
typename Reader = SchemaReader,
typename boost::enable_if<std::is_same<Reader, SchemaReader> >::type* =
nullptr>
156void Skip(SchemaReader&,
const std::nothrow_t&) BOND_NOEXCEPT
159template <
typename Reader>
160BOND_NO_INLINE
void Skip(Reader& input,
const RuntimeSchema& schema,
const std::nothrow_t&) BOND_NOEXCEPT
170inline void Skip(SchemaReader&,
const RuntimeSchema&,
const std::nothrow_t&) BOND_NOEXCEPT
173template <
typename Reader>
174BOND_NO_INLINE
void Skip(Reader& input, BondDataType type,
const std::nothrow_t&) BOND_NOEXCEPT
184inline void Skip(SchemaReader&, BondDataType,
const std::nothrow_t&) BOND_NOEXCEPT
189template <
typename T,
typename Reader>
191 : detail::nonassignable
194 value_common(Reader input,
bool skip)
199 value_common(value_common&& rhs) BOND_NOEXCEPT_IF(
200 BOND_NOEXCEPT_EXPR(detail::move_data<Reader>(rhs._input)))
201 : _input(detail::move_data<Reader>(rhs._input)),
202 _skip(
std::move(rhs._skip))
207 value_common(
const value_common& that) =
default;
208 value_common& operator=(
const value_common& that) =
default;
214 bond::Skip<T, typename std::remove_reference<Reader>::type>(_input, std::nothrow);
220 bond::Skip<T, typename std::remove_reference<Reader>::type>(_input);
224 template <
typename Protocols = BuiltInProtocols,
typename X>
225 void Deserialize(X& ,
typename boost::disable_if<is_matching<T, X> >::type* =
nullptr)
const
239template <
typename T,
typename Reader>
240class value<T, Reader, typename boost::enable_if_c<is_basic_type<T>::value && !is_type_alias<T>::value>::type>
241 :
public value_common<T, Reader>
244 value(Reader input,
bool skip =
true)
245 : value_common<T, Reader>(input, skip)
248 value(value&& rhs) BOND_NOEXCEPT_IF((
249 std::is_nothrow_move_constructible<value_common<T, Reader> >::value))
250 : value_common<T, Reader>(std::move(rhs))
253 value(
const value& that) =
default;
254 value& operator=(
const value& that) =
default;
257 template <
typename Protocols = BuiltInProtocols>
266 template <
typename Protocols = BuiltInProtocols>
269 BOOST_STATIC_ASSERT((std::is_same<T, blob::value_type>::value));
271 _input.Read(var, size);
276 template <
typename Protocols = BuiltInProtocols,
typename X>
277 typename boost::enable_if_c<is_matching_basic<T, X>::value && !is_string_type<T>::value>::type
280 typename std::conditional<std::is_enum<X>::value &&
sizeof(X) ==
sizeof(T), X, T>::type data;
284 detail::set(var, data);
289 template <
typename Protocols = BuiltInProtocols,
typename X>
290 typename boost::enable_if_c<is_matching_basic<T, X>::value && is_string_type<T>::value>::type
301 using value_common<T, Reader>::_input;
302 using value_common<T, Reader>::_skip;
307template <
typename T,
typename Reader>
308class value<T, Reader, typename boost::enable_if<is_type_alias<T> >::type>
309 :
public value_common<T, Reader>
312 value(Reader input,
bool skip =
true)
313 : value_common<T, Reader>(input, skip)
316 value(value&& rhs) BOND_NOEXCEPT_IF((
317 std::is_nothrow_move_constructible<value_common<T, Reader> >::value))
318 : value_common<T, Reader>(
std::move(rhs))
321 value(
const value& that) =
default;
322 value& operator=(
const value& that) =
default;
324 template <
typename Protocols = BuiltInProtocols>
327 typename aliased_type<T>::type value;
330 set_aliased_value(var, value);
334 using value_common<T, Reader>::_skip;
335 using value_common<T, Reader>::_input;
340template <
typename T,
typename Reader>
341class value<T, Reader, typename boost::enable_if<is_bond_type<T> >::type>
342 :
public value_common<T, Reader>
345 value(Reader input,
bool skip =
true)
346 : value_common<T, Reader>(input, skip)
349 value(value&& rhs) BOND_NOEXCEPT_IF((
350 std::is_nothrow_move_constructible<value_common<T, Reader> >::value))
351 : value_common<T, Reader>(
std::move(rhs))
354 value(
const value& that) =
default;
355 value& operator=(
const value& that) =
default;
358 template <
typename Protocols = BuiltInProtocols,
typename X>
359 typename boost::enable_if<is_bond_type<X> >::type
363 bonded<T, Reader>(_input).template Deserialize<Protocols>(var);
367 template <
typename Protocols = BuiltInProtocols,
typename Transform>
368 void _Apply(
const Transform& transform)
const
371 Apply<Protocols>(transform, bonded<T, Reader>(_input));
376 using value_common<T, Reader>::_skip;
377 using value_common<T, Reader>::_input;
382template <
typename T1,
typename T2,
typename Reader>
383class value<
std::pair<T1, T2>, Reader>
386 value(Reader ,
bool skip =
true)
393template <
typename Protocols,
typename X,
typename T1,
typename T2,
typename Reader>
394inline void DeserializeContainer(X& var,
const value<std::pair<T1, T2>, Reader&>&, Reader& input);
396template <
typename Protocols,
typename X,
typename T,
typename Reader>
397typename boost::disable_if<is_container<X> >::type
398inline DeserializeContainer(X& var,
const T& element, Reader& input);
400template <
typename Protocols,
typename X,
typename T,
typename Reader>
401typename boost::enable_if<is_nested_container<X> >::type
402inline DeserializeContainer(X& var,
const T& element, Reader& input);
404template <
typename Protocols,
typename X,
typename T,
typename Reader>
405typename boost::enable_if<is_basic_container<X> >::type
406inline DeserializeContainer(X& var,
const T& element, Reader& input);
408template <
typename Protocols,
typename Transform,
typename T>
409void DeserializeContainer(
const Transform& transform,
const value<T, SchemaReader&>& element, SchemaReader&)
411 transform.Container(element, 0);
414template <
typename Protocols,
typename Transform,
typename T1,
typename T2>
415void DeserializeContainer(
const Transform& transform,
const value<std::pair<T1, T2>, SchemaReader&>&, SchemaReader& input)
417 transform.Container(value<T1, SchemaReader&>{ input,
false }, value<T2, SchemaReader&>{ input,
false }, 0);
420template <
typename Protocols,
typename Transform>
421void DeserializeContainer(
const Transform& transform,
const value<void, SchemaReader&>& element, SchemaReader& input);
425template <
typename T,
typename Reader>
426class value<T, Reader, typename boost::enable_if<is_container<T> >::type>
427 :
public value_common<T, Reader>
430 value(Reader input,
bool skip =
true)
431 : value_common<T, Reader>(input, skip)
434 value(value&& rhs) BOND_NOEXCEPT_IF((
435 std::is_nothrow_move_constructible<value_common<T, Reader> >::value))
436 : value_common<T, Reader>(
std::move(rhs))
439 value(
const value& that) =
default;
440 value& operator=(
const value& that) =
default;
443 template <
typename Protocols = BuiltInProtocols,
typename X>
444 typename boost::enable_if_c<is_matching_container<T, X>::value>::type
448 DeserializeContainer<Protocols>(var, value<
typename element_type<T>::type, Reader>(_input,
false), _input);
452 template <
typename Protocols = BuiltInProtocols,
typename Transform>
453 void _Apply(
const Transform& transform)
const
456 DeserializeContainer<Protocols>(transform, value<
typename element_type<T>::type, Reader>(_input,
false), _input);
463 using value_common<T, Reader>::_input;
464 using value_common<T, Reader>::_skip;
468template <
typename Protocols,
typename X,
typename T,
typename Reader>
469typename boost::disable_if<is_container<X> >::type
470inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input);
472template <
typename Protocols,
typename X,
typename T,
typename Reader>
473typename boost::enable_if<is_nested_container<X> >::type
474inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input);
476template <
typename Protocols,
typename X,
typename T,
typename Reader>
477typename boost::enable_if<is_basic_container<X> >::type
478inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input);
480template <
typename Protocols,
typename Transform>
481void DeserializeMap(
const Transform& transform, BondDataType keyType,
const value<void, SchemaReader&>& element, SchemaReader& input);
485template <
typename Reader>
486class value<void, Reader>
487 : detail::nonassignable
490 value(Reader input,
const RuntimeSchema& schema,
bool skip =
true)
496 value(Reader input, BondDataType type,
bool skip =
true)
501 _schemaDef.root.id = type;
504 value(value&& rhs) BOND_NOEXCEPT_IF(
505 BOND_NOEXCEPT_EXPR(detail::move_data<Reader>(rhs._input))
506 && std::is_nothrow_move_constructible<SchemaDef>::value
507 && std::is_nothrow_move_constructible<RuntimeSchema>::value)
508 : _input(detail::move_data<Reader>(rhs._input)),
509 _schemaDef(
std::move(rhs._schemaDef)),
510 _schema(
std::move(rhs._schema)),
511 _skip(
std::move(rhs._skip))
516 value(
const value& that) =
default;
517 value& operator=(
const value& that) =
default;
523 bond::Skip(_input, _schema, std::nothrow);
529 bond::Skip(_input, _schema);
534 template <
typename Protocols = BuiltInProtocols,
typename X>
535 typename boost::enable_if_c<is_container<X>::value && !is_map_container<X>::value>::type
538 if (_schema.GetTypeId() == get_type_id<X>::value)
541 DeserializeContainer<Protocols>(var,
542 value<void, Reader>(_input, element_schema(_schema),
false), _input);
552 template <
typename Protocols = BuiltInProtocols,
typename X>
553 typename boost::enable_if<is_map_container<X> >::type
556 if (_schema.GetTypeId() == get_type_id<X>::value)
559 DeserializeMap<Protocols>(var, key_schema(_schema).GetTypeId(),
560 value<void, Reader>(_input, element_schema(_schema),
false), _input);
570 template <
typename Protocols = BuiltInProtocols,
typename X>
571 typename boost::enable_if<is_bond_type<X> >::type
574 if (_schema.GetTypeId() == get_type_id<X>::value)
577 bonded<void, Reader>(_input, _schema).template Deserialize<Protocols>(var);
586 template <
typename Protocols = BuiltInProtocols,
typename Transform>
587 void _Apply(
const Transform& transform)
const
591 if (_schema.GetTypeId() == bond::BT_STRUCT)
593 Apply<Protocols>(transform, bonded<void, Reader>(_input, _schema));
595 else if(_schema.GetTypeId() == bond::BT_MAP)
597 DeserializeMap<Protocols>(transform, key_schema(_schema).GetTypeId(),
598 value<void, Reader>(_input, element_schema(_schema),
false), _input);
602 BOOST_ASSERT(_schema.GetTypeId() == bond::BT_LIST || _schema.GetTypeId() == bond::BT_SET);
604 DeserializeContainer<Protocols>(transform,
605 value<void, Reader>(_input, element_schema(_schema),
false), _input);
611 template <
typename Protocols = BuiltInProtocols,
typename X>
612 typename boost::disable_if_c<is_container<X>::value || is_bond_type<X>::value>::type
619 BondDataType GetTypeId()
const
621 return _schema.GetTypeId();
632 SchemaDef _schemaDef;
633 RuntimeSchema _schema;
638template <
typename Protocols,
typename Transform>
639void DeserializeContainer(
const Transform& transform,
const value<void, SchemaReader&>& element, SchemaReader& input)
641 switch (element.GetTypeId())
646 case bond::BT_STRUCT:
647 transform.Container(element, 0);
650 detail::BasicTypeContainer<Protocols>(transform, element.GetTypeId(), input, 0);
656template <
typename Protocols,
typename X,
typename I,
typename T>
657typename boost::enable_if<require_modify_element<X> >::type
658inline DeserializeElement(X& var,
const I& item,
const T& element)
660 struct DeserializeImpl
662 DeserializeImpl(
const T& element)
666 void operator()(
typename element_type<X>::type& e)
668 this->element.template Deserialize<Protocols>(e);
674 modify_element(var, item, DeserializeImpl(element));
678template <
typename Protocols,
typename X,
typename I,
typename T>
679typename boost::disable_if<require_modify_element<X> >::type
680inline DeserializeElement(X&, I& item,
const T& element)
682 element.template Deserialize<Protocols>(item);
687template <
typename Protocols,
typename X,
typename T>
688typename boost::enable_if_c<is_list_container<X>::value
689 && is_element_matching<T, X>::value>::type
690inline DeserializeElements(X& var,
const T& element, uint32_t size)
692 resize_list(var, size);
694 for (enumerator<X> items(var); items.more();)
695 DeserializeElement<Protocols>(var, items.next(), element);
699template <
typename Protocols,
typename X,
typename T>
700typename boost::enable_if<is_matching<T, X> >::type
701inline DeserializeElements(nullable<X>& var,
const T& element, uint32_t size)
703 resize_list(var, size);
705 for (enumerator<nullable<X> > items(var); items.more(); --size)
706 element.template Deserialize<Protocols>(items.next());
711 detail::SkipElements(element, size);
715template <
typename Protocols,
typename Reader>
716inline void DeserializeElements(blob& var,
const value<blob::value_type, Reader&>& element, uint32_t size)
718 element.template Deserialize<Protocols>(var, size);
722template <
typename Protocols,
typename X,
typename T>
723typename boost::enable_if_c<is_set_container<X>::value
724 && is_element_matching<T, X>::value>::type
725inline DeserializeElements(X& var,
const T& element, uint32_t size)
729 typename element_type<X>::type e(make_element(var));
733 element.template Deserialize<Protocols>(e);
739template <
typename Protocols,
typename X,
typename T>
740typename boost::disable_if<is_element_matching<T, X> >::type
741inline DeserializeElements(X&,
const T& element, uint32_t size)
743 detail::SkipElements(element, size);
747template <
typename Protocols,
typename Transform,
typename T>
748inline void DeserializeElements(
const Transform& transform,
const T& element, uint32_t size)
750 transform.Container(element, size);
754template <
typename T1,
typename T2,
typename Reader>
755inline void SkipContainer(
const value<std::pair<T1, T2>, Reader&>&, Reader& input)
757 BOOST_STATIC_ASSERT(uses_static_parser<Reader>::value);
759 SkipMap(get_type_id<T1>::value, value<T2, Reader&>(input,
false), input);
763template <
typename T,
typename Reader>
764inline void SkipContainer(
const T& element, Reader& input)
766 BOOST_STATIC_ASSERT(uses_static_parser<Reader>::value);
772 input.ReadContainerBegin(size, type);
775 detail::SkipElements(element, size);
777 input.ReadContainerEnd();
781template <
typename Protocols,
typename X,
typename T1,
typename T2,
typename Reader>
782inline void DeserializeContainer(X& var,
const value<std::pair<T1, T2>, Reader&>&, Reader& input)
784 return DeserializeMap<Protocols>(var, get_type_id<T1>::value, value<T2, Reader&>(input,
false), input);
788template <
typename Protocols,
typename X,
typename T,
typename Reader>
789typename boost::disable_if<is_container<X> >::type
790inline DeserializeContainer(X& var,
const T& element, Reader& input)
792 BondDataType type = GetTypeId(element);
795 input.ReadContainerBegin(size, type);
802 case bond::BT_STRUCT:
804 if (type == GetTypeId(element))
806 DeserializeElements<Protocols>(var, element, size);
810 DeserializeElements<Protocols>(var, value<void, Reader&>(input, type,
false), size);
816 detail::BasicTypeContainer<Protocols>(var, type, input, size);
821 input.ReadContainerEnd();
825template <
typename Protocols,
typename X,
typename T,
typename Reader>
826typename boost::enable_if<is_nested_container<X> >::type
827inline DeserializeContainer(X& var,
const T& element, Reader& input)
829 BondDataType type = GetTypeId(element);
832 input.ReadContainerBegin(size, type);
834 if (type == GetTypeId(element))
836 DeserializeElements<Protocols>(var, element, size);
840 detail::SkipElements(type, input, size);
843 input.ReadContainerEnd();
847template <
typename Protocols,
typename X,
typename T,
typename Reader>
848typename boost::enable_if<is_basic_container<X> >::type
849inline DeserializeContainer(X& var,
const T& element, Reader& input)
851 BondDataType type = GetTypeId(element);
854 input.ReadContainerBegin(size, type);
861 case bond::BT_STRUCT:
863 if (type == GetTypeId(element))
865 detail::SkipElements(element, size);
876 detail::MatchingTypeContainer<Protocols>(var, type, input, size);
881 input.ReadContainerEnd();
885template <
typename Protocols,
typename Transform>
886void DeserializeMap(
const Transform& transform, BondDataType keyType,
const value<void, SchemaReader&>& element, SchemaReader& input)
888 switch (element.GetTypeId())
893 case bond::BT_STRUCT:
894 detail::MapByKey<Protocols>(transform, keyType, element, input, 0);
897 detail::MapByElement<Protocols>(transform, keyType, element.GetTypeId(), input, 0);
903template <
typename Protocols,
typename X,
typename Key,
typename T>
904typename boost::enable_if<is_map_key_matching<Key, X> >::type
905inline DeserializeMapElements(X& var,
const Key& key,
const T& element, uint32_t size)
907 BOOST_STATIC_ASSERT((is_map_element_matching<T, X>::value));
911 typename element_type<X>::type::first_type k(make_key(var));
915 key.template Deserialize<Protocols>(k);
921 element.template Deserialize<Protocols>(mapped_at(var, k) = make_value(var));
923 element.template Deserialize<Protocols>(mapped_at(var, k));
929template <
typename Protocols,
typename X,
typename Key,
typename T>
930typename boost::disable_if<is_map_key_matching<Key, X> >::type
931inline DeserializeMapElements(X&,
const Key& key,
const T& element, uint32_t size)
941template <
typename Protocols,
typename Transform,
typename Key,
typename T>
942inline void DeserializeMapElements(
const Transform& transform,
const Key& key,
const T& element, uint32_t size)
944 transform.Container(key, element, size);
948template <
typename T,
typename Reader>
949inline void SkipMap(BondDataType keyType,
const T& element, Reader& input)
951 BOOST_STATIC_ASSERT(uses_static_parser<Reader>::value);
956 std::pair<BondDataType, BondDataType> type;
958 input.ReadContainerBegin(size, type);
961 detail::SkipElements(keyType, element, input, size);
963 input.ReadContainerEnd();
967template <
typename Protocols,
typename X,
typename T,
typename Reader>
968typename boost::disable_if<is_container<X> >::type
969inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input)
971 std::pair<BondDataType, BondDataType> type(keyType, GetTypeId(element));
974 input.ReadContainerBegin(size, type);
981 case bond::BT_STRUCT:
983 if (type.second == GetTypeId(element))
985 detail::MapByKey<Protocols>(var, type.first, element, input, size);
989 detail::MapByKey<Protocols>(var, type.first, value<void, Reader&>(input, type.second,
false), input, size);
995 detail::MapByElement<Protocols>(var, type.first, type.second, input, size);
1000 input.ReadContainerEnd();
1004template <
typename Protocols,
typename X,
typename T,
typename Reader>
1005typename boost::enable_if<is_nested_container<X> >::type
1006inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input)
1008 std::pair<BondDataType, BondDataType> type(keyType, GetTypeId(element));
1011 input.ReadContainerBegin(size, type);
1013 if (type.second == GetTypeId(element))
1015 detail::MapByKey<Protocols>(var, type.first, element, input, size);
1019 detail::SkipElements(type.first, type.second, input, size);
1022 input.ReadContainerEnd();
1026template <
typename Protocols,
typename X,
typename T,
typename Reader>
1027typename boost::enable_if<is_basic_container<X> >::type
1028inline DeserializeMap(X& var, BondDataType keyType,
const T& element, Reader& input)
1030 std::pair<BondDataType, BondDataType> type(keyType, GetTypeId(element));
1033 input.ReadContainerBegin(size, type);
1035 switch (type.second)
1040 case bond::BT_STRUCT:
1042 if (type.second == GetTypeId(element))
1044 detail::SkipElements(type.first, element, input, size);
1050 input.Skip(type.first);
1051 Skip(input, type.second);
1058 detail::MatchingMapByElement<Protocols>(var, type.first, type.second, input, size);
1063 input.ReadContainerEnd();
1071#if BOND_LIB_TYPE != BOND_LIB_TYPE_HEADER
1072#include "detail/value_extern.h"
1075#error BOND_LIB_TYPE is undefined
Memory blob.
Definition: blob.h:24
void Deserialize(T &var) const
Deserialize the value.
Definition: value.h:258
namespace bond
Definition: apply.h:17
RuntimeSchema GetRuntimeSchema()
Returns an instance of RuntimeSchema for a user defined struct.
Definition: schema.h:330
void Deserialize(Reader input, T &obj)
Deserialize an object from a protocol reader.
Definition: bond.h:27