[c++] Remove bond::customize<protocols>
`bond::customize<protocols>` has been removed. All the public APIs that require a protocol list (e.g. `bond::Marshal`) now accept an extra template argument `Protocols` which defaults to `bond::BuiltInProtocols`. Custom input streams now require `bond::type_id<>` to be specialized with a unique magic number. Closes https://github.com/Microsoft/bond/pull/425
This commit is contained in:
Родитель
e81d51b33b
Коммит
5454d52ea0
|
@ -53,6 +53,11 @@ different versioning scheme, following the Haskell community's
|
|||
and
|
||||
[the bf example](https://github.com/Microsoft/bond/commit/11beaf5319639e4bdee96a25f95154e4fed93a75#diff-bdda0f39d99280d4858b4453906eea17)
|
||||
for more details.
|
||||
* **Breaking change** The `bond::customize<protocols>` has been removed. All the
|
||||
public APIs that require a protocol list (e.g. `bond::Marshal`) now accept
|
||||
an extra template argument `Protocols` which defaults to `bond::BuiltInProtocols`.
|
||||
Custom input streams now require `bond::type_id<>` to be specialized with a
|
||||
unique magic number. For more details please see [the bf example](https://github.com/Microsoft/bond/tree/master/examples/cpp/core/bf).
|
||||
* Initial support for sending
|
||||
[Bond objects over gRPC](https://microsoft.github.io/bond/manual/bond_over_grpc.html)
|
||||
has been added.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <bond/core/traits.h>
|
||||
#include <bond/stream/output_buffer.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace bond { namespace comm
|
||||
|
|
|
@ -300,7 +300,7 @@ private:
|
|||
// FIXME - handle Unmarshal errors
|
||||
try
|
||||
{
|
||||
Unmarshal<Error, InputBuffer>(buffer, response.error);
|
||||
Unmarshal(buffer, response.error);
|
||||
}
|
||||
catch (const bond::Exception&)
|
||||
{
|
||||
|
|
|
@ -16,26 +16,26 @@ namespace detail
|
|||
{
|
||||
|
||||
/// @brief Apply transform to serialized struct wrapped in bonded<T>
|
||||
template <typename Transform, typename T, typename Reader>
|
||||
template <typename Protocols, typename Transform, typename T, typename Reader>
|
||||
typename boost::disable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const bonded<T, Reader>& bonded)
|
||||
{
|
||||
return bonded._Apply(transform);
|
||||
return bonded.template _Apply<Protocols>(transform);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Apply transform to serialized container wrapped in value<T, Reader>
|
||||
template <typename Transform, typename T, typename Reader>
|
||||
template <typename Protocols, typename Transform, typename T, typename Reader>
|
||||
bool inline
|
||||
ApplyTransform(const Transform& transform, const value<T, Reader>& value)
|
||||
{
|
||||
value._Apply(transform);
|
||||
value.template _Apply<Protocols>(transform);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Apply transform to an instance of a struct
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
typename boost::disable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const T& value)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ ApplyTransform(const Transform& transform, const T& value)
|
|||
|
||||
|
||||
/// @brief Apply transform which can modify an instance of a struct
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
typename boost::enable_if<is_modifying_transform<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, T& value)
|
||||
{
|
||||
|
@ -53,23 +53,23 @@ ApplyTransform(const Transform& transform, T& value)
|
|||
|
||||
|
||||
// Specializations for transform requiring double-pass
|
||||
template <typename Transform, typename T, typename Reader>
|
||||
template <typename Protocols, typename Transform, typename T, typename Reader>
|
||||
typename boost::enable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const bonded<T, Reader>& bonded)
|
||||
{
|
||||
if (transform.NeedPass0())
|
||||
return DoublePassApply(transform, bonded);
|
||||
return DoublePassApply<Protocols>(transform, bonded);
|
||||
else
|
||||
return bonded._Apply(transform);
|
||||
return bonded.template _Apply<Protocols>(transform);
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
typename boost::enable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const T& value)
|
||||
{
|
||||
if (transform.NeedPass0())
|
||||
return DoublePassApply(transform, value);
|
||||
return DoublePassApply<Protocols>(transform, value);
|
||||
else
|
||||
return StaticParser<const T&>(value).Apply(transform, typename schema<T>::type());
|
||||
}
|
||||
|
@ -77,16 +77,16 @@ ApplyTransform(const Transform& transform, const T& value)
|
|||
} // namespace detail
|
||||
|
||||
|
||||
template <typename Transform, typename T, typename boost::enable_if<is_modifying_transform<Transform> >::type* = nullptr>
|
||||
template <typename Protocols, typename Transform, typename T, typename boost::enable_if<is_modifying_transform<Transform> >::type*>
|
||||
bool Apply(const Transform& transform, T& value)
|
||||
{
|
||||
return detail::ApplyTransform(transform, value);
|
||||
return detail::ApplyTransform<Protocols>(transform, value);
|
||||
}
|
||||
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
bool Apply(const Transform& transform, const T& value)
|
||||
{
|
||||
return detail::ApplyTransform(transform, value);
|
||||
return detail::ApplyTransform<Protocols>(transform, value);
|
||||
}
|
||||
|
||||
} // namespace bond
|
||||
|
|
|
@ -13,116 +13,116 @@ namespace bond
|
|||
|
||||
/// @brief Serialize an object using a protocol writer
|
||||
///
|
||||
template <typename T, typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename T, typename Writer>
|
||||
inline void Serialize(const T& obj, Writer& output)
|
||||
{
|
||||
Apply(Serializer<Writer>(output), obj);
|
||||
Apply<Protocols>(Serializer<Writer, Protocols>(output), obj);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize an object from a protocol reader
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols = BuiltInProtocols, typename Reader, typename T>
|
||||
inline void Deserialize(Reader input, T& obj)
|
||||
{
|
||||
Apply(To<T>(obj), bonded<T, Reader&>(input));
|
||||
Apply<Protocols>(To<T, Protocols>(obj), bonded<T, Reader&>(input));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize an object of type T from a protocol reader
|
||||
template <typename T, typename Reader>
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Reader>
|
||||
inline T Deserialize(Reader input)
|
||||
{
|
||||
T tmp;
|
||||
Apply(To<T>(tmp), bonded<T, Reader&>(input));
|
||||
Apply<Protocols>(To<T, Protocols>(tmp), bonded<T, Reader&>(input));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize an object from a protocol reader using runtime schema
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols = BuiltInProtocols, typename Reader, typename T>
|
||||
inline void Deserialize(Reader input, T& obj, const RuntimeSchema& schema)
|
||||
{
|
||||
Apply(To<T>(obj), bonded<void, Reader&>(input, schema));
|
||||
Apply<Protocols>(To<T, Protocols>(obj), bonded<void, Reader&>(input, schema));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize an object of type T from a protocol reader using runtime schema
|
||||
template <typename T, typename Reader>
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Reader>
|
||||
inline T Deserialize(Reader input, const RuntimeSchema& schema)
|
||||
{
|
||||
T tmp;
|
||||
Apply(To<T>(tmp), bonded<void, Reader&>(input, schema));
|
||||
Apply<Protocols>(To<T, Protocols>(tmp), bonded<void, Reader&>(input, schema));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Marshal an object using a protocol writer
|
||||
template <typename T, typename Writer>
|
||||
template <typename Protocols, typename T, typename Writer>
|
||||
inline void Marshal(const T& obj, Writer& output)
|
||||
{
|
||||
Apply(Marshaler<Writer>(output), obj);
|
||||
Apply<Protocols>(Marshaler<Writer, Protocols>(output), obj);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Unmarshal an object from data stream
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Buffer, typename T>
|
||||
inline void Unmarshal(Buffer input, T& obj)
|
||||
{
|
||||
SelectProtocolAndApply<T>(input, To<T>(obj));
|
||||
SelectProtocolAndApply<T, Protocols>(input, To<T, Protocols>(obj));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Unmarshal an object of type T from data stream
|
||||
template <typename T, typename Buffer>
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Buffer>
|
||||
inline T Unmarshal(Buffer input)
|
||||
{
|
||||
T tmp;
|
||||
SelectProtocolAndApply<T>(input, To<T>(tmp));
|
||||
SelectProtocolAndApply<T, Protocols>(input, To<T, Protocols>(tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Initialize a bonded<T> from data stream contained marshaled object
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Buffer, typename T>
|
||||
inline void Unmarshal(Buffer input, bonded<T>& obj)
|
||||
{
|
||||
SelectProtocolAndApply<T>(input, boost::ref(obj));
|
||||
SelectProtocolAndApply<T, Protocols>(input, boost::ref(obj));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Unmarshal an object from data stream using a runtime schema
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Buffer, typename T>
|
||||
inline void Unmarshal(Buffer input, T& obj, const RuntimeSchema& schema)
|
||||
{
|
||||
SelectProtocolAndApply(schema, input, To<T>(obj));
|
||||
SelectProtocolAndApply<Protocols>(schema, input, To<T, Protocols>(obj));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Unmarshal an object of type T from data stream using a runtime schema
|
||||
template <typename T, typename Buffer>
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Buffer>
|
||||
inline T Unmarshal(Buffer input, const RuntimeSchema& schema)
|
||||
{
|
||||
T tmp;
|
||||
SelectProtocolAndApply(schema, input, To<T>(tmp));
|
||||
SelectProtocolAndApply<Protocols>(schema, input, To<T, Protocols>(tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Initialize a bonded<T> from data stream contained marshaled object
|
||||
/// using a runtime schema
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Buffer, typename T>
|
||||
inline void Unmarshal(Buffer input, bonded<T>& obj, const RuntimeSchema& schema)
|
||||
{
|
||||
SelectProtocolAndApply(schema, input, boost::ref(obj));
|
||||
SelectProtocolAndApply<Protocols>(schema, input, boost::ref(obj));
|
||||
}
|
||||
|
||||
|
||||
/// @brief Merge an object with serialize data and write the result using
|
||||
/// a protocol writer
|
||||
template <typename T, typename Reader, typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename T, typename Reader, typename Writer>
|
||||
inline void Merge(const T& obj, Reader input, Writer& output)
|
||||
{
|
||||
Apply(Merger<T, Writer>(obj, output), bonded<T>(input));
|
||||
Apply<Protocols>(Merger<T, Writer, Protocols>(obj, output), bonded<T>(input));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include <bond/core/bond_const_enum.h>
|
||||
#include "detail/tags.h"
|
||||
#include <stdint.h>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace bond
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ class blob;
|
|||
class InputBuffer;
|
||||
class RuntimeSchema;
|
||||
|
||||
struct ProtocolReader;
|
||||
class ProtocolReader;
|
||||
|
||||
template <typename T, typename Reader = ProtocolReader>
|
||||
class bonded;
|
||||
|
@ -43,7 +44,9 @@ class DOMParser;
|
|||
template <typename T>
|
||||
class RequiredFieldValiadator;
|
||||
|
||||
template <typename T, typename Validator = RequiredFieldValiadator<T> >
|
||||
struct BuiltInProtocols;
|
||||
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Validator = RequiredFieldValiadator<T> >
|
||||
class To;
|
||||
|
||||
template <typename T, typename Enable = void> struct
|
||||
|
@ -62,4 +65,26 @@ struct Metadata;
|
|||
|
||||
struct qualified_name_tag;
|
||||
|
||||
}
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform, typename T, typename boost::enable_if<is_modifying_transform<Transform> >::type* = nullptr>
|
||||
bool Apply(const Transform& transform, T& value);
|
||||
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform, typename T>
|
||||
bool Apply(const Transform& transform, const T& value);
|
||||
|
||||
template <typename Protocols = BuiltInProtocols, typename T, typename Writer>
|
||||
inline void Marshal(const T& obj, Writer& output);
|
||||
|
||||
template <typename Writer, typename Protocols = BuiltInProtocols>
|
||||
class Marshaler;
|
||||
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
Marshaler<Writer, Protocols> MarshalTo(Writer& output);
|
||||
|
||||
template <typename Writer, typename Protocols = BuiltInProtocols>
|
||||
class Serializer;
|
||||
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
Serializer<Writer, Protocols> SerializeTo(Writer& output);
|
||||
|
||||
} // bond
|
||||
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
|
||||
namespace bond
|
||||
{
|
||||
template <typename Buffer>
|
||||
class SimpleBinaryReader;
|
||||
template <typename... T>
|
||||
struct Protocols;
|
||||
|
||||
template <typename BufferT>
|
||||
class CompactBinaryReader;
|
||||
|
||||
template <typename BufferT, typename MarshaledBondedProtocolsT = Protocols<CompactBinaryReader<BufferT> > >
|
||||
class SimpleBinaryReader;
|
||||
|
||||
BOND_CONSTEXPR_OR_CONST uint16_t v1 = 0x0001;
|
||||
BOND_CONSTEXPR_OR_CONST uint16_t v2 = 0x0002;
|
||||
|
||||
|
|
|
@ -6,20 +6,22 @@
|
|||
#include "config.h"
|
||||
#include "protocol.h"
|
||||
#include "runtime_schema.h"
|
||||
#include "detail/protocol_visitors.h"
|
||||
#include "bond_fwd.h"
|
||||
#include "detail/double_pass.h"
|
||||
#include "detail/protocol_visitors.h"
|
||||
#include "detail/marshaled_bonded.h"
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Transform, typename T, typename Reader>
|
||||
template <typename Protocols, typename Transform, typename T, typename Reader>
|
||||
typename boost::disable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const bonded<T, Reader>& bonded);
|
||||
|
||||
template <typename Transform, typename T, typename Reader>
|
||||
template <typename Protocols, typename Transform, typename T, typename Reader>
|
||||
typename boost::enable_if<need_double_pass<Transform>, bool>::type inline
|
||||
ApplyTransform(const Transform& transform, const bonded<T, Reader>& bonded);
|
||||
|
||||
|
@ -33,7 +35,7 @@ is_marshaled_bonded
|
|||
&& is_bonded<T>::value> {};
|
||||
|
||||
|
||||
template <typename T, typename Buffer, typename Transform>
|
||||
template <typename T, typename Protocols, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> SelectProtocolAndApply(
|
||||
Buffer& input,
|
||||
const Transform& transform);
|
||||
|
@ -153,46 +155,38 @@ public:
|
|||
}
|
||||
|
||||
/// @brief Serialize bonded using specified protocol writer
|
||||
template <typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
void Serialize(Writer& output) const
|
||||
{
|
||||
Apply(SerializeTo(output), *this);
|
||||
}
|
||||
|
||||
/// @brief Deserialize an object of type T
|
||||
T Deserialize() const
|
||||
{
|
||||
T tmp;
|
||||
Apply(To<T>(tmp), *this);
|
||||
return tmp;
|
||||
Apply<Protocols>(SerializeTo<Protocols>(output), *this);
|
||||
}
|
||||
|
||||
/// @brief Deserialize an object of type X
|
||||
template <typename X>
|
||||
template <typename X = T, typename Protocols = BuiltInProtocols>
|
||||
X Deserialize() const
|
||||
{
|
||||
X tmp;
|
||||
Apply(To<X>(tmp), *this);
|
||||
Apply<Protocols>(To<X, Protocols>(tmp), *this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// @brief Deserialize to an object of type X
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
void Deserialize(X& var) const
|
||||
{
|
||||
Apply(To<X>(var), *this);
|
||||
Apply<Protocols>(To<X, Protocols>(var), *this);
|
||||
}
|
||||
|
||||
/// @brief Deserialize to a bonded<U>
|
||||
template <typename U>
|
||||
template <typename Protocols = BuiltInProtocols, typename U>
|
||||
typename boost::enable_if<is_marshaled_bonded<T, Reader, U> >::type
|
||||
Deserialize(bonded<U>& var) const
|
||||
{
|
||||
_SelectProtocolAndApply(boost::ref(var));
|
||||
_SelectProtocolAndApply<Protocols>(boost::ref(var));
|
||||
}
|
||||
|
||||
|
||||
template <typename U>
|
||||
template <typename Protocols = BuiltInProtocols, typename U>
|
||||
typename boost::disable_if<is_marshaled_bonded<T, Reader, U> >::type
|
||||
Deserialize(bonded<U>& var) const
|
||||
{
|
||||
|
@ -201,10 +195,10 @@ public:
|
|||
|
||||
|
||||
/// @brief Update bonded<T> payload by merging it with an object of type X
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
void Merge(const X& var)
|
||||
{
|
||||
detail::Merge(var, _data);
|
||||
detail::Merge<Protocols>(var, _data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,11 +220,11 @@ public:
|
|||
}
|
||||
|
||||
|
||||
template <typename Transform, typename U, typename ReaderT>
|
||||
template <typename Protocols, typename Transform, typename U, typename ReaderT>
|
||||
friend typename boost::disable_if<detail::need_double_pass<Transform>, bool>::type inline
|
||||
detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
|
||||
|
||||
template <typename Transform, typename U, typename ReaderT>
|
||||
template <typename Protocols, typename Transform, typename U, typename ReaderT>
|
||||
friend typename boost::enable_if<detail::need_double_pass<Transform>, bool>::type inline
|
||||
detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
|
||||
|
||||
|
@ -239,29 +233,29 @@ public:
|
|||
|
||||
private:
|
||||
// Apply transform to serialized data
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
typename boost::enable_if<is_marshaled_bonded<T, Reader, Transform>, bool>::type
|
||||
_Apply(const Transform& transform) const
|
||||
{
|
||||
return _SelectProtocolAndApply(transform);
|
||||
return _SelectProtocolAndApply<Protocols>(transform);
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
typename boost::disable_if<is_marshaled_bonded<T, Reader, Transform>, bool>::type
|
||||
_Apply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
return detail::Parse<T>(transform, _data, typename schema_for_passthrough<T>::type(), _schema.get(), _base);
|
||||
return detail::Parse<T, Protocols>(transform, _data, typename schema_for_passthrough<T>::type(), _schema.get(), _base);
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
bool _SelectProtocolAndApply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
auto input = CreateInputBuffer(_data.GetBuffer(), detail::ReadBlob(_data));
|
||||
return SelectProtocolAndApply<typename remove_bonded<T>::type>(input, transform).second;
|
||||
return SelectProtocolAndApply<typename remove_bonded<T>::type, Protocols>(input, transform).second;
|
||||
}
|
||||
|
||||
Reader _data;
|
||||
|
|
|
@ -70,45 +70,45 @@ public:
|
|||
|
||||
|
||||
/// @brief Serialize bonded using specified protocol writer
|
||||
template <typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
typename boost::disable_if<uses_marshaled_bonded<typename Writer::Reader> >::type
|
||||
Serialize(Writer& output) const
|
||||
{
|
||||
Apply(SerializeTo(output), *this);
|
||||
Apply<Protocols>(SerializeTo<Protocols>(output), *this);
|
||||
}
|
||||
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
typename boost::enable_if<uses_marshaled_bonded<typename Writer::Reader> >::type
|
||||
Serialize(Writer& output) const
|
||||
{
|
||||
if (_schema.GetType().bonded_type)
|
||||
detail::MarshalToBlob(*this, output);
|
||||
detail::MarshalToBlob<Protocols>(*this, output);
|
||||
else
|
||||
Apply(SerializeTo(output), *this);
|
||||
Apply<Protocols>(SerializeTo<Protocols>(output), *this);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize an object of type T
|
||||
template <typename T>
|
||||
template <typename T, typename Protocols = BuiltInProtocols>
|
||||
T Deserialize() const
|
||||
{
|
||||
T tmp;
|
||||
Apply(To<T>(tmp), *this);
|
||||
Apply<Protocols>(To<T, Protocols>(tmp), *this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize to an object of type T
|
||||
template <typename T>
|
||||
template <typename Protocols = BuiltInProtocols, typename T>
|
||||
void Deserialize(T& var) const
|
||||
{
|
||||
Apply(To<T>(var), *this);
|
||||
Apply<Protocols>(To<T, Protocols>(var), *this);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Deserialize to a bonded<T>
|
||||
template <typename T>
|
||||
template <typename Protocols = BuiltInProtocols, typename T>
|
||||
void Deserialize(bonded<T>& var) const
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
|
@ -121,8 +121,8 @@ public:
|
|||
#endif
|
||||
{
|
||||
bonded<T> tmp;
|
||||
_SelectProtocolAndApply(boost::ref(tmp));
|
||||
tmp.Deserialize(var);
|
||||
_SelectProtocolAndApply<Protocols>(boost::ref(tmp));
|
||||
tmp.template Deserialize<Protocols>(var);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -139,11 +139,11 @@ public:
|
|||
}
|
||||
|
||||
|
||||
template <typename Transform, typename U, typename ReaderT>
|
||||
template <typename Protocols, typename Transform, typename U, typename ReaderT>
|
||||
friend typename boost::disable_if<detail::need_double_pass<Transform>, bool>::type inline
|
||||
detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
|
||||
|
||||
template <typename Transform, typename U, typename ReaderT>
|
||||
template <typename Protocols, typename Transform, typename U, typename ReaderT>
|
||||
friend typename boost::enable_if<detail::need_double_pass<Transform>, bool>::type inline
|
||||
detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
|
||||
|
||||
|
@ -152,7 +152,7 @@ public:
|
|||
|
||||
private:
|
||||
// Apply transform to serialized data
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
bool _Apply(const Transform& transform) const
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
|
@ -164,27 +164,27 @@ private:
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
return _SelectProtocolAndApply(transform);
|
||||
return _SelectProtocolAndApply<Protocols>(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_skip = false;
|
||||
return detail::Parse<void>(transform, _data, _schema, NULL, _base);
|
||||
return detail::Parse<void, Protocols>(transform, _data, _schema, NULL, _base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
typename boost::enable_if<uses_marshaled_bonded<Reader, Transform>, bool>::type
|
||||
_SelectProtocolAndApply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
auto input = CreateInputBuffer(_data.GetBuffer(), detail::ReadBlob(_data));
|
||||
return SelectProtocolAndApply(_schema, input, transform).second;
|
||||
return SelectProtocolAndApply<Protocols>(_schema, input, transform).second;
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols, typename Transform>
|
||||
typename boost::disable_if<uses_marshaled_bonded<Reader, Transform>, bool>::type
|
||||
_SelectProtocolAndApply(const Transform&) const
|
||||
{
|
||||
|
|
|
@ -14,18 +14,4 @@ is_protocol_enabled
|
|||
: false_type {};
|
||||
|
||||
|
||||
struct protocols;
|
||||
|
||||
// User can modify set of protocols by specializing customize<protocols>
|
||||
template <typename> struct
|
||||
customize
|
||||
{
|
||||
template <typename T> struct
|
||||
modify
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
/*
|
||||
* This header implements bond::detail::any class which provides similar functionality to
|
||||
* the boost::any which (1) uses user-defined CTTI instead of a built-in RTTI and (2) uses
|
||||
* user-defined storage size for small object optimization.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mpl.h"
|
||||
#include <bond/core/config.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <template <typename> class TypeId, std::size_t Size>
|
||||
class any
|
||||
{
|
||||
BOOST_STATIC_ASSERT(Size >= sizeof(void*));
|
||||
|
||||
public:
|
||||
any() BOND_NOEXCEPT
|
||||
: _id{}
|
||||
{}
|
||||
|
||||
any(const any& other)
|
||||
{
|
||||
emplace_uninitialized(other);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
any(const T& value)
|
||||
{
|
||||
emplace_uninitialized(value);
|
||||
}
|
||||
|
||||
~any()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
any& operator=(const any& other)
|
||||
{
|
||||
return assign(other);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
any& operator=(const T& value)
|
||||
{
|
||||
return assign(value);
|
||||
}
|
||||
|
||||
bool empty() const BOND_NOEXCEPT
|
||||
{
|
||||
return _id == 0;
|
||||
}
|
||||
|
||||
explicit operator bool() const BOND_NOEXCEPT
|
||||
{
|
||||
return !empty();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* cast() BOND_NOEXCEPT
|
||||
{
|
||||
return TypeId<T>::value == _id ? functions::template table<T>::unsafe_cast(*this) : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* cast() const BOND_NOEXCEPT
|
||||
{
|
||||
return TypeId<T>::value == _id ? functions::template table<T>::unsafe_cast(*this) : nullptr;
|
||||
}
|
||||
|
||||
bool operator==(const any& other) const
|
||||
{
|
||||
return _id == other._id && (empty() || _functions.compare(*this, other));
|
||||
}
|
||||
|
||||
bool operator!=(const any& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
using storage = typename std::aligned_storage<Size>::type;
|
||||
|
||||
struct functions
|
||||
{
|
||||
void (*destroy)(any& x);
|
||||
|
||||
void (*assign)(any& x, const any& other);
|
||||
|
||||
void (*emplace_uninitialized)(any& x, const any& other);
|
||||
|
||||
bool (*compare)(const any& x, const any& y);
|
||||
|
||||
|
||||
template <typename T, bool IsSmall>
|
||||
struct impl;
|
||||
|
||||
template <typename T>
|
||||
struct impl<T, true>
|
||||
{
|
||||
static T* unsafe_cast(any& x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(TypeId<T>::value == x._id);
|
||||
return static_cast<T*>(x.data());
|
||||
}
|
||||
|
||||
static const T* unsafe_cast(const any& x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(TypeId<T>::value == x._id);
|
||||
return static_cast<const T*>(x.data());
|
||||
}
|
||||
|
||||
static void emplace_uninitialized(any& x, const T& value)
|
||||
{
|
||||
new (x.data()) T{ value };
|
||||
}
|
||||
|
||||
static void destroy(any& x)
|
||||
{
|
||||
unsafe_cast(x)->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct impl<T, false>
|
||||
{
|
||||
static T* unsafe_cast(any& x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(TypeId<T>::value == x._id);
|
||||
return *static_cast<T**>(x.data());
|
||||
}
|
||||
|
||||
static const T* unsafe_cast(const any& x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(TypeId<T>::value == x._id);
|
||||
return *static_cast<const T* const*>(x.data());
|
||||
}
|
||||
|
||||
static void emplace_uninitialized(any& x, const T& value)
|
||||
{
|
||||
*static_cast<T**>(x.data()) = new T{ value };
|
||||
}
|
||||
|
||||
static void destroy(any& x)
|
||||
{
|
||||
delete unsafe_cast(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct table : impl<T, (sizeof(T) <= sizeof(storage))>
|
||||
{
|
||||
BOOST_STATIC_ASSERT(TypeId<T>::value != 0);
|
||||
|
||||
using base = impl<T, (sizeof(T) <= sizeof(storage))>;
|
||||
|
||||
template <typename U = T, typename boost::enable_if<std::is_copy_assignable<U> >::type* = nullptr>
|
||||
static void assign(any& x, const T& value)
|
||||
{
|
||||
*base::unsafe_cast(x) = value;
|
||||
}
|
||||
|
||||
template <typename U = T, typename boost::disable_if<std::is_copy_assignable<U> >::type* = nullptr>
|
||||
static void assign(any& x, const T& value)
|
||||
{
|
||||
// TODO: Cache allocated buffer and reuse.
|
||||
base::destroy(x);
|
||||
emplace_uninitialized(x, value);
|
||||
}
|
||||
|
||||
static void emplace_uninitialized(any& x, const T& value)
|
||||
{
|
||||
base::emplace_uninitialized(x, value);
|
||||
x._id = TypeId<T>::value; // Update the id if emplace_uninitialized did not throw.
|
||||
}
|
||||
|
||||
static functions make() BOND_NOEXCEPT
|
||||
{
|
||||
return
|
||||
{
|
||||
base::destroy,
|
||||
[](any& x, const any& other) { assign(x, *base::unsafe_cast(other)); },
|
||||
[](any& x, const any& other) { emplace_uninitialized(x, *base::unsafe_cast(other)); },
|
||||
[](const any& x, const any& y) { return *base::unsafe_cast(x) == *base::unsafe_cast(y); }
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const void* data() const BOND_NOEXCEPT
|
||||
{
|
||||
return &_storage;
|
||||
}
|
||||
|
||||
void* data() BOND_NOEXCEPT
|
||||
{
|
||||
return &_storage;
|
||||
}
|
||||
|
||||
/// The precondition is that *this is uninitialized (or destroyed).
|
||||
template <typename T>
|
||||
void emplace_uninitialized(const T& value)
|
||||
{
|
||||
functions::template table<T>::emplace_uninitialized(*this, value);
|
||||
_functions = functions::template table<T>::make();
|
||||
}
|
||||
|
||||
/// The precondition is that *this is uninitialized (or destroyed).
|
||||
void emplace_uninitialized(const any& other)
|
||||
{
|
||||
if (!other.empty())
|
||||
{
|
||||
other._functions.emplace_uninitialized(*this, other);
|
||||
_functions = other._functions;
|
||||
}
|
||||
else
|
||||
{
|
||||
_id = {};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
any& assign(const T& value)
|
||||
{
|
||||
if (!try_assign_same(value))
|
||||
{
|
||||
// TODO: Cache allocated buffer and reuse.
|
||||
destroy();
|
||||
emplace_uninitialized(value);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool try_assign_same(const T& value)
|
||||
{
|
||||
if (_id == TypeId<T>::value)
|
||||
{
|
||||
functions::template table<T>::assign(*this, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_assign_same(const any& other)
|
||||
{
|
||||
if (_id == other._id)
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
_functions.assign(*this, other);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
_functions.destroy(*this);
|
||||
_id = {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
storage _storage;
|
||||
functions _functions;
|
||||
std::uint32_t _id;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, template <typename> class TypeId, std::size_t Size>
|
||||
inline T* any_cast(any<TypeId, Size>* x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(x);
|
||||
return x->template cast<T>();
|
||||
}
|
||||
|
||||
template <typename T, template <typename> class TypeId, std::size_t Size>
|
||||
inline const T* any_cast(const any<TypeId, Size>* x) BOND_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(x);
|
||||
return x->template cast<T>();
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace bond
|
|
@ -18,16 +18,17 @@ namespace bond
|
|||
typename Transform::writer_type::Pass0>::value>::type
|
||||
> : true_type {};
|
||||
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
inline bool DoublePassApply(const Transform& transform, const T& value)
|
||||
{
|
||||
typedef typename Transform::writer_type Writer;
|
||||
typedef Serializer<Writer, Protocols> Serializer;
|
||||
|
||||
typename Writer::Pass0::Buffer output;
|
||||
typename Writer::Pass0 pass0(output, transform.Serializer<Writer>::_output);
|
||||
typename Writer::Pass0 pass0(output, transform.Serializer::_output);
|
||||
|
||||
Apply(transform.Rebind(pass0), value);
|
||||
return transform.Serializer<Writer>::_output.WithPass0(pass0), Apply(transform, value);
|
||||
Apply<Protocols>(transform.Rebind(pass0), value);
|
||||
return transform.Serializer::_output.WithPass0(pass0), Apply<Protocols>(transform, value);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -37,19 +37,10 @@ expected_depth
|
|||
: std::integral_constant<uint16_t, 0xffff> {};
|
||||
|
||||
|
||||
template <typename T> struct
|
||||
expected_depth<bond::To<T> >
|
||||
template <typename T, typename Protocols, typename Validator> struct
|
||||
expected_depth<bond::To<T, Protocols, Validator> >
|
||||
: hierarchy_depth<typename schema<T>::type> {};
|
||||
|
||||
template <typename Input, typename T = void, typename Enable = void> struct
|
||||
is_reader
|
||||
: false_type {};
|
||||
|
||||
|
||||
template <typename Input, typename T> struct
|
||||
is_reader<Input&, T, typename boost::enable_if<is_class<typename Input::Parser> >::type>
|
||||
: true_type {};
|
||||
|
||||
|
||||
template <typename Base, typename T>
|
||||
inline Base& base_cast(T& obj)
|
||||
|
|
|
@ -29,13 +29,13 @@ auto ReadBlob(Reader& reader)
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Writer>
|
||||
template <typename Protocols, typename T, typename Writer>
|
||||
void MarshalToBlob(const T& obj, Writer& writer)
|
||||
{
|
||||
auto output = CreateOutputBuffer(writer.GetBuffer());
|
||||
CompactBinaryWriter<decltype(output)> cbw(output);
|
||||
|
||||
Marshal(obj, cbw);
|
||||
Marshal<Protocols>(obj, cbw);
|
||||
auto data = std::move(output).GetBuffer();
|
||||
|
||||
writer.Write(static_cast<uint32_t>(data.size()));
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
/*
|
||||
* This header provides a faster alternative to some of the facilities provided by boost::mpl.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
|
||||
namespace detail {namespace mpl
|
||||
{
|
||||
|
||||
template <typename T> struct
|
||||
identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
/// @brief Represents a type list.
|
||||
template <typename... T> struct
|
||||
list {};
|
||||
|
||||
|
||||
/// @brief Appends the given list of types or a single pack of list<> to the end.
|
||||
template <typename List, typename... T> struct
|
||||
append;
|
||||
|
||||
template <typename List, typename... T>
|
||||
using append_t = typename append<List, T...>::type;
|
||||
|
||||
template <typename List, typename... T> struct
|
||||
append
|
||||
: append<List, list<T...> > {};
|
||||
|
||||
template <typename... T, typename... U> struct
|
||||
append<list<T...>, list<U...> >
|
||||
: identity<list<T..., U...> > {};
|
||||
|
||||
|
||||
/// @brief Filters the given type list with the provided predicate.
|
||||
template <typename List, template <typename> class C> struct
|
||||
filter;
|
||||
|
||||
template <typename List, template <typename> class C>
|
||||
using filter_t = typename filter<List, C>::type;
|
||||
|
||||
template <template <typename> class C> struct
|
||||
filter<list<>, C>
|
||||
: identity<list<> > {};
|
||||
|
||||
template <typename T, typename... U, template <typename> class C> struct
|
||||
filter<list<T, U...>, C>
|
||||
: append< typename std::conditional<C<T>::value, list<T>, list<> >::type, filter_t<list<U...>, C> > {};
|
||||
|
||||
|
||||
template <typename F, typename... T>
|
||||
inline void apply(F&& f, const list<T...>&)
|
||||
{
|
||||
std::initializer_list<int>{ (f(identity<T>{}), 0)... };
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline void apply(F&& /*f*/, const list<>&)
|
||||
{}
|
||||
|
||||
template <typename List, typename F>
|
||||
inline void apply(F&& f)
|
||||
{
|
||||
apply(std::forward<F>(f), List{});
|
||||
}
|
||||
|
||||
|
||||
template <typename F, typename T>
|
||||
inline auto try_apply(F&& f, const list<T>&)
|
||||
#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
|
||||
-> decltype(std::forward<F>(f)(identity<T>{}))
|
||||
#endif
|
||||
{
|
||||
return std::forward<F>(f)(identity<T>{});
|
||||
}
|
||||
|
||||
template <typename F, typename T, typename U, typename... R>
|
||||
inline auto try_apply(F&& f, const list<T, U, R...>&)
|
||||
#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
|
||||
-> decltype(f(identity<T>{}))
|
||||
#endif
|
||||
{
|
||||
if (auto&& result = f(identity<T>{}))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return try_apply(std::forward<F>(f), list<U, R...>{});
|
||||
}
|
||||
|
||||
template <typename List, typename F>
|
||||
inline auto try_apply(F&& f)
|
||||
#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
|
||||
-> decltype(try_apply(std::forward<F>(f), List{}))
|
||||
#endif
|
||||
{
|
||||
BOOST_STATIC_ASSERT(!std::is_same<List, list<> >::value);
|
||||
|
||||
return try_apply(std::forward<F>(f), List{});
|
||||
}
|
||||
|
||||
|
||||
}} // namespace mpl {namespace detail
|
||||
|
||||
} // namespace bond
|
|
@ -8,13 +8,15 @@
|
|||
#include <bond/stream/input_buffer.h>
|
||||
#include <bond/stream/output_buffer.h>
|
||||
#include <bond/core/traits.h>
|
||||
#include <bond/core/null.h>
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
|
||||
class RuntimeSchema;
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Writer, typename Protocols>
|
||||
class Serializer;
|
||||
|
||||
namespace detail
|
||||
|
@ -24,8 +26,7 @@ namespace detail
|
|||
// It is used to dispatch to appropriate protocol at runtime.
|
||||
template <typename T, typename Schema, typename Transform>
|
||||
class _Parser
|
||||
: public boost::static_visitor<bool>,
|
||||
boost::noncopyable
|
||||
: boost::noncopyable
|
||||
{
|
||||
public:
|
||||
_Parser(const Transform& transform, const Schema& schema)
|
||||
|
@ -51,11 +52,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename Reader, typename Writer>
|
||||
template <typename Reader, typename Writer, typename Protocols>
|
||||
static
|
||||
typename boost::enable_if_c<is_protocol_same<Reader, Writer>::value
|
||||
&& protocol_has_multiple_versions<Reader>::value, bool>::type
|
||||
Apply(const Serializer<Writer>& transform, Reader& reader, const Schema& schema, bool base)
|
||||
Apply(const Serializer<Writer, Protocols>& transform, Reader& reader, const Schema& schema, bool base)
|
||||
{
|
||||
if (is_protocol_version_same(reader, transform._output))
|
||||
return FastPassThrough(reader, transform._output, schema);
|
||||
|
@ -63,11 +64,11 @@ public:
|
|||
return typename Reader::Parser(reader, base).Apply(transform, schema);
|
||||
}
|
||||
|
||||
template <typename Reader, typename Writer>
|
||||
template <typename Reader, typename Writer, typename Protocols>
|
||||
static
|
||||
typename boost::enable_if_c<is_protocol_same<Reader, Writer>::value
|
||||
&& !protocol_has_multiple_versions<Reader>::value, bool>::type
|
||||
Apply(const Serializer<Writer>& transform, Reader& reader, const Schema& schema, bool base)
|
||||
Apply(const Serializer<Writer, Protocols>& transform, Reader& reader, const Schema& schema, bool base)
|
||||
{
|
||||
BOOST_VERIFY(!base);
|
||||
// Triggering the following assert means that bond::enable_protocol_versions trait is
|
||||
|
@ -154,72 +155,96 @@ protected:
|
|||
|
||||
|
||||
template <typename Reader, typename T>
|
||||
inline void Skip(Reader& reader, const T& bonded)
|
||||
inline void Skip(Reader& reader, const bonded<T, Reader&>& bonded)
|
||||
{
|
||||
reader.Skip(bonded);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, template <typename BufferT, typename MarshaledBondedProtocolsT> class Reader, typename Buffer, typename MarshaledBondedProtocols>
|
||||
inline void Skip(const bonded<T, Reader<Buffer, MarshaledBondedProtocols>&>& bonded)
|
||||
{
|
||||
// Skip the structure field-by-field by applying Null transform
|
||||
Apply<MarshaledBondedProtocols>(Null(), bonded);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename T>
|
||||
BOND_NO_INLINE void Skip(Reader& reader, const T& bonded, const std::nothrow_t&)
|
||||
BOND_NO_INLINE void Skip(Reader& reader, const bonded<T, Reader&>& bonded, const std::nothrow_t&)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.Skip(bonded);
|
||||
Skip(reader, bonded);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
{}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void Skip(ProtocolReader& /*reader*/, const T& /*bonded*/)
|
||||
inline void Skip(ProtocolReader& /*reader*/, const bonded<T>& /*bonded*/)
|
||||
{
|
||||
// Not skipping for outer structures
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void Skip(ProtocolReader& /*reader*/, const T& /*bonded*/, const std::nothrow_t&)
|
||||
inline void Skip(ProtocolReader& /*reader*/, const bonded<T>& /*bonded*/, const std::nothrow_t&)
|
||||
{
|
||||
// Not skipping for outer structures
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename Transform, typename Reader, typename Schema>
|
||||
template <typename T, typename Protocols, typename Transform, typename Reader, typename Schema>
|
||||
inline bool Parse(const Transform& transform, Reader& reader, const Schema& schema, const RuntimeSchema* runtime_schema, bool base)
|
||||
{
|
||||
BOOST_VERIFY(!runtime_schema);
|
||||
return Parser<T, Schema, Transform>::Apply(transform, reader, schema, base);
|
||||
}
|
||||
|
||||
template <typename T, typename Transform, typename Schema>
|
||||
template <typename T, typename Protocols, typename Transform, typename Schema>
|
||||
inline bool Parse(const Transform& transform, ProtocolReader reader, const Schema& schema, const RuntimeSchema* runtime_schema, bool base)
|
||||
{
|
||||
BOOST_VERIFY(!base);
|
||||
|
||||
boost::optional<bool> result;
|
||||
|
||||
if (runtime_schema)
|
||||
{
|
||||
// Use named variable to avoid gcc silently copying objects (which
|
||||
// causes build break, because Parser<> is non-copyable).
|
||||
Parser<void, RuntimeSchema, Transform> parser(transform, *runtime_schema);
|
||||
return boost::apply_visitor(parser, reader.value);
|
||||
result = reader.template Visit<Protocols
|
||||
#if defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) || defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
, bool
|
||||
#endif
|
||||
>(parser);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use named variable to avoid gcc silently copying objects (which
|
||||
// causes build break, because Parser<> is non-copyable).
|
||||
Parser<T, Schema, Transform> parser(transform, schema);
|
||||
return boost::apply_visitor(parser, reader.value);
|
||||
result = reader.template Visit<Protocols
|
||||
#if defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) || defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
, bool
|
||||
#endif
|
||||
>(parser);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException();
|
||||
}
|
||||
|
||||
|
||||
// Visitor which updates in-situ bonded<T> payload by merging it with an object.
|
||||
template <typename T, typename Buffer>
|
||||
class InsituMerge
|
||||
: public boost::static_visitor<>,
|
||||
boost::noncopyable
|
||||
: boost::noncopyable
|
||||
{
|
||||
public:
|
||||
InsituMerge(const T& var, ProtocolReader& reader)
|
||||
|
@ -261,10 +286,17 @@ private:
|
|||
};
|
||||
|
||||
|
||||
template <typename Buffer = OutputBuffer, typename T>
|
||||
template <typename Protocols, typename Buffer = OutputBuffer, typename T>
|
||||
inline void Merge(const T& var, ProtocolReader& reader)
|
||||
{
|
||||
boost::apply_visitor(InsituMerge<T, Buffer>(var, reader), reader.value);
|
||||
if (!reader.template Visit<Protocols
|
||||
#if defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) || defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
, void
|
||||
#endif
|
||||
>(InsituMerge<T, Buffer>(var, reader)))
|
||||
{
|
||||
UnknownProtocolException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <bond/core/bond_fwd.h>
|
||||
#include <bond/core/bond_const_enum.h>
|
||||
#include "nonassignable.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace bond
|
||||
{
|
||||
|
||||
struct Metadata;
|
||||
|
||||
// Used to get qualified name of enum using generated GetTypeName
|
||||
struct qualified_name_tag
|
||||
{};
|
||||
|
@ -74,17 +77,17 @@ struct ModifyingTransform
|
|||
|
||||
template <typename T, typename Unused = void> struct
|
||||
is_serializing_transform
|
||||
: is_base_of<SerializingTransform, T> {};
|
||||
: std::is_base_of<SerializingTransform, T> {};
|
||||
|
||||
|
||||
template <typename T, typename Unused = void> struct
|
||||
is_deserializing_transform
|
||||
: is_base_of<DeserializingTransform, T> {};
|
||||
: std::is_base_of<DeserializingTransform, T> {};
|
||||
|
||||
|
||||
template <typename T, typename Unused = void> struct
|
||||
is_modifying_transform
|
||||
: is_base_of<ModifyingTransform, T> {};
|
||||
: std::is_base_of<ModifyingTransform, T> {};
|
||||
|
||||
|
||||
} // namespace bond
|
||||
|
|
|
@ -6,6 +6,41 @@
|
|||
namespace bond
|
||||
{
|
||||
|
||||
template <typename Protocols, typename X, typename Key, typename T>
|
||||
typename boost::enable_if<is_map_key_matching<Key, X> >::type
|
||||
inline DeserializeMapElements(X& var, const Key& key, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename X, typename Key, typename T>
|
||||
typename boost::disable_if<is_map_key_matching<Key, X> >::type
|
||||
inline DeserializeMapElements(X&, const Key& key, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename Transform, typename Key, typename T>
|
||||
inline void DeserializeMapElements(const Transform& transform, const Key& key, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::enable_if_c<is_list_container<X>::value
|
||||
&& is_element_matching<T, X>::value>::type
|
||||
inline DeserializeElements(X& var, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename X, typename Allocator, bool useValue, typename T>
|
||||
typename boost::enable_if<is_matching<T, X> >::type
|
||||
inline DeserializeElements(nullable<X, Allocator, useValue>& var, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename Reader>
|
||||
inline void DeserializeElements(blob& var, const value<blob::value_type, Reader&>& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::enable_if_c<is_set_container<X>::value
|
||||
&& is_element_matching<T, X>::value>::type
|
||||
inline DeserializeElements(X& var, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::disable_if<is_element_matching<T, X> >::type
|
||||
inline DeserializeElements(X&, const T& element, uint32_t size);
|
||||
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
inline void DeserializeElements(const Transform& transform, const T& element, uint32_t size);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
@ -115,7 +150,7 @@ inline bool BasicTypeField(uint16_t id, const Metadata& metadata, BondDataType t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
inline void BasicTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(!is_container<T>::value);
|
||||
|
@ -123,43 +158,43 @@ inline void BasicTypeContainer(T& var, BondDataType type, Reader& input, uint32_
|
|||
switch (type)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return DeserializeElements(var, value<bool, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<bool, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT8:
|
||||
return DeserializeElements(var, value<uint8_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint8_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return DeserializeElements(var, value<uint16_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint16_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return DeserializeElements(var, value<uint32_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint32_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return DeserializeElements(var, value<uint64_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint64_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_FLOAT:
|
||||
return DeserializeElements(var, value<float, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<float, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return DeserializeElements(var, value<double, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<double, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_STRING:
|
||||
return DeserializeElements(var, value<std::string, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<std::string, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_WSTRING:
|
||||
return DeserializeElements(var, value<std::wstring, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<std::wstring, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT8:
|
||||
return DeserializeElements(var, value<int8_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int8_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return DeserializeElements(var, value<int16_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int16_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return DeserializeElements(var, value<int32_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int32_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return DeserializeElements(var, value<int64_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int64_t, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(false);
|
||||
|
@ -170,13 +205,13 @@ inline void BasicTypeContainer(T& var, BondDataType type, Reader& input, uint32_
|
|||
|
||||
// MatchingTypeContainer function are manually expended versions of BasicTypeContainer
|
||||
// using the type information about destination container. This helps with compilation speed.
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_type_alias<typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
if (type == get_type_id<typename element_type<T>::type>::value)
|
||||
{
|
||||
DeserializeElements(var, value<typename element_type<T>::type, Reader&>(input, false), size);
|
||||
DeserializeElements<Protocols>(var, value<typename element_type<T>::type, Reader&>(input, false), size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -188,14 +223,14 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_same<bool, typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return DeserializeElements(var, value<bool, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<bool, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -207,14 +242,14 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_string<typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_STRING:
|
||||
return DeserializeElements(var, value<std::string, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<std::string, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -226,14 +261,14 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_wstring<typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_WSTRING:
|
||||
return DeserializeElements(var, value<std::wstring, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<std::wstring, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -245,17 +280,17 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_floating_point<typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_FLOAT:
|
||||
return DeserializeElements(var, value<float, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<float, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return DeserializeElements(var, value<double, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<double, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -267,23 +302,23 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_UINT8:
|
||||
return DeserializeElements(var, value<uint8_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint8_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return DeserializeElements(var, value<uint16_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint16_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return DeserializeElements(var, value<uint32_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint32_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return DeserializeElements(var, value<uint64_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<uint64_t, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -295,23 +330,23 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type> >::type
|
||||
inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case bond::BT_INT8:
|
||||
return DeserializeElements(var, value<int8_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int8_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return DeserializeElements(var, value<int16_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int16_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return DeserializeElements(var, value<int32_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int32_t, Reader&>(input, false), size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return DeserializeElements(var, value<int64_t, Reader&>(input, false), size);
|
||||
return DeserializeElements<Protocols>(var, value<int64_t, Reader&>(input, false), size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type>(type));
|
||||
|
@ -322,16 +357,17 @@ inline MatchingTypeContainer(T& var, BondDataType type, Reader& input, uint32_t
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// MatchingMapByKey function are manually expended versions of MapByKey using the type
|
||||
// information about destination container. This helps with compilation speed.
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_type_alias<typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
if (keyType == get_type_id<typename element_type<T>::type::first_type>::value)
|
||||
{
|
||||
return DeserializeMapElements(var, value<typename element_type<T>::type::first_type, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<typename element_type<T>::type::first_type, Reader&>(input, false), element, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -346,14 +382,14 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_same<bool, typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return DeserializeMapElements(var, value<bool, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<bool, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -368,14 +404,14 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_string<typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_STRING:
|
||||
return DeserializeMapElements(var, value<std::string, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<std::string, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -390,14 +426,14 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_wstring<typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_WSTRING:
|
||||
return DeserializeMapElements(var, value<std::wstring, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<std::wstring, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -412,17 +448,17 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_floating_point<typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_FLOAT:
|
||||
return DeserializeMapElements(var, value<float, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<float, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return DeserializeMapElements(var, value<double, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<double, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -437,23 +473,23 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_UINT8:
|
||||
return DeserializeMapElements(var, value<uint8_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint8_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return DeserializeMapElements(var, value<uint16_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint16_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return DeserializeMapElements(var, value<uint32_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint32_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return DeserializeMapElements(var, value<uint64_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint64_t, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -468,23 +504,23 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type::first_type> >::type
|
||||
inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_INT8:
|
||||
return DeserializeMapElements(var, value<int8_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int8_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return DeserializeMapElements(var, value<int16_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int16_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return DeserializeMapElements(var, value<int32_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int32_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return DeserializeMapElements(var, value<int64_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int64_t, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::first_type>(keyType));
|
||||
|
@ -500,50 +536,50 @@ inline MatchingMapByKey(T& var, BondDataType keyType, const E& element, Reader&
|
|||
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::disable_if<is_map_container<T> >::type
|
||||
inline MapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (keyType)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return DeserializeMapElements(var, value<bool, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<bool, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT8:
|
||||
return DeserializeMapElements(var, value<uint8_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint8_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return DeserializeMapElements(var, value<uint16_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint16_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return DeserializeMapElements(var, value<uint32_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint32_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return DeserializeMapElements(var, value<uint64_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<uint64_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_FLOAT:
|
||||
return DeserializeMapElements(var, value<float, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<float, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return DeserializeMapElements(var, value<double, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<double, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_STRING:
|
||||
return DeserializeMapElements(var, value<std::string, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<std::string, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_WSTRING:
|
||||
return DeserializeMapElements(var, value<std::wstring, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<std::wstring, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT8:
|
||||
return DeserializeMapElements(var, value<int8_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int8_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return DeserializeMapElements(var, value<int16_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int16_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return DeserializeMapElements(var, value<int32_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int32_t, Reader&>(input, false), element, size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return DeserializeMapElements(var, value<int64_t, Reader&>(input, false), element, size);
|
||||
return DeserializeMapElements<Protocols>(var, value<int64_t, Reader&>(input, false), element, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(false);
|
||||
|
@ -552,15 +588,15 @@ inline MapByKey(T& var, BondDataType keyType, const E& element, Reader& input, u
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::enable_if<is_map_element_matching<E, T> >::type
|
||||
inline MapByKey(T& var, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
return MatchingMapByKey(var, keyType, element, input, size);
|
||||
return MatchingMapByKey<Protocols>(var, keyType, element, input, size);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename E, typename Reader>
|
||||
template <typename Protocols, typename T, typename E, typename Reader>
|
||||
typename boost::disable_if_c<!is_map_container<T>::value || is_map_element_matching<E, T>::value>::type
|
||||
inline MapByKey(T&, BondDataType keyType, const E& element, Reader& input, uint32_t size)
|
||||
{
|
||||
|
@ -572,49 +608,49 @@ inline MapByKey(T&, BondDataType keyType, const E& element, Reader& input, uint3
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
inline void MapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return MapByKey(var, keyType, value<bool, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<bool, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT8:
|
||||
return MapByKey(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return MapByKey(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return MapByKey(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return MapByKey(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_FLOAT:
|
||||
return MapByKey(var, keyType, value<float, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<float, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return MapByKey(var, keyType, value<double, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<double, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_STRING:
|
||||
return MapByKey(var, keyType, value<std::string, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<std::string, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_WSTRING:
|
||||
return MapByKey(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT8:
|
||||
return MapByKey(var, keyType, value<int8_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int8_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return MapByKey(var, keyType, value<int16_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int16_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return MapByKey(var, keyType, value<int32_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int32_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return MapByKey(var, keyType, value<int64_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int64_t, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(false);
|
||||
|
@ -626,13 +662,13 @@ inline void MapByElement(T& var, BondDataType keyType, BondDataType elementType,
|
|||
// MatchingMapByElement function are manually expended versions of MapByElement using
|
||||
// the type information about destination container. This helps with compilation speed.
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_type_alias<typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
if (elementType == get_type_id<typename element_type<T>::type::second_type>::value)
|
||||
{
|
||||
MapByKey(var, keyType, value<typename element_type<T>::type::second_type, Reader&>(input, false), input, size);
|
||||
MapByKey<Protocols>(var, keyType, value<typename element_type<T>::type::second_type, Reader&>(input, false), input, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -647,14 +683,14 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_same<bool, typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_BOOL:
|
||||
return MapByKey(var, keyType, value<bool, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<bool, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
@ -669,14 +705,14 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_string<typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_STRING:
|
||||
return MapByKey(var, keyType, value<std::string, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<std::string, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
@ -691,14 +727,14 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_wstring<typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_WSTRING:
|
||||
return MapByKey(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<std::wstring, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
@ -713,17 +749,17 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_floating_point<typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_FLOAT:
|
||||
return MapByKey(var, keyType, value<float, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<float, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_DOUBLE:
|
||||
return MapByKey(var, keyType, value<double, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<double, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
@ -738,23 +774,23 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_matching<uint8_t, typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_UINT8:
|
||||
return MapByKey(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint8_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT16:
|
||||
return MapByKey(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint16_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT32:
|
||||
return MapByKey(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint32_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_UINT64:
|
||||
return MapByKey(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<uint64_t, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
@ -769,23 +805,23 @@ inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementTy
|
|||
}
|
||||
|
||||
|
||||
template <typename T, typename Reader>
|
||||
template <typename Protocols, typename T, typename Reader>
|
||||
typename boost::enable_if<is_matching<int8_t, typename element_type<T>::type::second_type> >::type
|
||||
inline MatchingMapByElement(T& var, BondDataType keyType, BondDataType elementType, Reader& input, uint32_t size)
|
||||
{
|
||||
switch (elementType)
|
||||
{
|
||||
case bond::BT_INT8:
|
||||
return MapByKey(var, keyType, value<int8_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int8_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT16:
|
||||
return MapByKey(var, keyType, value<int16_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int16_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT32:
|
||||
return MapByKey(var, keyType, value<int32_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int32_t, Reader&>(input, false), input, size);
|
||||
|
||||
case bond::BT_INT64:
|
||||
return MapByKey(var, keyType, value<int64_t, Reader&>(input, false), input, size);
|
||||
return MapByKey<Protocols>(var, keyType, value<int64_t, Reader&>(input, false), input, size);
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(!IsMatching<typename element_type<T>::type::second_type>(elementType));
|
||||
|
|
|
@ -207,6 +207,7 @@ inline void ValidateStruct(const RuntimeSchema& src,
|
|||
|
||||
|
||||
// Checks if payload contains unknown fields
|
||||
template <typename Protocols>
|
||||
class SchemaValidator
|
||||
: public DeserializingTransform
|
||||
{
|
||||
|
@ -271,14 +272,14 @@ private:
|
|||
typename boost::disable_if<is_basic_type<T>, bool>::type
|
||||
Recurse(const value<T, Reader>& value) const
|
||||
{
|
||||
Apply(*this, value);
|
||||
Apply<Protocols>(*this, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, typename Reader>
|
||||
bool Recurse(const bonded<T, Reader>& value) const
|
||||
{
|
||||
return Apply(*this, value);
|
||||
return Apply<Protocols>(*this, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mpl.h"
|
||||
#include <boost/optional.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) && !defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
|
||||
template <typename T, typename Visitor, typename Any>
|
||||
inline typename boost::disable_if<std::is_void<std::result_of_t<Visitor(T&)> >, boost::optional<std::result_of_t<Visitor(T&)> > >::type
|
||||
try_visit_any(Visitor&& visitor, Any& x)
|
||||
{
|
||||
if (auto value = any_cast<T>(&x))
|
||||
{
|
||||
return std::forward<Visitor>(visitor)(*value);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T, typename Visitor, typename Any>
|
||||
inline typename boost::enable_if<std::is_void<std::result_of_t<Visitor(T&)> >, bool>::type
|
||||
try_visit_any(Visitor&& visitor, Any& x)
|
||||
{
|
||||
if (auto value = any_cast<T>(&x))
|
||||
{
|
||||
std::forward<Visitor>(visitor)(*value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename List, typename Visitor, typename Any>
|
||||
inline auto visit_any(Visitor&& visitor, Any& x)
|
||||
{
|
||||
return mpl::try_apply<List>(
|
||||
[&](auto identity)
|
||||
{
|
||||
(void)identity;
|
||||
return try_visit_any<typename decltype(identity)::type>(std::forward<Visitor>(visitor), x);
|
||||
});
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <typename Result, typename Visitor, typename Any>
|
||||
struct try_visit_any
|
||||
{
|
||||
try_visit_any(Visitor& visitor, Any& x)
|
||||
: _visitor(visitor),
|
||||
_x(x)
|
||||
{}
|
||||
|
||||
try_visit_any& operator=(const try_visit_any& other) = delete;
|
||||
|
||||
template <typename T, typename R = Result>
|
||||
typename boost::disable_if<std::is_void<R>, boost::optional<Result> >::type
|
||||
operator()(const mpl::identity<T>&) const
|
||||
{
|
||||
if (auto value = any_cast<T>(&_x))
|
||||
{
|
||||
return _visitor(*value);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename T, typename R = Result>
|
||||
typename boost::enable_if<std::is_void<R>, bool>::type
|
||||
operator()(const mpl::identity<T>&) const
|
||||
{
|
||||
if (auto value = any_cast<T>(&_x))
|
||||
{
|
||||
_visitor(*value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Visitor& _visitor;
|
||||
Any& _x;
|
||||
};
|
||||
|
||||
template <typename T> struct
|
||||
visitor_result
|
||||
{
|
||||
using type = boost::optional<T>;
|
||||
};
|
||||
|
||||
template <> struct
|
||||
visitor_result<void>
|
||||
{
|
||||
using type = bool;
|
||||
};
|
||||
|
||||
template <typename Result, typename Visitor, typename Any, typename T, typename... U>
|
||||
inline typename visitor_result<Result>::type visit_any(Visitor&& visitor, Any& x, const mpl::list<T, U...>&)
|
||||
{
|
||||
return mpl::try_apply<mpl::list<T, U...> >(try_visit_any<Result, Visitor, Any>(visitor, x));
|
||||
}
|
||||
|
||||
template <typename List, typename Result, typename Visitor, typename Any>
|
||||
inline typename visitor_result<Result>::type visit_any(Visitor&& visitor, Any& x)
|
||||
{
|
||||
return visit_any<Result>(std::forward<Visitor>(visitor), x, List{});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace bond
|
|
@ -14,18 +14,18 @@ namespace bond
|
|||
{
|
||||
|
||||
|
||||
template <typename T, typename Writer>
|
||||
template <typename T, typename Writer, typename Protocols = BuiltInProtocols>
|
||||
class Merger
|
||||
: public Serializer<Writer>
|
||||
{
|
||||
public:
|
||||
typedef T FastPathType;
|
||||
|
||||
using Serializer<Writer>::Base;
|
||||
using Serializer<Writer>::Field;
|
||||
using Serializer<Writer>::Write;
|
||||
using Serializer<Writer>::OmittedField;
|
||||
using Serializer<Writer>::Container;
|
||||
using Serializer<Writer, Protocols>::Base;
|
||||
using Serializer<Writer, Protocols>::Field;
|
||||
using Serializer<Writer, Protocols>::Write;
|
||||
using Serializer<Writer, Protocols>::OmittedField;
|
||||
using Serializer<Writer, Protocols>::Container;
|
||||
|
||||
Merger(const T& var, Writer& output, bool base = false)
|
||||
: Serializer<Writer>(output, base),
|
||||
|
@ -33,16 +33,16 @@ public:
|
|||
{}
|
||||
|
||||
template <typename Pass0>
|
||||
Merger<T, Pass0> Rebind(Pass0& pass0) const
|
||||
Merger<T, Pass0, Protocols> Rebind(Pass0& pass0) const
|
||||
{
|
||||
return Merger<T, Pass0>(_var, pass0);
|
||||
return Merger<T, Pass0, Protocols>(_var, pass0);
|
||||
}
|
||||
|
||||
template <typename X, typename Reader>
|
||||
typename boost::enable_if<has_schema<X>, bool>::type
|
||||
Base(const bonded<X, Reader>& value) const
|
||||
{
|
||||
return Apply(Merger<typename schema<T>::type::base, Writer>(_var, _output, true), value);
|
||||
return Apply<Protocols>(Merger<typename schema<T>::type::base, Writer, Protocols>(_var, _output, true), value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,14 +100,14 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
using Serializer<Writer>::_output;
|
||||
using Serializer<Writer, Protocols>::_output;
|
||||
|
||||
|
||||
private:
|
||||
template <typename U, typename X>
|
||||
void Merge(const U& var, const X& value) const
|
||||
{
|
||||
Apply(Merger<U, Writer>(var, _output), value);
|
||||
Apply<Protocols>(Merger<U, Writer, Protocols>(var, _output), value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,7 +138,7 @@ private:
|
|||
|
||||
while (size--)
|
||||
{
|
||||
key.Deserialize(k);
|
||||
key.template Deserialize<Protocols>(k);
|
||||
|
||||
Write(k);
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ public:
|
|||
return Apply(*this, base);
|
||||
}
|
||||
|
||||
template <typename T, template <typename BufferT, typename MarshaledBondedProtocolsT> class Reader, typename Buffer, typename MarshaledBondedProtocols>
|
||||
bool Base(const bonded<T, Reader<Buffer, MarshaledBondedProtocols>&>& base) const
|
||||
{
|
||||
return Apply<MarshaledBondedProtocols>(*this, base);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Field(uint16_t, const Metadata&, const T&) const
|
||||
{
|
||||
|
|
|
@ -137,7 +137,7 @@ private:
|
|||
|
||||
|
||||
template <typename T, typename Transform>
|
||||
typename boost::enable_if_c<detail::is_reader<Input>::value && !is_nested_field<T>::value
|
||||
typename boost::enable_if_c<is_reader<Input>::value && !is_nested_field<T>::value
|
||||
&& !is_fast_path_field<T, Transform>::value, bool>::type
|
||||
NextField(const T&, const Transform& transform)
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ private:
|
|||
|
||||
|
||||
template <typename T, typename Transform>
|
||||
typename boost::enable_if_c<detail::is_reader<Input>::value && !is_nested_field<T>::value
|
||||
typename boost::enable_if_c<is_reader<Input>::value && !is_nested_field<T>::value
|
||||
&& is_fast_path_field<T, Transform>::value, bool>::type
|
||||
NextField(const T& field, const Transform& transform)
|
||||
{
|
||||
|
@ -155,7 +155,7 @@ private:
|
|||
|
||||
|
||||
template <typename T, typename Transform>
|
||||
typename boost::enable_if_c<detail::is_reader<Input>::value && is_nested_field<T>::value
|
||||
typename boost::enable_if_c<is_reader<Input>::value && is_nested_field<T>::value
|
||||
&& !is_fast_path_field<T, Transform>::value, bool>::type
|
||||
NextField(const T&, const Transform& transform)
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ private:
|
|||
|
||||
|
||||
template <typename T, typename Transform>
|
||||
typename boost::enable_if_c<detail::is_reader<Input>::value && is_nested_field<T>::value
|
||||
typename boost::enable_if_c<is_reader<Input>::value && is_nested_field<T>::value
|
||||
&& is_fast_path_field<T, Transform>::value, bool>::type
|
||||
NextField(const T& field, const Transform& transform)
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ private:
|
|||
|
||||
|
||||
template <typename T, typename Transform>
|
||||
typename boost::disable_if<detail::is_reader<Input, T>, bool>::type
|
||||
typename boost::disable_if<is_reader<Input, T>, bool>::type
|
||||
NextField(const T&, const Transform& transform)
|
||||
{
|
||||
return transform.Field(T::id, T::metadata, T::GetVariable(_input));
|
||||
|
@ -498,8 +498,8 @@ private:
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool UnknownField(uint16_t, BondDataType type, const To<T>&)
|
||||
template <typename T, typename Protocols, typename Validator>
|
||||
bool UnknownField(uint16_t, BondDataType type, const To<T, Protocols, Validator>&)
|
||||
{
|
||||
_input.Skip(type);
|
||||
return false;
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/insert_range.hpp>
|
||||
#include <boost/mpl/filter_view.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
|
||||
#include "traits.h"
|
||||
#include "customize.h"
|
||||
#include "detail/any.h"
|
||||
#include "detail/mpl.h"
|
||||
#include "detail/odr.h"
|
||||
#include "detail/visit_any.h"
|
||||
#include <bond/stream/input_buffer.h>
|
||||
#include <bond/protocol/simple_binary.h>
|
||||
#include <bond/protocol/compact_binary.h>
|
||||
#include <bond/protocol/fast_binary.h>
|
||||
#include <bond/protocol/simple_json_reader.h>
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#if !defined(BOND_COMPACT_BINARY_PROTOCOL) \
|
||||
&& !defined(BOND_SIMPLE_BINARY_PROTOCOL) \
|
||||
&& !defined(BOND_FAST_BINARY_PROTOCOL) \
|
||||
|
@ -41,8 +41,8 @@ is_protocol_enabled<CompactBinaryReader<Buffer> >
|
|||
#endif
|
||||
|
||||
#ifdef BOND_SIMPLE_BINARY_PROTOCOL
|
||||
template <typename Buffer> struct
|
||||
is_protocol_enabled<SimpleBinaryReader<Buffer> >
|
||||
template <typename Buffer, typename MarshaledBondedProtocols> struct
|
||||
is_protocol_enabled<SimpleBinaryReader<Buffer, MarshaledBondedProtocols> >
|
||||
: true_type {};
|
||||
#endif
|
||||
|
||||
|
@ -106,10 +106,58 @@ uses_marshaled_bonded
|
|||
: uses_static_parser<Reader> {};
|
||||
|
||||
|
||||
template <typename... T>
|
||||
struct Protocols
|
||||
{
|
||||
private:
|
||||
template <typename Buffer>
|
||||
struct FilterBufferHelper;
|
||||
|
||||
public:
|
||||
using type = detail::mpl::list<T...>;
|
||||
|
||||
template <typename... U>
|
||||
using Append = typename Protocols<detail::mpl::append_t<type, U...> >::type;
|
||||
|
||||
using FilterEnabled = typename Protocols<detail::mpl::filter_t<type, is_protocol_enabled> >::type;
|
||||
|
||||
template <typename Buffer>
|
||||
using FilterBuffer = typename FilterBufferHelper<Buffer>::type;
|
||||
|
||||
private:
|
||||
template <typename Buffer>
|
||||
struct FilterBufferHelper
|
||||
{
|
||||
template <typename U>
|
||||
using check_buffer = std::is_same<typename std::remove_reference<typename U::Buffer>::type, Buffer>;
|
||||
|
||||
using type = typename Protocols<detail::mpl::filter_t<typename FilterEnabled::type, check_buffer> >::type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <typename... T>
|
||||
struct Protocols<detail::mpl::list<T...> >
|
||||
{
|
||||
using type = Protocols<T...>;
|
||||
};
|
||||
|
||||
|
||||
// Deriving from Protocols<> instead of using an alias to avoid
|
||||
// binary size increase due to much longer type/function names on VC.
|
||||
struct BuiltInProtocols
|
||||
: Protocols<
|
||||
CompactBinaryReader<InputBuffer>,
|
||||
SimpleBinaryReader<InputBuffer>,
|
||||
FastBinaryReader<InputBuffer>,
|
||||
SimpleJsonReader<InputBuffer> > {};
|
||||
|
||||
|
||||
struct ValueReader
|
||||
{
|
||||
// Constructors that explicitly declared noexcept are needed for
|
||||
// boost::variant to use optimized code path.
|
||||
BOOST_STATIC_CONSTEXPR uint16_t magic = 0x5256 /*VR*/;
|
||||
using Buffer = void;
|
||||
|
||||
ValueReader() BOND_NOEXCEPT
|
||||
: pointer(NULL)
|
||||
{}
|
||||
|
@ -147,85 +195,82 @@ struct ValueReader
|
|||
};
|
||||
|
||||
|
||||
using boost::mpl::_;
|
||||
BOND_DEFINE_BUFFER_MAGIC(ValueReader::Buffer, 0);
|
||||
|
||||
struct Protocols
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef boost::mpl::list<
|
||||
CompactBinaryReader<InputBuffer>,
|
||||
SimpleBinaryReader<InputBuffer>,
|
||||
FastBinaryReader<InputBuffer>,
|
||||
SimpleJsonReader<InputBuffer>
|
||||
>::type built_in;
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
typedef customize<protocols>::modify<built_in>::type all;
|
||||
// Avoid std::max due to a bug in Visual C++ 2017.
|
||||
template <std::size_t V0, std::size_t V1>
|
||||
struct max_of
|
||||
: std::integral_constant<std::size_t, (V0 < V1 ? V1 : V0)> {};
|
||||
|
||||
typedef boost::mpl::filter_view<all, is_protocol_enabled<_> >::type type;
|
||||
template <typename List> struct
|
||||
max_size;
|
||||
|
||||
typedef boost::mpl::begin<type>::type begin;
|
||||
template <> struct
|
||||
max_size<detail::mpl::list<> >
|
||||
: std::integral_constant<std::size_t, 0> {};
|
||||
|
||||
typedef boost::mpl::end<type>::type end;
|
||||
};
|
||||
template <typename T, typename... U> struct
|
||||
max_size<detail::mpl::list<T, U...> >
|
||||
: max_of<sizeof(T), max_size<detail::mpl::list<U...> >::value> {};
|
||||
|
||||
using protocol_max_size = max_size<BuiltInProtocols::Append<ValueReader>::type>;
|
||||
|
||||
#else // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
// Use hard-coded 128 byte storage on VC12 as a compiler crash workaround.
|
||||
using protocol_max_size = std::integral_constant<std::size_t, 128>;
|
||||
|
||||
#endif
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <typename InputBuffer>
|
||||
struct FilteredProtocols
|
||||
class ProtocolReader
|
||||
{
|
||||
private:
|
||||
template <typename Reader, typename Enable = void> struct
|
||||
check_buffer
|
||||
: std::false_type {};
|
||||
|
||||
template <typename Reader> struct
|
||||
check_buffer<Reader, typename boost::enable_if<std::is_same<typename Reader::Buffer, InputBuffer> >::type>
|
||||
: std::true_type {};
|
||||
|
||||
public:
|
||||
typedef typename boost::mpl::filter_view<Protocols::type, check_buffer<_> >::type type;
|
||||
using Parser = void;
|
||||
using Writer = void;
|
||||
|
||||
typedef typename boost::mpl::begin<type>::type begin;
|
||||
|
||||
typedef typename boost::mpl::end<type>::type end;
|
||||
};
|
||||
|
||||
|
||||
struct ProtocolReader
|
||||
{
|
||||
typedef void Parser;
|
||||
typedef void Writer;
|
||||
|
||||
ProtocolReader()
|
||||
: value()
|
||||
{
|
||||
// Validate that all compilation units in a program use the same set of protocols.
|
||||
(void)one_definition<Protocols, Protocols::all>::value;
|
||||
}
|
||||
|
||||
ProtocolReader(const ValueReader& x)
|
||||
: value(x)
|
||||
ProtocolReader(const ValueReader& reader = {})
|
||||
: _value(reader)
|
||||
{}
|
||||
|
||||
template <typename Reader, typename boost::enable_if<boost::mpl::contains<Protocols::all, Reader> >::type* = nullptr>
|
||||
|
||||
template <typename Reader, typename boost::enable_if<is_reader<Reader> >::type* = nullptr>
|
||||
ProtocolReader(const Reader& reader)
|
||||
: value(reader)
|
||||
{}
|
||||
|
||||
ProtocolReader(const ProtocolReader& that)
|
||||
: value(that.value)
|
||||
: _value(reader)
|
||||
{}
|
||||
|
||||
bool operator==(const ProtocolReader& rhs) const
|
||||
bool operator==(const ProtocolReader& rhs) const
|
||||
{
|
||||
return value == rhs.value;
|
||||
return _value == rhs._value;
|
||||
}
|
||||
|
||||
boost::make_variant_over<
|
||||
boost::mpl::insert_range<
|
||||
boost::mpl::list<ValueReader>::type,
|
||||
boost::mpl::end<boost::mpl::list<ValueReader>::type>::type,
|
||||
Protocols::all
|
||||
>::type
|
||||
>::type value;
|
||||
|
||||
#if !defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) && !defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
template <typename Protocols, typename Visitor>
|
||||
auto Visit(Visitor&& visitor)
|
||||
#else
|
||||
template <typename Protocols, typename Result, typename Visitor>
|
||||
typename detail::visitor_result<Result>::type Visit(Visitor&& visitor)
|
||||
#endif
|
||||
{
|
||||
return detail::visit_any<typename Protocols::template Append<ValueReader>::type
|
||||
#if defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) || defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
|
||||
, Result
|
||||
#endif
|
||||
>(std::forward<Visitor>(visitor), _value);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Reader> struct
|
||||
reader_id
|
||||
: std::integral_constant<uint32_t, Reader::magic | (buffer_magic<typename Reader::Buffer>::value << 16)> {};
|
||||
|
||||
|
||||
detail::any<reader_id, detail::protocol_max_size::value> _value;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -65,17 +65,17 @@ inline BondDataType RuntimeSchema::GetTypeId() const
|
|||
}
|
||||
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
inline void Serialize(const RuntimeSchema& schema, Writer& output)
|
||||
{
|
||||
Apply(SerializeTo(output), schema.GetSchema());
|
||||
Apply<Protocols>(SerializeTo<Protocols>(output), schema.GetSchema());
|
||||
}
|
||||
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Protocols = BuiltInProtocols, typename Writer>
|
||||
inline void Marshal(const RuntimeSchema& schema, Writer& output)
|
||||
{
|
||||
Apply(MarshalTo(output), schema.GetSchema());
|
||||
Apply<Protocols>(MarshalTo<Protocols>(output), schema.GetSchema());
|
||||
}
|
||||
|
||||
class InitSchemaDef;
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
#include "runtime_schema.h"
|
||||
#include "exception.h"
|
||||
|
||||
#ifdef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
namespace detail
|
||||
|
@ -15,196 +20,212 @@ namespace detail
|
|||
|
||||
|
||||
// Overload of Apply used to extract bonded<T> from marshaled payload
|
||||
template <typename T, typename U, typename Reader>
|
||||
template <typename Protocols, typename T, typename U, typename Reader>
|
||||
inline bool
|
||||
Apply(const boost::reference_wrapper<bonded<T> >& ref, const bonded<U, Reader>& value)
|
||||
{
|
||||
value.Deserialize(ref.get());
|
||||
value.template Deserialize<Protocols>(ref.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Select protocol and apply transform using compile-time schema
|
||||
template <typename T, typename Buffer, typename Transform, typename EndIter>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(
|
||||
const EndIter&,
|
||||
const EndIter&,
|
||||
Buffer&,
|
||||
const Transform&)
|
||||
template <typename Protocols, typename F>
|
||||
inline auto TryEachProtocol(F&& f)
|
||||
#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
|
||||
-> decltype(mpl::try_apply<typename Protocols::type>(std::forward<F>(f)))
|
||||
#endif
|
||||
{
|
||||
UnknownProtocolException();
|
||||
return std::make_pair(MARSHALED_PROTOCOL, false);
|
||||
return mpl::try_apply<typename Protocols::type>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename Buffer, typename Transform, typename Iter, typename EndIter>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(
|
||||
const Iter&,
|
||||
const EndIter& end,
|
||||
Buffer& input,
|
||||
const Transform& transform)
|
||||
template <typename T, typename Protocols>
|
||||
struct NextProtocolFunctor
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iter>::type Reader;
|
||||
|
||||
Reader reader(input);
|
||||
|
||||
if (reader.ReadVersion())
|
||||
template <typename Buffer, typename Transform, typename Reader>
|
||||
boost::optional<std::pair<ProtocolType, bool> >
|
||||
operator()(Buffer& input, const Transform& transform, const mpl::identity<Reader>&) const
|
||||
{
|
||||
return std::make_pair(
|
||||
static_cast<ProtocolType>(Reader::magic),
|
||||
Apply(transform, bonded<T, ProtocolReader>(reader)));
|
||||
Reader reader(input);
|
||||
|
||||
if (reader.ReadVersion())
|
||||
{
|
||||
return std::make_pair(
|
||||
static_cast<ProtocolType>(Reader::magic),
|
||||
Apply<Protocols>(transform, bonded<T, ProtocolReader>(reader)));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
else
|
||||
|
||||
template <typename Buffer, typename Transform, typename Reader>
|
||||
boost::optional<bool>
|
||||
operator()(Buffer& input, const Transform& transform, uint16_t protocol, const mpl::identity<Reader>&) const
|
||||
{
|
||||
return NextProtocol<T>(typename boost::mpl::next<Iter>::type(), end, input, transform);
|
||||
if (Reader::magic == protocol)
|
||||
{
|
||||
Reader reader(input);
|
||||
return Apply<Protocols>(transform, bonded<T, Reader&>(reader));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
template <template <typename Writer, typename ProtocolsT> class Transform>
|
||||
struct TransformFunctor
|
||||
{
|
||||
template <typename Buffer, typename Reader>
|
||||
boost::optional<bool>
|
||||
operator()(const T& value, Buffer& output, uint16_t protocol, const mpl::identity<Reader>&) const
|
||||
{
|
||||
if (Reader::magic == protocol)
|
||||
{
|
||||
using Writer = typename get_protocol_writer<Reader, Buffer>::type;
|
||||
|
||||
Writer writer(output);
|
||||
return Apply<Protocols>(Transform<Writer, Protocols>(writer), value);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <typename Protocols>
|
||||
struct NextProtocolFunctor<void, Protocols>
|
||||
{
|
||||
template <typename Buffer, typename Transform, typename Reader>
|
||||
boost::optional<std::pair<ProtocolType, bool> >
|
||||
operator()(const RuntimeSchema& schema, Buffer& input, const Transform& transform, const mpl::identity<Reader>&) const
|
||||
{
|
||||
Reader reader(input);
|
||||
|
||||
if (reader.ReadVersion())
|
||||
{
|
||||
return std::make_pair(
|
||||
static_cast<ProtocolType>(Reader::magic),
|
||||
Apply<Protocols>(transform, bonded<void, ProtocolReader>(reader, schema)));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename Buffer, typename Transform, typename Reader>
|
||||
boost::optional<bool>
|
||||
operator()(const RuntimeSchema& schema, Buffer& input, const Transform& transform, uint16_t protocol, const mpl::identity<Reader>&) const
|
||||
{
|
||||
if (Reader::magic == protocol)
|
||||
{
|
||||
Reader reader(input);
|
||||
return Apply<Protocols>(transform, bonded<void, Reader&>(reader, schema));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Select protocol and apply transform using compile-time schema
|
||||
template <typename T, typename Protocols, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(Buffer& input, const Transform& transform)
|
||||
{
|
||||
auto&& visitor =
|
||||
#ifndef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
[&](const auto& identity) { return NextProtocolFunctor<T, Protocols>{}(input, transform, identity); };
|
||||
#else
|
||||
std::bind(NextProtocolFunctor<T, Protocols>{}, std::ref(input), std::cref(transform), std::placeholders::_1);
|
||||
#endif
|
||||
|
||||
if (auto&& result = TryEachProtocol<typename Protocols::template FilterBuffer<Buffer> >(std::move(visitor)))
|
||||
{
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException();
|
||||
}
|
||||
|
||||
|
||||
// Select protocol and apply transform using runtime schema
|
||||
template <typename Buffer, typename Transform, typename EndIter>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(
|
||||
const EndIter&,
|
||||
const EndIter&,
|
||||
const RuntimeSchema&,
|
||||
Buffer&,
|
||||
const Transform&)
|
||||
template <typename Protocols, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(const RuntimeSchema& schema, Buffer& input, const Transform& transform)
|
||||
{
|
||||
UnknownProtocolException();
|
||||
return std::make_pair(MARSHALED_PROTOCOL, false);
|
||||
}
|
||||
auto&& visitor =
|
||||
#ifndef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
[&](const auto& identity) { return NextProtocolFunctor<void, Protocols>{}(schema, input, transform, identity); };
|
||||
#else
|
||||
std::bind(NextProtocolFunctor<void, Protocols>{}, std::cref(schema), std::ref(input), std::cref(transform), std::placeholders::_1);
|
||||
#endif
|
||||
|
||||
|
||||
template <typename Buffer, typename Transform, typename Iter, typename EndIter>
|
||||
inline std::pair<ProtocolType, bool> NextProtocol(
|
||||
const Iter&,
|
||||
const EndIter& end,
|
||||
const RuntimeSchema& schema,
|
||||
Buffer& input,
|
||||
const Transform& transform)
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iter>::type Reader;
|
||||
|
||||
Reader reader(input);
|
||||
|
||||
if (reader.ReadVersion())
|
||||
if (auto&& result = TryEachProtocol<typename Protocols::template FilterBuffer<Buffer> >(std::move(visitor)))
|
||||
{
|
||||
return std::make_pair(
|
||||
static_cast<ProtocolType>(Reader::magic),
|
||||
Apply(transform, bonded<void, ProtocolReader>(reader, schema)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NextProtocol(typename boost::mpl::next<Iter>::type(), end, schema, input, transform);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException();
|
||||
}
|
||||
|
||||
|
||||
// Select protocol based on magic number and apply transform using compile-time schema
|
||||
template <typename T, typename Buffer, typename Transform, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const EndIter&,
|
||||
const EndIter&,
|
||||
Buffer&,
|
||||
const Transform&, uint16_t protocol)
|
||||
template <typename T, typename Protocols, typename Buffer, typename Transform>
|
||||
inline bool NextProtocol(Buffer& input, const Transform& transform, uint16_t protocol)
|
||||
{
|
||||
auto&& visitor =
|
||||
#ifndef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
[&](const auto& identity) { return NextProtocolFunctor<T, Protocols>{}(input, transform, protocol, identity); };
|
||||
#else
|
||||
std::bind(NextProtocolFunctor<T, Protocols>{}, std::ref(input), std::cref(transform), protocol, std::placeholders::_1);
|
||||
#endif
|
||||
|
||||
if (auto&& result = TryEachProtocol<typename Protocols::template FilterBuffer<Buffer> >(std::move(visitor)))
|
||||
{
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException(protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename Buffer, typename Transform, typename Iter, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const Iter&,
|
||||
const EndIter& end,
|
||||
Buffer& input,
|
||||
const Transform& transform,
|
||||
uint16_t protocol)
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iter>::type Reader;
|
||||
|
||||
if (Reader::magic == protocol)
|
||||
{
|
||||
Reader reader(input);
|
||||
return Apply(transform, bonded<T, Reader&>(reader));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NextProtocol<T>(typename boost::mpl::next<Iter>::type(), end, input, transform, protocol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Select protocol based on magic number and apply transform using runtime schema
|
||||
template <typename Buffer, typename Transform, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const EndIter&,
|
||||
const EndIter&,
|
||||
const RuntimeSchema&, Buffer&, const Transform&, uint16_t protocol)
|
||||
template <typename Protocols, typename Buffer, typename Transform>
|
||||
inline bool NextProtocol(const RuntimeSchema& schema, Buffer& input, const Transform& transform, uint16_t protocol)
|
||||
{
|
||||
UnknownProtocolException(protocol);
|
||||
return false;
|
||||
}
|
||||
auto&& visitor =
|
||||
#ifndef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
[&](const auto& identity) { return NextProtocolFunctor<void, Protocols>{}(schema, input, transform, protocol, identity); };
|
||||
#else
|
||||
std::bind(NextProtocolFunctor<void, Protocols>{}, std::cref(schema), std::ref(input), std::cref(transform), protocol, std::placeholders::_1);
|
||||
#endif
|
||||
|
||||
|
||||
template <typename Buffer, typename Transform, typename Iter, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const Iter&,
|
||||
const EndIter& end,
|
||||
const RuntimeSchema& schema,
|
||||
Buffer& input,
|
||||
const Transform& transform,
|
||||
uint16_t protocol)
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iter>::type Reader;
|
||||
|
||||
if (Reader::magic == protocol)
|
||||
if (auto&& result = TryEachProtocol<typename Protocols::template FilterBuffer<Buffer> >(std::move(visitor)))
|
||||
{
|
||||
Reader reader(input);
|
||||
return Apply(transform, bonded<void, Reader&>(reader, schema));
|
||||
}
|
||||
else
|
||||
{
|
||||
return NextProtocol(typename boost::mpl::next<Iter>::type(), end, schema, input, transform, protocol);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException(protocol);
|
||||
}
|
||||
|
||||
|
||||
// Select protocol based on magic number and apply instance of serializing transform
|
||||
template <template <typename Writer> class Transform, typename Buffer, typename T, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const EndIter&,
|
||||
const EndIter&,
|
||||
const T&,
|
||||
Buffer&,
|
||||
uint16_t protocol)
|
||||
template <template <typename Writer, typename ProtocolsT> class Transform, typename Protocols, typename T, typename Buffer>
|
||||
inline bool NextProtocol(const T& value, Buffer& output, uint16_t protocol)
|
||||
{
|
||||
using TransformFunctor = typename NextProtocolFunctor<T, Protocols>::template TransformFunctor<Transform>;
|
||||
|
||||
auto&& visitor =
|
||||
#ifndef BOND_NO_CXX14_GENERIC_LAMBDAS
|
||||
[&](const auto& identity) { return TransformFunctor{}(value, output, protocol, identity); };
|
||||
#else
|
||||
std::bind(TransformFunctor{}, std::cref(value), std::ref(output), protocol, std::placeholders::_1);
|
||||
#endif
|
||||
|
||||
if (auto&& result = TryEachProtocol<typename Protocols::FilterEnabled>(std::move(visitor)))
|
||||
{
|
||||
return result.get();
|
||||
}
|
||||
|
||||
UnknownProtocolException(protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <template <typename Writer> class Transform, typename Buffer, typename T, typename Iter, typename EndIter>
|
||||
inline bool NextProtocol(
|
||||
const Iter&,
|
||||
const EndIter& end,
|
||||
const T& value,
|
||||
Buffer& output,
|
||||
uint16_t protocol)
|
||||
{
|
||||
typedef typename boost::mpl::deref<Iter>::type Reader;
|
||||
|
||||
if (Reader::magic == protocol)
|
||||
{
|
||||
typedef typename get_protocol_writer<Reader, Buffer>::type Writer;
|
||||
|
||||
Writer writer(output);
|
||||
return Apply(Transform<Writer>(writer), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NextProtocol<Transform>(typename boost::mpl::next<Iter>::type(), end, value, output, protocol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -217,74 +238,48 @@ inline bool NextProtocol(
|
|||
|
||||
|
||||
// Use compile-time schema
|
||||
template <typename T, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> SelectProtocolAndApply(
|
||||
Buffer& input,
|
||||
const Transform& transform)
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> SelectProtocolAndApply(Buffer& input, const Transform& transform)
|
||||
{
|
||||
return detail::NextProtocol<T>(typename FilteredProtocols<Buffer>::begin(), typename FilteredProtocols<Buffer>::end(), input, transform);
|
||||
return detail::NextProtocol<T, Protocols>(input, transform);
|
||||
}
|
||||
|
||||
|
||||
// Use runtime schema
|
||||
template <typename Buffer, typename Transform>
|
||||
template <typename Protocols = BuiltInProtocols, typename Buffer, typename Transform>
|
||||
inline std::pair<ProtocolType, bool> SelectProtocolAndApply(
|
||||
const RuntimeSchema& schema,
|
||||
Buffer& input,
|
||||
const Transform& transform)
|
||||
{
|
||||
return detail::NextProtocol(typename FilteredProtocols<Buffer>::begin(), typename FilteredProtocols<Buffer>::end(), schema, input, transform);
|
||||
return detail::NextProtocol<Protocols>(schema, input, transform);
|
||||
}
|
||||
|
||||
|
||||
// Apply deserializing transform with a protocol specified by magic number
|
||||
// Use compile-time schema
|
||||
template <typename T, typename Buffer, typename Transform>
|
||||
inline bool Apply(
|
||||
const Transform& transform,
|
||||
Buffer& input,
|
||||
uint16_t protocol)
|
||||
template <typename T, typename Protocols = BuiltInProtocols, typename Transform, typename Buffer>
|
||||
inline bool Apply(const Transform& transform, Buffer& input, uint16_t protocol)
|
||||
{
|
||||
return detail::NextProtocol<T>(
|
||||
typename FilteredProtocols<Buffer>::begin(),
|
||||
typename FilteredProtocols<Buffer>::end(),
|
||||
input,
|
||||
transform,
|
||||
protocol
|
||||
);
|
||||
return detail::NextProtocol<T, Protocols>(input, transform, protocol);
|
||||
}
|
||||
|
||||
|
||||
// Use runtime schema
|
||||
template <typename Buffer, typename Transform>
|
||||
inline bool Apply(
|
||||
const Transform& transform,
|
||||
const RuntimeSchema& schema,
|
||||
Buffer& input,
|
||||
uint16_t protocol)
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform, typename Buffer>
|
||||
inline bool Apply(const Transform& transform, const RuntimeSchema& schema, Buffer& input, uint16_t protocol)
|
||||
{
|
||||
return detail::NextProtocol(
|
||||
typename FilteredProtocols<Buffer>::begin(),
|
||||
typename FilteredProtocols<Buffer>::end(),
|
||||
schema,
|
||||
input,
|
||||
transform,
|
||||
protocol
|
||||
);
|
||||
return detail::NextProtocol<Protocols>(schema, input, transform, protocol);
|
||||
}
|
||||
|
||||
|
||||
// Apply an instance of serializing transform with a protocol specified by magic number
|
||||
template <template <typename Writer> class Transform, typename Buffer, typename T>
|
||||
template <template <typename Writer, typename ProtocolsT> class Transform, typename Protocols = BuiltInProtocols, typename T, typename Buffer>
|
||||
inline bool Apply(const T& value, Buffer& output, uint16_t protocol)
|
||||
{
|
||||
return detail::NextProtocol<Transform>(
|
||||
Protocols::begin(),
|
||||
Protocols::end(),
|
||||
value,
|
||||
output,
|
||||
protocol);
|
||||
return detail::NextProtocol<Transform, Protocols>(value, output, protocol);
|
||||
}
|
||||
|
||||
|
||||
} // namespace bond
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "bond_fwd.h"
|
||||
#include <boost/type_traits/has_nothrow_copy.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#ifndef BOND_NO_CXX11_HDR_TYPE_TRAITS
|
||||
# include <type_traits>
|
||||
|
@ -99,9 +100,15 @@ is_protocol_same
|
|||
: false_type {};
|
||||
|
||||
|
||||
template <template <typename T> class Reader, typename I, template <typename T> class Writer, typename O> struct
|
||||
is_protocol_same<Reader<I>, Writer<O> >
|
||||
: is_same<typename Reader<O>::Writer, Writer<O> > {};
|
||||
template <template <typename T> class Reader, typename Input, template <typename T> class Writer, typename Output> struct
|
||||
is_protocol_same<Reader<Input>, Writer<Output> >
|
||||
: is_same<typename Reader<Output>::Writer, Writer<Output> > {};
|
||||
|
||||
|
||||
template <template <typename T, typename U> class Reader, typename Input, typename MarshaledBondedProtocols, template <typename T> class Writer, typename Output> struct
|
||||
is_protocol_same<Reader<Input, MarshaledBondedProtocols>, Writer<Output> >
|
||||
: is_same<typename Reader<Output, MarshaledBondedProtocols>::Writer, Writer<Output> > {};
|
||||
|
||||
|
||||
// For protocols that have multiple versions, specialize this template...
|
||||
template <typename Reader> struct
|
||||
|
@ -168,6 +175,40 @@ template <typename T> struct
|
|||
is_type_alias
|
||||
: is_object<typename aliased_type<T>::type> {};
|
||||
|
||||
|
||||
// is_reader
|
||||
template <typename Input, typename T = void, typename Enable = void> struct
|
||||
is_reader
|
||||
: false_type {};
|
||||
|
||||
template <typename Input, typename T> struct
|
||||
is_reader<Input&, T>
|
||||
: is_reader<Input, T> {};
|
||||
|
||||
template <typename Input, typename T> struct
|
||||
is_reader<Input, T, typename boost::enable_if<is_class<typename Input::Parser> >::type>
|
||||
: true_type {};
|
||||
|
||||
|
||||
template <typename T> struct
|
||||
buffer_magic
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_same<T, T>::value, "Undefined buffer.");
|
||||
};
|
||||
|
||||
template <typename T> struct
|
||||
buffer_magic<T&>
|
||||
: buffer_magic<T> {};
|
||||
|
||||
|
||||
template <uint16_t Id> struct
|
||||
unique_buffer_magic_check;
|
||||
|
||||
#define BOND_DEFINE_BUFFER_MAGIC(Buffer, Id) \
|
||||
template <> struct unique_buffer_magic_check<Id> {}; \
|
||||
template <> struct buffer_magic<Buffer> : std::integral_constant<uint16_t, Id> {}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "bond_fwd.h"
|
||||
#include "reflection.h"
|
||||
#include "exception.h"
|
||||
#include "null.h"
|
||||
|
@ -39,7 +40,7 @@ namespace detail
|
|||
// Applying this transform to input from parsing serialized data is equivalent
|
||||
// to transcoding from one protocol to another.
|
||||
//
|
||||
template <typename Writer>
|
||||
template <typename Writer, typename Protocols>
|
||||
class Serializer
|
||||
: public SerializingTransform
|
||||
{
|
||||
|
@ -60,9 +61,9 @@ public:
|
|||
}
|
||||
|
||||
template <typename Pass0>
|
||||
Serializer<Pass0> Rebind(Pass0& pass0) const
|
||||
Serializer<Pass0, Protocols> Rebind(Pass0& pass0) const
|
||||
{
|
||||
return Serializer<Pass0>(pass0);
|
||||
return Serializer<Pass0, Protocols>(pass0);
|
||||
}
|
||||
|
||||
void Begin(const Metadata& metadata) const
|
||||
|
@ -84,7 +85,7 @@ public:
|
|||
bool Base(const T& value) const
|
||||
{
|
||||
// 'true' means that we are writing a base struct
|
||||
Apply(Serializer<Writer>(_output, true), value);
|
||||
Apply<Protocols>(Serializer(_output, true), value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -199,7 +200,7 @@ private:
|
|||
typename boost::enable_if<is_bond_type<T> >::type
|
||||
Write(const T& value) const
|
||||
{
|
||||
Apply(Serializer<Writer>(_output), value);
|
||||
Apply<Protocols>(Serializer(_output), value);
|
||||
}
|
||||
|
||||
// bonded<T> and untagged writer
|
||||
|
@ -207,7 +208,7 @@ private:
|
|||
typename boost::enable_if<uses_marshaled_bonded<typename Writer::Reader, T> >::type
|
||||
Write(const bonded<T>& value) const
|
||||
{
|
||||
detail::MarshalToBlob(value, _output);
|
||||
detail::MarshalToBlob<Protocols>(value, _output);
|
||||
}
|
||||
|
||||
// bonded<void> and untagged writer
|
||||
|
@ -215,7 +216,7 @@ private:
|
|||
typename boost::enable_if<uses_marshaled_bonded<typename Writer::Reader, Reader> >::type
|
||||
Write(const bonded<void, Reader>& value) const
|
||||
{
|
||||
value.Serialize(_output);
|
||||
value.template Serialize<Protocols>(_output);
|
||||
}
|
||||
|
||||
// 2-tuple
|
||||
|
@ -258,7 +259,7 @@ private:
|
|||
{
|
||||
T data = T();
|
||||
|
||||
value.Deserialize(data);
|
||||
value.template Deserialize<Protocols>(data);
|
||||
Write(data);
|
||||
}
|
||||
|
||||
|
@ -266,11 +267,11 @@ private:
|
|||
typename boost::disable_if<is_basic_type<T> >::type
|
||||
Write(const value<T, Reader>& value) const
|
||||
{
|
||||
Apply(Serializer<Writer>(_output), value);
|
||||
Apply<Protocols>(Serializer(_output), value);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename WriterT>
|
||||
template <typename T, typename WriterT, typename ProtocolsT>
|
||||
friend class Merger;
|
||||
|
||||
template <typename T, typename Reader, typename Enable>
|
||||
|
@ -279,7 +280,7 @@ private:
|
|||
template <typename T, typename Schema, typename Transform>
|
||||
friend class detail::_Parser;
|
||||
|
||||
template <typename Transform, typename T>
|
||||
template <typename ProtocolsT, typename Transform, typename T>
|
||||
friend bool detail::DoublePassApply(const Transform&, const T&);
|
||||
|
||||
protected:
|
||||
|
@ -289,29 +290,29 @@ protected:
|
|||
|
||||
|
||||
// SerializeTo
|
||||
template <typename Writer>
|
||||
Serializer<Writer> SerializeTo(Writer& output)
|
||||
template <typename Protocols, typename Writer>
|
||||
Serializer<Writer, Protocols> SerializeTo(Writer& output)
|
||||
{
|
||||
return Serializer<Writer>(output);
|
||||
return Serializer<Writer, Protocols>(output);
|
||||
}
|
||||
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Writer, typename Protocols>
|
||||
class Marshaler
|
||||
: protected Serializer<Writer>
|
||||
: protected Serializer<Writer, Protocols>
|
||||
{
|
||||
public:
|
||||
typedef Writer writer_type;
|
||||
|
||||
Marshaler(Writer& output)
|
||||
: Serializer<Writer>(output)
|
||||
: Serializer<Writer, Protocols>(output)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
bool Marshal(const T& value) const
|
||||
{
|
||||
this->_output.WriteVersion();
|
||||
return Apply(static_cast<const Serializer<Writer>&>(*this), value);
|
||||
return Apply<Protocols>(static_cast<const Serializer<Writer, Protocols>&>(*this), value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -319,17 +320,17 @@ public:
|
|||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Writer, typename T, typename Reader>
|
||||
template <typename Protocols, typename Writer, typename T, typename Reader>
|
||||
bool inline
|
||||
ApplyTransform(const Marshaler<Writer>& marshaler, const bonded<T, Reader>& bonded)
|
||||
ApplyTransform(const Marshaler<Writer, Protocols>& marshaler, const bonded<T, Reader>& bonded)
|
||||
{
|
||||
return marshaler.Marshal(bonded);
|
||||
}
|
||||
|
||||
|
||||
template <typename Writer, typename T>
|
||||
template <typename Protocols, typename Writer, typename T>
|
||||
bool inline
|
||||
ApplyTransform(const Marshaler<Writer>& marshaler, const T& value)
|
||||
ApplyTransform(const Marshaler<Writer, Protocols>& marshaler, const T& value)
|
||||
{
|
||||
return marshaler.Marshal(value);
|
||||
}
|
||||
|
@ -338,10 +339,10 @@ ApplyTransform(const Marshaler<Writer>& marshaler, const T& value)
|
|||
|
||||
|
||||
// MarshalTo
|
||||
template <typename Writer>
|
||||
Marshaler<Writer> MarshalTo(Writer& output)
|
||||
template <typename Protocols, typename Writer>
|
||||
Marshaler<Writer, Protocols> MarshalTo(Writer& output)
|
||||
{
|
||||
return Marshaler<Writer>(output);
|
||||
return Marshaler<Writer, Protocols>(output);
|
||||
}
|
||||
|
||||
|
||||
|
@ -410,6 +411,7 @@ void RequiredFieldValiadator<T>::MissingFieldException() const
|
|||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Protocols>
|
||||
class To
|
||||
: public DeserializingTransform
|
||||
{
|
||||
|
@ -426,20 +428,20 @@ protected:
|
|||
template <typename V, typename X>
|
||||
void AssignToVar(V& var, const X& value) const
|
||||
{
|
||||
value.Deserialize(var);
|
||||
value.template Deserialize<Protocols>(var);
|
||||
}
|
||||
|
||||
template <typename V, typename X>
|
||||
void AssignToVar(maybe<V>& var, const X& value) const
|
||||
{
|
||||
value.Deserialize(var.set_value());
|
||||
value.template Deserialize<Protocols>(var.set_value());
|
||||
}
|
||||
|
||||
template <typename V, typename X>
|
||||
typename boost::enable_if<has_base<V>, bool>::type
|
||||
AssignToBase(V& var, const X& value) const
|
||||
{
|
||||
return Apply(bond::To<typename schema<V>::type::base>(var), value);
|
||||
return Apply<Protocols>(bond::To<typename schema<V>::type::base, Protocols>(var), value);
|
||||
}
|
||||
|
||||
template <typename V, typename X>
|
||||
|
@ -459,9 +461,9 @@ protected:
|
|||
} // namespace detail
|
||||
|
||||
|
||||
template <typename T, typename Validator>
|
||||
template <typename T, typename Protocols, typename Validator>
|
||||
class To
|
||||
: public detail::To,
|
||||
: public detail::To<Protocols>,
|
||||
protected Validator
|
||||
{
|
||||
public:
|
||||
|
@ -536,8 +538,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
using detail::To::AssignToBase;
|
||||
using detail::To::AssignToField;
|
||||
using detail::To<Protocols>::AssignToBase;
|
||||
using detail::To<Protocols>::AssignToVar;
|
||||
using detail::To<Protocols>::AssignToField;
|
||||
|
||||
template <typename Fields, typename X>
|
||||
bool AssignToField(const Fields&, uint16_t id, const X& value) const
|
||||
|
@ -582,6 +585,7 @@ BOND_STATIC_CONSTEXPR uint16_t mapping_base = invalid_field_id;
|
|||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Protocols>
|
||||
class MapTo
|
||||
: public DeserializingTransform
|
||||
{
|
||||
|
@ -602,7 +606,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
struct PathView
|
||||
struct PathView
|
||||
: boost::noncopyable
|
||||
{
|
||||
PathView(const Path& path)
|
||||
|
@ -730,23 +734,23 @@ protected:
|
|||
template <typename V, typename X>
|
||||
void AssignToVar(V& var, const X& value) const
|
||||
{
|
||||
value.Deserialize(var);
|
||||
value.template Deserialize<Protocols>(var);
|
||||
}
|
||||
|
||||
|
||||
template <typename V, typename X>
|
||||
void AssignToVar(maybe<V>& var, const X& value) const
|
||||
{
|
||||
value.Deserialize(var.set_value());
|
||||
value.template Deserialize<Protocols>(var.set_value());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename Protocols = BuiltInProtocols>
|
||||
class MapTo
|
||||
: public detail::MapTo
|
||||
: public detail::MapTo<Protocols>
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_ASSERT(has_schema<T>::value);
|
||||
|
@ -763,7 +767,7 @@ public:
|
|||
Mappings::const_iterator it = _mappings.find(mapping_base);
|
||||
|
||||
if (it != _mappings.end())
|
||||
return Apply(MapTo(_var, it->second.fields), value);
|
||||
return Apply<Protocols>(MapTo(_var, it->second.fields), value);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -781,7 +785,7 @@ public:
|
|||
return Apply(MapTo(_var, it->second.fields), value);
|
||||
|
||||
if (!it->second.path.empty())
|
||||
return Assign(_var, it->second.path, value);
|
||||
return this->Assign(_var, it->second.path, value);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -795,7 +799,7 @@ public:
|
|||
Mappings::const_iterator it = _mappings.find(id);
|
||||
|
||||
if (it != _mappings.end() && !it->second.path.empty())
|
||||
return Assign(_var, it->second.path, value);
|
||||
return this->Assign(_var, it->second.path, value);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace bond
|
|||
/// are different but payload in source schema can be deserialized as destination.
|
||||
/// @throw SchemaValidateException if payload in source schema is incompatible
|
||||
/// with destination schema.
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
inline bool Validate(const RuntimeSchema& src,
|
||||
const RuntimeSchema& dst)
|
||||
{
|
||||
|
@ -38,14 +39,15 @@ inline bool Validate(const RuntimeSchema& src,
|
|||
/// are different but payload in source schema can be deserialized as destination.
|
||||
/// @throw SchemaValidateException if payload in source schema is incompatible
|
||||
/// with destination schema or the schema of source SchemaDef is unknown.
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
inline bool Validate(const bonded<SchemaDef>& src,
|
||||
const RuntimeSchema& dst)
|
||||
{
|
||||
Apply(detail::SchemaValidator(), src);
|
||||
Apply<Protocols>(detail::SchemaValidator<Protocols>(), src);
|
||||
|
||||
SchemaDef schema;
|
||||
src.Deserialize(schema);
|
||||
return Validate(RuntimeSchema(schema), dst);
|
||||
src.template Deserialize<Protocols>(schema);
|
||||
return Validate<Protocols>(RuntimeSchema(schema), dst);
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,14 +58,15 @@ inline bool Validate(const bonded<SchemaDef>& src,
|
|||
/// are different but payload in source schema can be deserialized as destination.
|
||||
/// @throw SchemaValidateException if payload in source schema is incompatible
|
||||
/// with destination schema or the schema of destination SchemaDef is unknown.
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
inline bool Validate(const RuntimeSchema& src,
|
||||
const bonded<SchemaDef>& dst)
|
||||
{
|
||||
Apply(detail::SchemaValidator(), dst);
|
||||
Apply<Protocols>(detail::SchemaValidator<Protocols>(), dst);
|
||||
|
||||
SchemaDef schema;
|
||||
dst.Deserialize(schema);
|
||||
return Validate(src, RuntimeSchema(schema));
|
||||
dst.template Deserialize<Protocols>(schema);
|
||||
return Validate<Protocols>(src, RuntimeSchema(schema));
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,10 +78,10 @@ inline bool Validate(const RuntimeSchema& src,
|
|||
/// and vice versa.
|
||||
/// @throw SchemaValidateException if payload in any one schema is incompatible
|
||||
/// with the other schema.
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = BuiltInProtocols, typename T1, typename T2>
|
||||
inline bool ValidateTwoWay(const T1& s1, const T2& s2)
|
||||
{
|
||||
return Validate(s1, s2) & Validate(s2, s1);
|
||||
return Validate<Protocols>(s1, s2) & Validate<Protocols>(s2, s1);
|
||||
}
|
||||
|
||||
} // namespace bond
|
||||
|
|
|
@ -32,7 +32,9 @@ inline set(X& var, const T& value)
|
|||
set_aliased_value(var, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <typename X, typename T>
|
||||
inline X cast(const T& value)
|
||||
|
@ -209,7 +211,7 @@ public:
|
|||
}
|
||||
|
||||
// skip value of non-matching type
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::disable_if_c<is_matching<T, X>::value>::type
|
||||
Deserialize(X& /*var*/) const
|
||||
{
|
||||
|
@ -247,6 +249,7 @@ public:
|
|||
#endif
|
||||
|
||||
/// @brief Deserialize the value
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
void Deserialize(T& var) const
|
||||
{
|
||||
_skip = false;
|
||||
|
@ -255,6 +258,7 @@ public:
|
|||
|
||||
|
||||
// deserialize series of matching values to blob
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
void Deserialize(blob& var, uint32_t size) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T, blob::value_type>::value));
|
||||
|
@ -264,7 +268,7 @@ public:
|
|||
|
||||
|
||||
// deserialize the value and cast it to a variable of a matching non-string type
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if_c<is_matching_basic<T, X>::value && !is_string_type<T>::value>::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
|
@ -277,7 +281,7 @@ public:
|
|||
|
||||
|
||||
// deserialize the value to a variable of a matching string type
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if_c<is_matching_basic<T, X>::value && is_string_type<T>::value>::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
|
@ -316,6 +320,7 @@ public:
|
|||
value& operator=(const value& that) = default;
|
||||
#endif
|
||||
|
||||
template <typename Protocols = BuiltInProtocols>
|
||||
void Deserialize(T& var) const
|
||||
{
|
||||
typename aliased_type<T>::type value;
|
||||
|
@ -353,20 +358,20 @@ public:
|
|||
#endif
|
||||
|
||||
// deserialize Bond struct into matching variable
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if<is_bond_type<X> >::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
_skip = false;
|
||||
bonded<T, Reader>(_input).Deserialize(var);
|
||||
bonded<T, Reader>(_input).template Deserialize<Protocols>(var);
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform>
|
||||
void _Apply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
Apply(transform, bonded<T, Reader>(_input));
|
||||
Apply<Protocols>(transform, bonded<T, Reader>(_input));
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,6 +393,23 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <typename Protocols, typename X, typename T1, typename T2, typename Reader>
|
||||
inline void DeserializeContainer(X& var, const value<std::pair<T1, T2>, Reader&>&, Reader& input);
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::disable_if<is_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input);
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_nested_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input);
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_basic_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input);
|
||||
|
||||
|
||||
|
||||
// Specialization of value for containers with compile-time schema
|
||||
template <typename T, typename Reader>
|
||||
class value<T, Reader, typename boost::enable_if<is_container<T> >::type>
|
||||
|
@ -411,20 +433,20 @@ public:
|
|||
#endif
|
||||
|
||||
// Deserialize container
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if_c<is_matching_container<T, X>::value>::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
_skip = false;
|
||||
DeserializeContainer(var, value<typename element_type<T>::type, Reader>(_input, false), _input);
|
||||
DeserializeContainer<Protocols>(var, value<typename element_type<T>::type, Reader>(_input, false), _input);
|
||||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform>
|
||||
void _Apply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
DeserializeContainer(transform, value<typename element_type<T>::type, Reader>(_input, false), _input);
|
||||
DeserializeContainer<Protocols>(transform, value<typename element_type<T>::type, Reader>(_input, false), _input);
|
||||
}
|
||||
|
||||
using value_common<T, Reader>::Deserialize;
|
||||
|
@ -436,6 +458,18 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::disable_if<is_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input);
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_nested_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input);
|
||||
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_basic_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input);
|
||||
|
||||
|
||||
// Specialization of value for data described by runtime schema
|
||||
template <typename Reader>
|
||||
|
@ -491,14 +525,14 @@ public:
|
|||
|
||||
|
||||
// Deserialize container
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if_c<is_container<X>::value && !is_map_container<X>::value>::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
if (_schema.GetTypeId() == get_type_id<X>::value)
|
||||
{
|
||||
_skip = false;
|
||||
DeserializeContainer(var,
|
||||
DeserializeContainer<Protocols>(var,
|
||||
value<void, Reader>(_input, element_schema(_schema), false), _input);
|
||||
}
|
||||
else
|
||||
|
@ -509,14 +543,14 @@ public:
|
|||
|
||||
|
||||
// Deserialize map
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if<is_map_container<X> >::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
if (_schema.GetTypeId() == get_type_id<X>::value)
|
||||
{
|
||||
_skip = false;
|
||||
DeserializeMap(var, key_schema(_schema).GetTypeId(),
|
||||
DeserializeMap<Protocols>(var, key_schema(_schema).GetTypeId(),
|
||||
value<void, Reader>(_input, element_schema(_schema), false), _input);
|
||||
}
|
||||
else
|
||||
|
@ -527,14 +561,14 @@ public:
|
|||
|
||||
|
||||
// Deserialize Bond struct
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::enable_if<is_bond_type<X> >::type
|
||||
Deserialize(X& var) const
|
||||
{
|
||||
if (_schema.GetTypeId() == get_type_id<X>::value)
|
||||
{
|
||||
_skip = false;
|
||||
bonded<void, Reader>(_input, _schema).Deserialize(var);
|
||||
bonded<void, Reader>(_input, _schema).template Deserialize<Protocols>(var);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -543,32 +577,32 @@ public:
|
|||
}
|
||||
|
||||
|
||||
template <typename Transform>
|
||||
template <typename Protocols = BuiltInProtocols, typename Transform>
|
||||
void _Apply(const Transform& transform) const
|
||||
{
|
||||
_skip = false;
|
||||
|
||||
if (_schema.GetTypeId() == bond::BT_STRUCT)
|
||||
{
|
||||
Apply(transform, bonded<void, Reader>(_input, _schema));
|
||||
Apply<Protocols>(transform, bonded<void, Reader>(_input, _schema));
|
||||
}
|
||||
else if(_schema.GetTypeId() == bond::BT_MAP)
|
||||
{
|
||||
DeserializeMap(transform, key_schema(_schema).GetTypeId(),
|
||||
DeserializeMap<Protocols>(transform, key_schema(_schema).GetTypeId(),
|
||||
value<void, Reader>(_input, element_schema(_schema), false), _input);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(_schema.GetTypeId() == bond::BT_LIST || _schema.GetTypeId() == bond::BT_SET);
|
||||
|
||||
DeserializeContainer(transform,
|
||||
DeserializeContainer<Protocols>(transform,
|
||||
value<void, Reader>(_input, element_schema(_schema), false), _input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// skip value of non-matching type
|
||||
template <typename X>
|
||||
template <typename Protocols = BuiltInProtocols, typename X>
|
||||
typename boost::disable_if_c<is_container<X>::value || is_bond_type<X>::value>::type
|
||||
Deserialize(X& /*var*/) const
|
||||
{
|
||||
|
@ -595,7 +629,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
template <typename X, typename I, typename T>
|
||||
template <typename Protocols, typename X, typename I, typename T>
|
||||
typename boost::enable_if<require_modify_element<X> >::type
|
||||
inline DeserializeElement(X& var, const I& item, const T& element)
|
||||
{
|
||||
|
@ -607,7 +641,7 @@ inline DeserializeElement(X& var, const I& item, const T& element)
|
|||
|
||||
void operator()(typename element_type<X>::type& e)
|
||||
{
|
||||
this->element.Deserialize(e);
|
||||
this->element.template Deserialize<Protocols>(e);
|
||||
}
|
||||
|
||||
const T& element;
|
||||
|
@ -617,16 +651,16 @@ inline DeserializeElement(X& var, const I& item, const T& element)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename I, typename T>
|
||||
template <typename Protocols, typename X, typename I, typename T>
|
||||
typename boost::disable_if<require_modify_element<X> >::type
|
||||
inline DeserializeElement(X&, I& item, const T& element)
|
||||
{
|
||||
element.Deserialize(item);
|
||||
element.template Deserialize<Protocols>(item);
|
||||
}
|
||||
|
||||
|
||||
// Read elements of a list
|
||||
template <typename X, typename T>
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::enable_if_c<is_list_container<X>::value
|
||||
&& is_element_matching<T, X>::value>::type
|
||||
inline DeserializeElements(X& var, const T& element, uint32_t size)
|
||||
|
@ -634,18 +668,18 @@ inline DeserializeElements(X& var, const T& element, uint32_t size)
|
|||
resize_list(var, size);
|
||||
|
||||
for (enumerator<X> items(var); items.more();)
|
||||
DeserializeElement(var, items.next(), element);
|
||||
DeserializeElement<Protocols>(var, items.next(), element);
|
||||
}
|
||||
|
||||
|
||||
template <typename X, typename Allocator, bool useValue, typename T>
|
||||
template <typename Protocols, typename X, typename Allocator, bool useValue, typename T>
|
||||
typename boost::enable_if<is_matching<T, X> >::type
|
||||
inline DeserializeElements(nullable<X, Allocator, useValue>& var, const T& element, uint32_t size)
|
||||
{
|
||||
resize_list(var, size);
|
||||
|
||||
for (enumerator<nullable<X, Allocator, useValue> > items(var); items.more(); --size)
|
||||
element.Deserialize(items.next());
|
||||
element.template Deserialize<Protocols>(items.next());
|
||||
|
||||
// Wire representation and interface for nullable is the same as for list.
|
||||
// However nullable can "contain" at most one element. If there are more
|
||||
|
@ -655,14 +689,14 @@ inline DeserializeElements(nullable<X, Allocator, useValue>& var, const T& eleme
|
|||
}
|
||||
|
||||
|
||||
template <typename Reader>
|
||||
template <typename Protocols, typename Reader>
|
||||
inline void DeserializeElements(blob& var, const value<blob::value_type, Reader&>& element, uint32_t size)
|
||||
{
|
||||
element.Deserialize(var, size);
|
||||
element.template Deserialize<Protocols>(var, size);
|
||||
}
|
||||
|
||||
|
||||
template <typename X, typename T>
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::enable_if_c<is_set_container<X>::value
|
||||
&& is_element_matching<T, X>::value>::type
|
||||
inline DeserializeElements(X& var, const T& element, uint32_t size)
|
||||
|
@ -673,13 +707,13 @@ inline DeserializeElements(X& var, const T& element, uint32_t size)
|
|||
|
||||
while (size--)
|
||||
{
|
||||
element.Deserialize(e);
|
||||
element.template Deserialize<Protocols>(e);
|
||||
set_insert(var, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename X, typename T>
|
||||
template <typename Protocols, typename X, typename T>
|
||||
typename boost::disable_if<is_element_matching<T, X> >::type
|
||||
inline DeserializeElements(X&, const T& element, uint32_t size)
|
||||
{
|
||||
|
@ -688,7 +722,7 @@ inline DeserializeElements(X&, const T& element, uint32_t size)
|
|||
}
|
||||
|
||||
|
||||
template <typename Transform, typename T>
|
||||
template <typename Protocols, typename Transform, typename T>
|
||||
inline void DeserializeElements(const Transform& transform, const T& element, uint32_t size)
|
||||
{
|
||||
transform.Container(element, size);
|
||||
|
@ -723,14 +757,14 @@ inline void SkipContainer(const T& element, Reader& input)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T1, typename T2, typename Reader>
|
||||
template <typename Protocols, typename X, typename T1, typename T2, typename Reader>
|
||||
inline void DeserializeContainer(X& var, const value<std::pair<T1, T2>, Reader&>&, Reader& input)
|
||||
{
|
||||
return DeserializeMap(var, get_type_id<T1>::value, value<T2, Reader&>(input, false), input);
|
||||
return DeserializeMap<Protocols>(var, get_type_id<T1>::value, value<T2, Reader&>(input, false), input);
|
||||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::disable_if<is_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -748,17 +782,17 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
{
|
||||
if (type == GetTypeId(element))
|
||||
{
|
||||
DeserializeElements(var, element, size);
|
||||
DeserializeElements<Protocols>(var, element, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeserializeElements(var, value<void, Reader&>(input, type, false), size);
|
||||
DeserializeElements<Protocols>(var, value<void, Reader&>(input, type, false), size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
detail::BasicTypeContainer(var, type, input, size);
|
||||
detail::BasicTypeContainer<Protocols>(var, type, input, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -767,7 +801,7 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_nested_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -778,7 +812,7 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
|
||||
if (type == GetTypeId(element))
|
||||
{
|
||||
DeserializeElements(var, element, size);
|
||||
DeserializeElements<Protocols>(var, element, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -790,7 +824,7 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_basic_container<X> >::type
|
||||
inline DeserializeContainer(X& var, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -820,7 +854,7 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
}
|
||||
default:
|
||||
{
|
||||
detail::MatchingTypeContainer(var, type, input, size);
|
||||
detail::MatchingTypeContainer<Protocols>(var, type, input, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -829,7 +863,7 @@ inline DeserializeContainer(X& var, const T& element, Reader& input)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename Key, typename T>
|
||||
template <typename Protocols, typename X, typename Key, typename T>
|
||||
typename boost::enable_if<is_map_key_matching<Key, X> >::type
|
||||
inline DeserializeMapElements(X& var, const Key& key, const T& element, uint32_t size)
|
||||
{
|
||||
|
@ -841,21 +875,21 @@ inline DeserializeMapElements(X& var, const Key& key, const T& element, uint32_t
|
|||
|
||||
while (size--)
|
||||
{
|
||||
key.Deserialize(k);
|
||||
key.template Deserialize<Protocols>(k);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// In debug build To<T> asserts that optional fields are set to default
|
||||
// values before deserialization; if invalid map payload contains duplicate
|
||||
// keys the second time we deserialize a value it will trigger the assert.
|
||||
element.Deserialize(mapped_at(var, k) = make_value(var));
|
||||
element.template Deserialize<Protocols>(mapped_at(var, k) = make_value(var));
|
||||
#else
|
||||
element.Deserialize(mapped_at(var, k));
|
||||
element.template Deserialize<Protocols>(mapped_at(var, k));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename X, typename Key, typename T>
|
||||
template <typename Protocols, typename X, typename Key, typename T>
|
||||
typename boost::disable_if<is_map_key_matching<Key, X> >::type
|
||||
inline DeserializeMapElements(X&, const Key& key, const T& element, uint32_t size)
|
||||
{
|
||||
|
@ -867,7 +901,7 @@ inline DeserializeMapElements(X&, const Key& key, const T& element, uint32_t siz
|
|||
}
|
||||
|
||||
|
||||
template <typename Transform, typename Key, typename T>
|
||||
template <typename Protocols, typename Transform, typename Key, typename T>
|
||||
inline void DeserializeMapElements(const Transform& transform, const Key& key, const T& element, uint32_t size)
|
||||
{
|
||||
transform.Container(key, element, size);
|
||||
|
@ -897,7 +931,7 @@ inline void SkipMap(BondDataType keyType, const T& element, Reader& input)
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::disable_if<is_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -915,17 +949,17 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
{
|
||||
if (type.second == GetTypeId(element))
|
||||
{
|
||||
detail::MapByKey(var, type.first, element, input, size);
|
||||
detail::MapByKey<Protocols>(var, type.first, element, input, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::MapByKey(var, type.first, value<void, Reader&>(input, type.second, false), input, size);
|
||||
detail::MapByKey<Protocols>(var, type.first, value<void, Reader&>(input, type.second, false), input, size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
detail::MapByElement(var, type.first, type.second, input, size);
|
||||
detail::MapByElement<Protocols>(var, type.first, type.second, input, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -934,7 +968,7 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_nested_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -945,7 +979,7 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
|
||||
if (type.second == GetTypeId(element))
|
||||
{
|
||||
detail::MapByKey(var, type.first, element, input, size);
|
||||
detail::MapByKey<Protocols>(var, type.first, element, input, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -960,7 +994,7 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
}
|
||||
|
||||
|
||||
template <typename X, typename T, typename Reader>
|
||||
template <typename Protocols, typename X, typename T, typename Reader>
|
||||
typename boost::enable_if<is_basic_container<X> >::type
|
||||
inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& input)
|
||||
{
|
||||
|
@ -996,7 +1030,7 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
}
|
||||
default:
|
||||
{
|
||||
detail::MatchingMapByElement(var, type.first, type.second, input, size);
|
||||
detail::MatchingMapByElement<Protocols>(var, type.first, type.second, input, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1004,4 +1038,5 @@ inline DeserializeMap(X& var, BondDataType keyType, const T& element, Reader& in
|
|||
input.ReadContainerEnd();
|
||||
}
|
||||
|
||||
|
||||
} // namespace bond
|
||||
|
|
|
@ -71,7 +71,7 @@ class SimpleBinaryWriter;
|
|||
|
||||
|
||||
/// @brief Reader for Simple Binary protocol
|
||||
template <typename BufferT>
|
||||
template <typename BufferT, typename MarshaledBondedProtocolsT>
|
||||
class SimpleBinaryReader
|
||||
{
|
||||
public:
|
||||
|
@ -257,9 +257,9 @@ protected:
|
|||
}
|
||||
|
||||
|
||||
template <typename Input, typename Output>
|
||||
template <typename Input, typename MarshaledBondedProtocols, typename Output>
|
||||
friend
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input>&,
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input, MarshaledBondedProtocols>&,
|
||||
const SimpleBinaryWriter<Output>&);
|
||||
|
||||
Buffer _input;
|
||||
|
@ -267,8 +267,8 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
template <typename Buffer>
|
||||
BOND_CONSTEXPR_OR_CONST uint16_t SimpleBinaryReader<Buffer>::magic;
|
||||
template <typename BufferT, typename MarshaledBondedProtocolsT>
|
||||
BOND_CONSTEXPR_OR_CONST uint16_t SimpleBinaryReader<BufferT, MarshaledBondedProtocolsT>::magic;
|
||||
|
||||
|
||||
/// @brief Writer for Simple Binary protocol
|
||||
|
@ -372,9 +372,9 @@ protected:
|
|||
WriteVariableUnsigned(_output, size);
|
||||
}
|
||||
|
||||
template <typename Input, typename Output>
|
||||
template <typename Input, typename MarshaledBondedProtocols, typename Output>
|
||||
friend
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input>&,
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input, MarshaledBondedProtocols>&,
|
||||
const SimpleBinaryWriter<Output>&);
|
||||
|
||||
Buffer& _output;
|
||||
|
@ -382,13 +382,13 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
template <typename Input> struct
|
||||
protocol_has_multiple_versions<SimpleBinaryReader<Input> >
|
||||
template <typename Input, typename MarshaledBondedProtocols> struct
|
||||
protocol_has_multiple_versions<SimpleBinaryReader<Input, MarshaledBondedProtocols> >
|
||||
: true_type {};
|
||||
|
||||
|
||||
template <typename Input, typename Output>
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input>& reader,
|
||||
template <typename Input, typename MarshaledBondedProtocols, typename Output>
|
||||
bool is_protocol_version_same(const SimpleBinaryReader<Input, MarshaledBondedProtocols>& reader,
|
||||
const SimpleBinaryWriter<Output>& writer)
|
||||
{
|
||||
return reader._version == writer._version;
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
namespace bond
|
||||
{
|
||||
|
||||
template <typename BufferT>
|
||||
template <typename BufferT, typename MarshaledBondedProtocolsT>
|
||||
template <typename T>
|
||||
inline void SimpleBinaryReader<BufferT>::Skip(const bonded<T, SimpleBinaryReader&>& bonded)
|
||||
inline void SimpleBinaryReader<BufferT, MarshaledBondedProtocolsT>::Skip(const bonded<T, SimpleBinaryReader&>& bonded)
|
||||
{
|
||||
// Skip the structure field-by-field by applying Null transform
|
||||
Apply(Null(), bonded);
|
||||
detail::Skip(bonded);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -152,21 +152,21 @@ private:
|
|||
template <typename Input>
|
||||
friend struct base_input;
|
||||
|
||||
template <typename A, typename T, typename Buffer>
|
||||
template <typename Protocols, typename A, typename T, typename Buffer>
|
||||
friend void DeserializeContainer(std::vector<bool, A>&, const T&, SimpleJsonReader<Buffer>&);
|
||||
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols, typename T, typename Buffer>
|
||||
friend void DeserializeContainer(blob&, const T&, SimpleJsonReader<Buffer>&);
|
||||
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
friend typename boost::enable_if<is_list_container<X> >::type
|
||||
DeserializeContainer(X&, const T&, SimpleJsonReader<Buffer>&);
|
||||
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
friend typename boost::enable_if<is_set_container<X> >::type
|
||||
DeserializeContainer(X&, const T&, SimpleJsonReader<Buffer>&);
|
||||
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
friend typename boost::enable_if<is_map_container<X> >::type
|
||||
DeserializeMap(X&, BondDataType, const T&, SimpleJsonReader<Buffer>&);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ SimpleJsonReader<BufferT>::FindField(uint16_t id, const Metadata& metadata, Bond
|
|||
}
|
||||
|
||||
// deserialize std::vector<bool>
|
||||
template <typename A, typename T, typename Buffer>
|
||||
template <typename Protocols, typename A, typename T, typename Buffer>
|
||||
inline void DeserializeContainer(std::vector<bool, A>& var, const T& /*element*/, SimpleJsonReader<Buffer>& reader)
|
||||
{
|
||||
rapidjson::Value::ConstValueIterator it = reader.ArrayBegin();
|
||||
|
@ -51,7 +51,7 @@ inline void DeserializeContainer(std::vector<bool, A>& var, const T& /*element*/
|
|||
|
||||
|
||||
// deserialize blob
|
||||
template <typename T, typename Buffer>
|
||||
template <typename Protocols, typename T, typename Buffer>
|
||||
inline void DeserializeContainer(blob& var, const T& /*element*/, SimpleJsonReader<Buffer>& reader)
|
||||
{
|
||||
if (uint32_t size = reader.ArraySize())
|
||||
|
@ -71,7 +71,7 @@ inline void DeserializeContainer(blob& var, const T& /*element*/, SimpleJsonRead
|
|||
|
||||
|
||||
// deserialize list
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
inline typename boost::enable_if<is_list_container<X> >::type
|
||||
DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
|
||||
{
|
||||
|
@ -87,12 +87,12 @@ DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
|
|||
if (type.ComplexTypeMatch(*it))
|
||||
{
|
||||
SimpleJsonReader<Buffer> input(reader, *it);
|
||||
DeserializeElement(var, items.next(), detail::MakeValue(input, element));
|
||||
DeserializeElement<Protocols>(var, items.next(), detail::MakeValue(input, element));
|
||||
}
|
||||
else if (type.BasicTypeMatch(*it))
|
||||
{
|
||||
SimpleJsonReader<Buffer> input(reader, *it);
|
||||
DeserializeElement(var, items.next(), value<typename element_type<X>::type, SimpleJsonReader<Buffer>&>(input));
|
||||
DeserializeElement<Protocols>(var, items.next(), value<typename element_type<X>::type, SimpleJsonReader<Buffer>&>(input));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
|
|||
|
||||
|
||||
// deserialize set
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
inline typename boost::enable_if<is_set_container<X> >::type
|
||||
DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
|
|||
|
||||
|
||||
// deserialize map
|
||||
template <typename X, typename T, typename Buffer>
|
||||
template <typename Protocols, typename X, typename T, typename Buffer>
|
||||
inline typename boost::enable_if<is_map_container<X> >::type
|
||||
DeserializeMap(X& var, BondDataType keyType, const T& element, SimpleJsonReader<Buffer>& reader)
|
||||
{
|
||||
|
@ -154,7 +154,7 @@ DeserializeMap(X& var, BondDataType keyType, const T& element, SimpleJsonReader<
|
|||
SimpleJsonReader<Buffer> input(reader, *++it);
|
||||
|
||||
if (value_type.ComplexTypeMatch(*it))
|
||||
detail::MakeValue(input, element).Deserialize(mapped_at(var, key));
|
||||
detail::MakeValue(input, element).template Deserialize<Protocols>(mapped_at(var, key));
|
||||
else
|
||||
value<typename element_type<X>::type::second_type, SimpleJsonReader<Buffer>&>(input).Deserialize(mapped_at(var, key));
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@ private:
|
|||
_output.Write(" ", _indent);
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
template <typename Writer, typename Protocols>
|
||||
friend class Serializer;
|
||||
|
||||
detail::RapidJsonOutputStream<BufferT> _stream;
|
||||
|
@ -226,8 +226,8 @@ is_writer<SimpleJsonWriter<Buffer>, void>
|
|||
: true_type {};
|
||||
|
||||
|
||||
template <typename Buffer>
|
||||
class Serializer<SimpleJsonWriter<Buffer> >
|
||||
template <typename Buffer, typename Protocols>
|
||||
class Serializer<SimpleJsonWriter<Buffer>, Protocols>
|
||||
: public SerializingTransform
|
||||
{
|
||||
public:
|
||||
|
@ -257,7 +257,7 @@ public:
|
|||
template <typename T>
|
||||
bool Base(const T& value) const
|
||||
{
|
||||
Apply(*this, value);
|
||||
Apply<Protocols>(*this, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -419,7 +419,7 @@ private:
|
|||
typename boost::enable_if<is_bond_type<T> >::type
|
||||
Write(const T& value) const
|
||||
{
|
||||
Apply(SerializeTo(_output), value);
|
||||
Apply<Protocols>(SerializeTo<Protocols>(_output), value);
|
||||
}
|
||||
|
||||
// 2-tuple
|
||||
|
@ -468,7 +468,7 @@ private:
|
|||
{
|
||||
T data;
|
||||
|
||||
value.Deserialize(data);
|
||||
value.template Deserialize<Protocols>(data);
|
||||
_output.Write(data);
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,7 @@ private:
|
|||
typename boost::disable_if<is_basic_type<T> >::type
|
||||
Write(const value<T, Reader>& value) const
|
||||
{
|
||||
Apply(SerializeTo(_output), value);
|
||||
Apply<Protocols>(SerializeTo<Protocols>(_output), value);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -240,18 +240,19 @@ protected:
|
|||
{
|
||||
return input._blob.range(input._pointer);
|
||||
}
|
||||
|
||||
friend InputBuffer CreateInputBuffer(const InputBuffer& /*other*/, const blob& blob)
|
||||
{
|
||||
return InputBuffer(blob);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline InputBuffer CreateInputBuffer(const InputBuffer& /*other*/, const blob& blob)
|
||||
{
|
||||
return InputBuffer(blob);
|
||||
}
|
||||
|
||||
inline blob GetBufferRange(const blob& begin, const blob& end)
|
||||
{
|
||||
return begin.range(0, begin.length() - end.length());
|
||||
}
|
||||
|
||||
BOND_DEFINE_BUFFER_MAGIC(InputBuffer, 0x4249 /*IB*/);
|
||||
|
||||
} // namespace bond
|
||||
|
|
|
@ -23,7 +23,7 @@ TEST_CASE_BEGIN(AllocatorTest)
|
|||
|
||||
Reader reader(data);
|
||||
bond::Deserialize(reader, *to);
|
||||
UT_AssertIsTrue(*from == *to);
|
||||
UT_Compare(*from, *to);
|
||||
|
||||
boost::shared_ptr<T> x = boost::allocate_shared<T>(alloc, alloc);
|
||||
boost::shared_ptr<T> y = boost::allocate_shared<T>(alloc, alloc);
|
||||
|
@ -32,7 +32,7 @@ TEST_CASE_BEGIN(AllocatorTest)
|
|||
|
||||
y->swap(*to);
|
||||
|
||||
UT_AssertIsTrue(*x == *y);
|
||||
UT_Compare(*x, *y);
|
||||
}
|
||||
|
||||
// Runtime-time deserialize
|
||||
|
@ -43,7 +43,7 @@ TEST_CASE_BEGIN(AllocatorTest)
|
|||
bond::bonded<void> bonded(reader, bond::GetRuntimeSchema<T>());
|
||||
|
||||
bonded.Deserialize(*to);
|
||||
UT_AssertIsTrue(*from == *to);
|
||||
UT_Compare(*from, *to);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
|
|
@ -24,13 +24,13 @@ void Marshal(uint16_t version = bond::v1)
|
|||
|
||||
bond::OutputBuffer output;
|
||||
Factory<Writer>::Call(output, version, boost::bind(
|
||||
bond::Marshal<X, Writer>, obj, _1));
|
||||
bond::Marshal<bond::BuiltInProtocols, X, Writer>, obj, _1));
|
||||
|
||||
bond::InputBuffer input = output.GetBuffer();
|
||||
|
||||
Unmarshal(input, obj2);
|
||||
|
||||
UT_AssertIsTrue(obj == obj2);
|
||||
UT_Compare(obj, obj2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,14 +43,14 @@ void Serialize(uint16_t version = bond::v1)
|
|||
|
||||
bond::OutputBuffer output;
|
||||
Factory<Writer>::Call(output, version, boost::bind(
|
||||
bond::Serialize<X, Writer>, obj, _1));
|
||||
bond::Serialize<bond::BuiltInProtocols, X, Writer>, obj, _1));
|
||||
|
||||
bond::InputBuffer input = output.GetBuffer();
|
||||
Reader reader(Factory<Reader>::Create(input, version));
|
||||
|
||||
Deserialize(reader, obj2);
|
||||
|
||||
UT_AssertIsTrue(obj == obj2);
|
||||
UT_Compare(obj, obj2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@ void Apply(uint16_t version = bond::v1)
|
|||
|
||||
bond::OutputBuffer output;
|
||||
Factory<Writer>::Call(output, version, boost::bind(
|
||||
CallApply<bond::Serializer<Writer>, X>, boost::bind(bond::SerializeTo<Writer>, _1), obj));
|
||||
CallApply<bond::Serializer<Writer>, X>, boost::bind(bond::SerializeTo<bond::BuiltInProtocols, Writer>, _1), obj));
|
||||
|
||||
bond::InputBuffer input = output.GetBuffer();
|
||||
Reader reader(Factory<Reader>::Create(input, version));
|
||||
|
@ -77,7 +77,7 @@ void Apply(uint16_t version = bond::v1)
|
|||
|
||||
Apply(bond::To<X>(obj2), bonded);
|
||||
|
||||
UT_AssertIsTrue(obj == obj2);
|
||||
UT_Compare(obj, obj2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@ void SimpleApply(uint16_t version = bond::v1)
|
|||
|
||||
typename Writer::Buffer output;
|
||||
Factory<Writer>::Call(output, version, boost::bind(
|
||||
CallApply<bond::Serializer<Writer>, X>, boost::bind(bond::SerializeTo<Writer>, _1), obj));
|
||||
CallApply<bond::Serializer<Writer>, X>, boost::bind(bond::SerializeTo<bond::BuiltInProtocols, Writer>, _1), obj));
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ Bonded(uint16_t version = bond::v1)
|
|||
|
||||
bond::OutputBuffer output;
|
||||
Factory<Writer>::Call(output, version, boost::bind(
|
||||
bond::Serialize<X, Writer>, obj, _1));
|
||||
bond::Serialize<bond::BuiltInProtocols, X, Writer>, obj, _1));
|
||||
|
||||
bond::InputBuffer input = output.GetBuffer();
|
||||
Reader reader(Factory<Reader>::Create(input, version));
|
||||
|
@ -122,7 +122,7 @@ Bonded(uint16_t version = bond::v1)
|
|||
|
||||
bond::OutputBuffer output2;
|
||||
Factory<Writer>::Call(output2, version, boost::bind(
|
||||
&bond::bonded<X>::template Serialize<Writer>, bonded, _1));
|
||||
&bond::bonded<X>::template Serialize<bond::BuiltInProtocols, Writer>, bonded, _1));
|
||||
|
||||
bond::InputBuffer input2 = output2.GetBuffer();
|
||||
Reader reader2(Factory<Reader>::Create(input2, version));
|
||||
|
@ -130,7 +130,7 @@ Bonded(uint16_t version = bond::v1)
|
|||
|
||||
bonded2.Deserialize(obj2);
|
||||
|
||||
UT_AssertIsTrue(obj == obj2);
|
||||
UT_Compare(obj, obj2);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
#include <bond/core/bond_version.h>
|
||||
#include <bond/stream/output_counter.h>
|
||||
|
||||
namespace bond
|
||||
{
|
||||
// Use Simple Protocol v2 by default
|
||||
template <typename Buffer> struct
|
||||
default_version<SimpleBinaryReader<Buffer> >
|
||||
: std::integral_constant<uint16_t, 2> {};
|
||||
};
|
||||
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "basic_tests.h"
|
||||
|
||||
|
@ -156,46 +147,46 @@ struct SwapTest
|
|||
{
|
||||
X x1, x2, y1, y2;
|
||||
|
||||
UT_AssertIsTrue(x1 == x2);
|
||||
UT_AssertIsTrue(y1 == y2);
|
||||
UT_Compare(x1, x2);
|
||||
UT_Compare(y1, y2);
|
||||
|
||||
x1 = InitRandom<X>();
|
||||
y1 = InitRandom<X>();
|
||||
|
||||
UT_AssertIsTrue(x1 != x2);
|
||||
UT_AssertIsTrue(y1 != y2);
|
||||
UT_NegateCompare(x1, x2);
|
||||
UT_NegateCompare(y1, y2);
|
||||
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
|
||||
UT_AssertIsTrue(x1 == x2);
|
||||
UT_AssertIsTrue(y1 == y2);
|
||||
UT_Compare(x1, x2);
|
||||
UT_Compare(y1, y2);
|
||||
|
||||
x2 = InitRandom<X>();
|
||||
y2 = InitRandom<X>();
|
||||
|
||||
X x3(x1), x4(x2), y3(y1), y4(y2);
|
||||
|
||||
UT_AssertIsTrue(x1 == x3);
|
||||
UT_AssertIsTrue(y1 == y3);
|
||||
UT_Compare(x1, x3);
|
||||
UT_Compare(y1, y3);
|
||||
|
||||
UT_AssertIsTrue(x2 == x4);
|
||||
UT_AssertIsTrue(y2 == y4);
|
||||
UT_Compare(x2, x4);
|
||||
UT_Compare(y2, y4);
|
||||
|
||||
UT_AssertIsTrue(x1 != x4);
|
||||
UT_AssertIsTrue(y1 != y4);
|
||||
UT_NegateCompare(x1, x4);
|
||||
UT_NegateCompare(y1, y4);
|
||||
|
||||
UT_AssertIsTrue(x3 != x2);
|
||||
UT_AssertIsTrue(y3 != y2);
|
||||
UT_NegateCompare(x3, x2);
|
||||
UT_NegateCompare(y3, y2);
|
||||
|
||||
swap(x1, x2);
|
||||
y1.swap(y2);
|
||||
|
||||
UT_AssertIsTrue(x1 == x4);
|
||||
UT_AssertIsTrue(y1 == y4);
|
||||
UT_Compare(x1, x4);
|
||||
UT_Compare(y1, y4);
|
||||
|
||||
UT_AssertIsTrue(x3 == x2);
|
||||
UT_AssertIsTrue(y3 == y2);
|
||||
UT_Compare(x3, x2);
|
||||
UT_Compare(y3, y2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -226,11 +217,11 @@ struct CopyMoveTest
|
|||
X src = InitRandom<X>();
|
||||
|
||||
X x(src);
|
||||
UT_AssertIsTrue(x == src);
|
||||
UT_Compare(x, src);
|
||||
|
||||
#ifndef BOND_NO_CXX11_RVALUE_REFERENCES
|
||||
X y(std::move(x));
|
||||
UT_AssertIsTrue(y == src);
|
||||
UT_Compare(y, src);
|
||||
UT_AssertIsTrue(moved(x));
|
||||
#endif
|
||||
}
|
||||
|
@ -308,11 +299,13 @@ TEST_CASE_END
|
|||
|
||||
TEST_CASE_BEGIN(SimpleBinaryVersion)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(bond::default_version<bond::SimpleBinaryReader<bond::InputBuffer>>::value == bond::v1);
|
||||
|
||||
SimpleListsStruct from = InitRandom<SimpleListsStruct>();
|
||||
|
||||
{
|
||||
bond::OutputBuffer output_buffer;
|
||||
|
||||
|
||||
// serialize using default version of SimpleBinary reader
|
||||
bond::SimpleBinaryWriter<bond::OutputBuffer> output(output_buffer);
|
||||
|
||||
|
@ -320,32 +313,32 @@ TEST_CASE_BEGIN(SimpleBinaryVersion)
|
|||
bond::InputBuffer input_buffer(output_buffer.GetBuffer());
|
||||
|
||||
{
|
||||
// deserialize using version 2 of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer, 2);
|
||||
|
||||
// deserialize using version 1 of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer, 1);
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
// deserialize using default version of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer);
|
||||
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bond::OutputBuffer output_buffer;
|
||||
|
||||
|
||||
// serialize using version 2 of SimpleBinary writer
|
||||
bond::SimpleBinaryWriter<bond::OutputBuffer> output(output_buffer, 2);
|
||||
|
||||
|
@ -355,29 +348,18 @@ TEST_CASE_BEGIN(SimpleBinaryVersion)
|
|||
{
|
||||
// deserialize using version 2 of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer, 2);
|
||||
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
}
|
||||
|
||||
{
|
||||
// deserialize using default version of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer);
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bond::OutputBuffer output_buffer;
|
||||
|
||||
|
||||
// serialize using version 1 of SimpleBinary writer
|
||||
bond::SimpleBinaryWriter<bond::OutputBuffer> output(output_buffer, 1);
|
||||
|
||||
|
@ -387,12 +369,23 @@ TEST_CASE_BEGIN(SimpleBinaryVersion)
|
|||
{
|
||||
// deserialize using version 1 of SimpleBinary reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer, 1);
|
||||
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
// deserialize using default version of SimpleProtocol reader
|
||||
bond::SimpleBinaryReader<bond::InputBuffer> input(input_buffer);
|
||||
|
||||
SimpleListsStruct to;
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ void BondedVoid(const bond::bonded<void>& bonded, const T& expected)
|
|||
|
||||
bonded.Deserialize(value);
|
||||
|
||||
UT_AssertIsTrue(Equal(expected, value));
|
||||
UT_Equal(expected, value);
|
||||
|
||||
CopyAndMove(value);
|
||||
|
||||
auto value2 = bonded.Deserialize<T>();
|
||||
UT_AssertIsTrue(Equal(expected, value2));
|
||||
UT_Equal(expected, value2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,12 +25,12 @@ void BondedTyped(const bond::bonded<T>& bonded, const T& expected)
|
|||
|
||||
bonded.Deserialize(value);
|
||||
|
||||
UT_AssertIsTrue(Equal(expected, value));
|
||||
UT_Equal(expected, value);
|
||||
|
||||
CopyAndMove(value);
|
||||
|
||||
auto value2 = bonded.Deserialize();
|
||||
UT_AssertIsTrue(Equal(expected, value2));
|
||||
UT_Equal(expected, value2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,10 +41,10 @@ void BondedCast(const bond::bonded<T1>& bonded, const T2& expected)
|
|||
|
||||
bonded.Deserialize(value);
|
||||
|
||||
UT_AssertIsTrue(Equal(expected, value));
|
||||
UT_Equal(expected, value);
|
||||
|
||||
auto value2 = bonded.template Deserialize<T2>();
|
||||
UT_AssertIsTrue(Equal(expected, value2));
|
||||
UT_Equal(expected, value2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,14 +103,14 @@ TEST_CASE_BEGIN(BondedConstructors)
|
|||
|
||||
simple.m_int8++;
|
||||
|
||||
UT_AssertIsTrue(from == from2);
|
||||
UT_Compare(from, from2);
|
||||
|
||||
NestedStruct1 to, to2;
|
||||
|
||||
SerializeDeserialize<Reader, Writer>(from, to);
|
||||
SerializeDeserialize<Reader, Writer>(from2, to2, Reader::version);
|
||||
|
||||
UT_AssertIsTrue(simple != original);
|
||||
UT_NegateCompare(simple, original);
|
||||
UT_Equal(to.s, original);
|
||||
UT_Equal(to, to2);
|
||||
}
|
||||
|
@ -124,14 +124,14 @@ TEST_CASE_BEGIN(BondedConstructors)
|
|||
|
||||
simple.m_int8++;
|
||||
|
||||
UT_AssertIsTrue(from == from2);
|
||||
UT_Compare(from, from2);
|
||||
|
||||
NestedStruct1 to, to2;
|
||||
|
||||
SerializeDeserialize<Reader, Writer>(from, to);
|
||||
SerializeDeserialize<Reader, Writer>(from2, to2, Reader::version);
|
||||
|
||||
UT_AssertIsTrue(simple != original);
|
||||
UT_NegateCompare(simple, original);
|
||||
UT_Equal(to.s, simple);
|
||||
UT_Equal(to, to2);
|
||||
}
|
||||
|
@ -147,15 +147,15 @@ TEST_CASE_BEGIN(BondedConstructors)
|
|||
simple.m_int8++;
|
||||
simple_ptr->m_int16++;
|
||||
|
||||
UT_AssertIsTrue(from == from2);
|
||||
UT_Compare(from, from2);
|
||||
|
||||
NestedStruct1 to, to2;
|
||||
|
||||
SerializeDeserialize<Reader, Writer>(from, to);
|
||||
SerializeDeserialize<Reader, Writer>(from2, to2, Reader::version);
|
||||
|
||||
UT_AssertIsTrue(*simple_ptr != original);
|
||||
UT_AssertIsTrue(*simple_ptr != simple);
|
||||
UT_NegateCompare(*simple_ptr, original);
|
||||
UT_NegateCompare(*simple_ptr, simple);
|
||||
UT_Equal(to.s, *simple_ptr);
|
||||
UT_Equal(to, to2);
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ TEST_CASE_BEGIN(BondedConstructors)
|
|||
|
||||
from2 = from;
|
||||
|
||||
UT_AssertIsTrue(from == from2);
|
||||
UT_Compare(from, from2);
|
||||
|
||||
NestedWithBase1BaseView to, to2;
|
||||
|
||||
|
@ -261,13 +261,13 @@ TEST_CASE_BEGIN(MarshaledBonded)
|
|||
From to;
|
||||
UT_AssertIsTrue(bond::Validate(bond::GetRuntimeSchema<From>(), bond::GetRuntimeSchema<From>()));
|
||||
bond::Deserialize(reader, to);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
From to;
|
||||
bond::Deserialize(reader, to, bond::GetRuntimeSchema<From>());
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
// 1.b. Deserialize To
|
||||
|
@ -275,7 +275,7 @@ TEST_CASE_BEGIN(MarshaledBonded)
|
|||
To to;
|
||||
UT_AssertIsFalse(bond::Validate(bond::GetRuntimeSchema<From>(), bond::GetRuntimeSchema<To>()));
|
||||
bond::Deserialize(reader, to, bond::GetRuntimeSchema<From>());
|
||||
UT_AssertIsTrue(Equal(from.field, to.field));
|
||||
UT_Equal(from.field, to.field);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
@ -299,13 +299,13 @@ TEST_CASE_BEGIN(MarshaledBondedDerived)
|
|||
To to;
|
||||
UT_AssertIsTrue(bond::Validate(bond::GetRuntimeSchema<From>(), bond::GetRuntimeSchema<To>()));
|
||||
bond::Deserialize(reader, to);
|
||||
UT_AssertIsTrue(Equal(t2, to.field));
|
||||
UT_Equal(t2, to.field);
|
||||
}
|
||||
|
||||
{
|
||||
To to;
|
||||
bond::Deserialize(reader, to, bond::GetRuntimeSchema<From>());
|
||||
UT_AssertIsTrue(Equal(t2, to.field));
|
||||
UT_Equal(t2, to.field);
|
||||
}
|
||||
|
||||
// 1.b. Deserialize T2
|
||||
|
@ -315,7 +315,7 @@ TEST_CASE_BEGIN(MarshaledBondedDerived)
|
|||
// to deserialize into instance of T2 directly instead of going via bonded<T2>
|
||||
UT_AssertIsFalse(bond::Validate(bond::GetRuntimeSchema<To>(), bond::GetRuntimeSchema<To2>()));
|
||||
bond::Deserialize(reader, to, bond::GetRuntimeSchema<To>());
|
||||
UT_AssertIsTrue(Equal(t2, to.field));
|
||||
UT_Equal(t2, to.field);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
|
|
@ -3,52 +3,53 @@
|
|||
#include "precompiled.h"
|
||||
#include "container_extensibility.h"
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
template <typename T, size_t N, typename S>
|
||||
bool operator==(const std::array<T, N>& left, const S& right)
|
||||
template <typename Protocols, typename T, size_t N, typename S>
|
||||
bool Compare(const std::array<T, N>& left, const S& right)
|
||||
{
|
||||
for (typename S::size_type i = 0; i < right.length(); ++i)
|
||||
if (left[i] != static_cast<T>(right[i]))
|
||||
for (typename S::size_type i = 0; i < right.size(); ++i)
|
||||
if (!Compare<Protocols>(left[i], static_cast<T>(right[i])))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator==(const WithStaticString& custom, const BondStruct<string>& standard)
|
||||
template <typename Protocols>
|
||||
bool Compare(const WithStaticString& custom, const BondStruct<string>& standard)
|
||||
{
|
||||
return custom.field == standard.field;
|
||||
return Compare<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
inline bool operator==(const BondStruct<string>& standard, const WithStaticString& custom)
|
||||
template <typename Protocols>
|
||||
bool Compare(const BondStruct<string>& standard, const WithStaticString& custom)
|
||||
{
|
||||
return custom.field == standard.field;
|
||||
return Compare<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
inline bool operator==(const WithStaticWString& custom, const BondStruct<wstring>& standard)
|
||||
template <typename Protocols>
|
||||
bool Compare(const WithStaticWString& custom, const BondStruct<wstring>& standard)
|
||||
{
|
||||
return custom.field == standard.field;
|
||||
return Compare<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
inline bool operator==(const BondStruct<wstring>& standard, const WithStaticWString& custom)
|
||||
template <typename Protocols>
|
||||
bool Compare(const BondStruct<wstring>& standard, const WithStaticWString& custom)
|
||||
{
|
||||
return custom.field == standard.field;
|
||||
return Compare<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(const WithSimpleList<T>& custom, const BondStruct<list<T> >& standard)
|
||||
template <typename Protocols, typename T>
|
||||
bool Compare(const WithSimpleList<T>& custom, const BondStruct<list<T> >& standard)
|
||||
{
|
||||
return Equal(custom.field, standard.field);
|
||||
return Equal<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(const BondStruct<list<T> >& standard, const WithSimpleList<T>& custom)
|
||||
template <typename Protocols, typename T>
|
||||
bool Compare(const BondStruct<list<T> >& standard, const WithSimpleList<T>& custom)
|
||||
{
|
||||
return Equal(custom.field, standard.field);
|
||||
return Equal<Protocols>(custom.field, standard.field);
|
||||
}
|
||||
|
||||
} // namespace unittest
|
||||
|
||||
template <typename Reader, typename Writer>
|
||||
struct SimpleListTest
|
||||
|
|
|
@ -3,23 +3,33 @@
|
|||
#include "serialization_test.h"
|
||||
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
template <uint16_t N, typename Reader, typename Writer, typename Protocols>
|
||||
void CustomProtocolsTests(const char* name)
|
||||
{
|
||||
UnitTestSuite suite(name);
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
AllBindingAndMapping1, Reader, Writer, TestReaderStruct>(suite, "Simple struct");
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
AllBindingAndMapping1,
|
||||
#else
|
||||
AllBindingAndMapping1_CustomProtocols,
|
||||
#endif
|
||||
Reader, Writer, TestReaderStruct, Protocols>(suite, "Simple struct");
|
||||
}
|
||||
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
template <uint16_t N, typename Reader, typename Writer, typename Protocols>
|
||||
void CustomInputBufferTests(const char* name)
|
||||
{
|
||||
UnitTestSuite suite(name);
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
AllBindingAndMapping2, Reader, Writer, NestedStruct1, NestedStruct1OptionalBondedView>(suite, "Optional bonded field");
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
AllBindingAndMapping2,
|
||||
#else
|
||||
AllBindingAndMapping2_CustomProtocols,
|
||||
#endif
|
||||
Reader, Writer, NestedStruct1, NestedStruct1OptionalBondedView, Protocols>(suite, "Optional bonded field");
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,12 +39,14 @@ void CustomProtocolsTestsInit()
|
|||
CustomProtocolsTests<
|
||||
0x2102,
|
||||
unit_test::TestReader<bond::InputBuffer>,
|
||||
unit_test::TestWriter<bond::OutputBuffer> >("Custom protocol TestReader");
|
||||
unit_test::TestWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<unit_test::TestReader<bond::InputBuffer> > >("Custom protocol TestReader");
|
||||
|
||||
CustomInputBufferTests<
|
||||
0x2103,
|
||||
unit_test::TestReader<unit_test::CustomInputBuffer>,
|
||||
unit_test::TestWriter<bond::OutputBuffer> >("Custom protocol TestReader using CustomInputBuffer");
|
||||
unit_test::TestWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<unit_test::TestReader<unit_test::CustomInputBuffer> > >("Custom protocol TestReader using CustomInputBuffer");
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <bond/core/customize.h>
|
||||
#include <bond/core/protocol.h>
|
||||
#include <bond/protocol/compact_binary.h>
|
||||
#include <bond/stream/input_buffer.h>
|
||||
|
||||
#include <boost/mpl/joint_view.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
#include "untagged_protocol.h"
|
||||
|
||||
|
||||
|
@ -128,31 +126,8 @@ namespace unit_test
|
|||
|
||||
namespace bond
|
||||
{
|
||||
// Add TestReader to the list of protocols used by Bond
|
||||
template <> struct
|
||||
customize<protocols>
|
||||
{
|
||||
template <typename T> struct
|
||||
modify
|
||||
{
|
||||
typedef typename boost::mpl::joint_view<
|
||||
boost::mpl::list<
|
||||
unit_test::TestReader<InputBuffer>,
|
||||
unit_test::TestReader<unit_test::CustomInputBuffer>,
|
||||
UntaggedProtocolReader<InputBuffer>
|
||||
>::type,
|
||||
T
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
BOND_DEFINE_BUFFER_MAGIC(unit_test::CustomInputBuffer, 0x4243 /*CB*/);
|
||||
|
||||
// Protocols are disabled by default and we leave TestReader disabled
|
||||
// and enable it only in custom_protocol.cpp and UntaggedProtocolReader
|
||||
// in pass_through.cpp.
|
||||
}
|
||||
|
||||
namespace bond
|
||||
{
|
||||
template <typename Buffer> struct
|
||||
is_protocol_enabled<UntaggedProtocolReader<Buffer> >
|
||||
: std::true_type {};
|
||||
|
|
|
@ -6,26 +6,94 @@
|
|||
#include <complex>
|
||||
#include <limits>
|
||||
|
||||
#define UT_Equal(x, y) UT_AssertIsTrue(Equal(x, y))
|
||||
#define UT_Equal_P(x, y, Protocols) UT_AssertIsTrue(Equal<Protocols>(x, y))
|
||||
#define UT_Equal(x, y) UT_Equal_P(x, y, bond::BuiltInProtocols)
|
||||
#define UT_Compare_P(x, y, Protocols) UT_AssertIsTrue(Compare<Protocols>(x, y))
|
||||
#define UT_Compare(x, y) UT_Compare_P(x, y, bond::BuiltInProtocols)
|
||||
#define UT_NegateCompare_P(x, y, Protocols) UT_AssertIsTrue(!Compare<Protocols>(x, y))
|
||||
#define UT_NegateCompare(x, y) UT_NegateCompare_P(x, y, bond::BuiltInProtocols)
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator==(const SkipStruct<T1>& left, const SkipStruct<T2>& right);
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
bool Compare(const SkipStruct<T1>& left, const SkipStruct<T2>& right);
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const SkipStruct<T>& left, const SkipStruct2<T>& right);
|
||||
template <typename Protocols, typename T>
|
||||
bool Compare(const SkipStruct<T>& left, const SkipStruct2<T>& right);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator==(const BondStruct<T1>& left, const BondStruct<T2>& right);
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
bool Compare(const BondStruct<T1>& left, const BondStruct<T2>& right);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols, typename NestedStruct1>
|
||||
bool Compare(const NestedStruct1& left, const NestedStruct1OptionalBondedView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedStruct1& left, const NestedStruct1BondedView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const SimpleStruct& left, const SimpleStructView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedStruct& left, const NestedStructView& right);
|
||||
|
||||
template <typename Protocols, typename T>
|
||||
bool Compare(const WithSimpleList<T>& custom, const BondStruct<std::list<T> >& standard);
|
||||
|
||||
template <typename Protocols, typename T>
|
||||
bool Compare(const BondStruct<std::list<T> >& standard, const WithSimpleList<T>& custom);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const WithStaticString& custom, const BondStruct<std::string>& standard);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const BondStruct<std::string>& standard, const WithStaticString& custom);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const WithStaticWString& custom, const BondStruct<std::wstring>& standard);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const BondStruct<std::wstring>& standard, const WithStaticWString& custom);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const StructWithBase& left, const StructWithBaseView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const SimpleBase& left, const SimpleBaseView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedWithBase& left, const NestedWithBaseView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const ListWithBase& left, const ListWithBaseView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const StructWithBase& left, const SimpleStruct& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const StructWithBase& left, const SimpleBase& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const ListWithBase& left, const ListOfBase& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedWithBase& left, const NestedWithBase2& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const SimpleListsStruct& left, const SimpleListsStructView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedListsStruct& left, const NestedListsStructView& right);
|
||||
|
||||
template <typename Protocols>
|
||||
bool Compare(const Required& left, const RequiredViewGood& right);
|
||||
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
Equal(const T1& lhs, const T2& rhs);
|
||||
|
||||
template <typename T>
|
||||
class Compare
|
||||
template <typename T, typename Protocols>
|
||||
class Comparer
|
||||
{
|
||||
public:
|
||||
Compare(const T& left, const T& right, bool& equal)
|
||||
Comparer(const T& left, const T& right, bool& equal)
|
||||
: left(left),
|
||||
right(right),
|
||||
equal(equal)
|
||||
|
@ -35,7 +103,7 @@ public:
|
|||
void operator()(const Field&);
|
||||
|
||||
private:
|
||||
Compare& operator=(const Compare&);
|
||||
Comparer& operator=(const Comparer&);
|
||||
|
||||
const T& left;
|
||||
const T& right;
|
||||
|
@ -43,102 +111,112 @@ private:
|
|||
};
|
||||
|
||||
|
||||
inline bool Equal(double left, double right)
|
||||
{
|
||||
const int ulp = 5;
|
||||
return std::abs(left - right) <= std::numeric_limits<double>::epsilon() * (std::max)(std::abs(left), std::abs(right)) * ulp;
|
||||
}
|
||||
|
||||
|
||||
inline bool Equal(const bond::blob& lhs, const bond::blob& rhs)
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Compare(const T1& lhs, const T2& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
inline typename boost::enable_if<std::is_floating_point<T>, bool>::type
|
||||
Equal(T left, T right)
|
||||
{
|
||||
const int ulp = 5;
|
||||
return std::abs(left - right) <= std::numeric_limits<T>::epsilon() * (std::max)(std::abs(left), std::abs(right)) * ulp;
|
||||
}
|
||||
|
||||
|
||||
template <typename Protocols = bond::BuiltInProtocols>
|
||||
inline bool Equal(const bond::blob& lhs, const bond::blob& rhs)
|
||||
{
|
||||
return Compare<Protocols>(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
typename boost::enable_if<bond::has_schema<T>, bool>::type
|
||||
Equal(const T& left, const T& right)
|
||||
{
|
||||
bool equal = true;
|
||||
boost::mpl::for_each<typename T::Schema::fields>(Compare<T>(left, right, equal));
|
||||
boost::mpl::for_each<typename T::Schema::fields>(Comparer<T, Protocols>(left, right, equal));
|
||||
return equal;
|
||||
}
|
||||
|
||||
// "loose" equality for matching but different types
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_basic_type<T1>, bool>::type
|
||||
Equal(const T1& lhs, const T2& rhs)
|
||||
{
|
||||
return bond::cast<T2>(lhs) == rhs;
|
||||
return Compare<Protocols>(bond::cast<T2>(lhs), rhs);
|
||||
}
|
||||
|
||||
|
||||
// "loose" equality for struct just calls ==
|
||||
template <typename T1, typename T2>
|
||||
// "loose" equality for struct just calls Compare
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
typename boost::enable_if_c<bond::has_schema<T1>::value
|
||||
&& bond::has_schema<T2>::value, bool>::type
|
||||
Equal(const T1& lhs, const T2& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
return Compare<Protocols>(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
// "loose" equality for T and bonded<T>
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Equal(const T1& lhs, const bond::bonded<T2>& rhs)
|
||||
{
|
||||
T2 rhs_value;
|
||||
|
||||
rhs.Deserialize(rhs_value);
|
||||
rhs.template Deserialize<Protocols>(rhs_value);
|
||||
|
||||
return Equal(lhs, rhs_value);
|
||||
return Equal<Protocols>(lhs, rhs_value);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Equal(const bond::bonded<T1>& lhs, const T2& rhs)
|
||||
{
|
||||
T1 lhs_value;
|
||||
|
||||
lhs.Deserialize(lhs_value);
|
||||
lhs.template Deserialize<Protocols>(lhs_value);
|
||||
|
||||
return Equal(lhs_value, rhs);
|
||||
return Equal<Protocols>(lhs_value, rhs);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Equal(const bond::bonded<T1>& lhs, const bond::bonded<T2>& rhs)
|
||||
{
|
||||
T1 lhs_value;
|
||||
|
||||
lhs.Deserialize(lhs_value);
|
||||
lhs.template Deserialize<Protocols>(lhs_value);
|
||||
|
||||
T2 rhs_value;
|
||||
|
||||
rhs.Deserialize(rhs_value);
|
||||
rhs.template Deserialize<Protocols>(rhs_value);
|
||||
|
||||
return Equal(lhs_value, rhs_value);
|
||||
return Equal<Protocols>(lhs_value, rhs_value);
|
||||
}
|
||||
|
||||
|
||||
// "loose" equality for pairs
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2, typename T3, typename T4>
|
||||
bool Equal(const std::pair<T1, T2>& p1, const std::pair<T3, T4>& p2)
|
||||
{
|
||||
return Equal(p1.first, p2.first) && Equal(p1.second, p2.second);
|
||||
return Equal<Protocols>(p1.first, p2.first) && Equal<Protocols>(p1.second, p2.second);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Equal(const std::pair<T1, T2>& p1, const std::pair<T1, T2>& p2)
|
||||
{
|
||||
return Equal(p1.first, p2.first) && Equal(p1.second, p2.second);
|
||||
return Equal<Protocols>(p1.first, p2.first) && Equal<Protocols>(p1.second, p2.second);
|
||||
}
|
||||
|
||||
|
||||
// "loose" equality for lists of matching but different types
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
Equal(const T1& lhs, const T2& rhs)
|
||||
{
|
||||
|
@ -150,7 +228,7 @@ Equal(const T1& lhs, const T2& rhs)
|
|||
|
||||
while (lhs_items.more() && rhs_items.more())
|
||||
{
|
||||
if (!Equal(lhs_items.next(), rhs_items.next()))
|
||||
if (!Equal<Protocols>(lhs_items.next(), rhs_items.next()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -158,6 +236,7 @@ Equal(const T1& lhs, const T2& rhs)
|
|||
}
|
||||
|
||||
|
||||
template <typename Protocols = bond::BuiltInProtocols>
|
||||
inline bool Equal(const bond::blob& lhs, const std::vector<int8_t>& rhs)
|
||||
{
|
||||
return (lhs.length() == rhs.size() && rhs.size() == 0)
|
||||
|
@ -165,6 +244,7 @@ inline bool Equal(const bond::blob& lhs, const std::vector<int8_t>& rhs)
|
|||
}
|
||||
|
||||
|
||||
template <typename Protocols = bond::BuiltInProtocols>
|
||||
inline bool Equal(const std::vector<int8_t>& lhs, const bond::blob& rhs)
|
||||
{
|
||||
return (rhs.length() == lhs.size() && lhs.size() == 0)
|
||||
|
@ -172,17 +252,17 @@ inline bool Equal(const std::vector<int8_t>& lhs, const bond::blob& rhs)
|
|||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
typename boost::enable_if_c<bond::has_base<T1>::value
|
||||
&& bond::has_base<T2>::value, bool>::type
|
||||
BaseIsEqual(const T1& left, const T2& right)
|
||||
{
|
||||
return Equal(static_cast<const typename T1::Schema::base&>(left),
|
||||
static_cast<const typename T2::Schema::base&>(right));
|
||||
return Equal<Protocols>(static_cast<const typename T1::Schema::base&>(left),
|
||||
static_cast<const typename T2::Schema::base&>(right));
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
typename boost::disable_if_c<bond::has_base<T1>::value
|
||||
|| bond::has_base<T2>::value, bool>::type
|
||||
BaseIsEqual(const T1& /*left*/, const T2& /*right*/)
|
||||
|
@ -191,84 +271,65 @@ BaseIsEqual(const T1& /*left*/, const T2& /*right*/)
|
|||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator==(const BondStruct<T1>& left, const BondStruct<T2>& right)
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Compare(const BondStruct<T1>& left, const BondStruct<T2>& right)
|
||||
{
|
||||
return Equal(left.field, right.field);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator!=(const BondStruct<T1>& left, const BondStruct<T2>& right)
|
||||
{
|
||||
return !(left == right);
|
||||
return Equal<Protocols>(left.field, right.field);
|
||||
}
|
||||
|
||||
|
||||
template <typename Protocols>
|
||||
inline bool all_empty(const bond::blob& x, bool root = false)
|
||||
{
|
||||
return x.empty() && root;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename Protocols, typename T>
|
||||
typename boost::disable_if<bond::is_container<T>, bool>::type
|
||||
all_empty(const T& x, bool root = false)
|
||||
{
|
||||
return x == T() && root;
|
||||
return Compare<Protocols>(x, T()) && root;
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
inline bool all_empty(const std::pair<T1, T2>& x)
|
||||
{
|
||||
return all_empty(x.second);
|
||||
return all_empty<Protocols>(x.second);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename Protocols, typename T>
|
||||
typename boost::enable_if<bond::is_container<T>, bool>::type
|
||||
all_empty(const T& x, bool = false)
|
||||
{
|
||||
if (!x.empty())
|
||||
for (bond::const_enumerator<T> items(x); items.more();)
|
||||
if (!all_empty(items.next()))
|
||||
if (!all_empty<Protocols>(items.next()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator==(const SkipStruct<T1>& left, const SkipStruct<T2>& right)
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T1, typename T2>
|
||||
bool Compare(const SkipStruct<T1>& left, const SkipStruct<T2>& right)
|
||||
{
|
||||
UT_AssertIsTrue(all_empty(right.field1, true));
|
||||
return left.field2 == right.field2;
|
||||
UT_AssertIsTrue(all_empty<Protocols>(right.field1, true));
|
||||
return Compare<Protocols>(left.field2, right.field2);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool operator!=(const SkipStruct<T1>& left, const SkipStruct<T2>& right)
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
bool Compare(const SkipStruct<T>& left, const SkipStruct2<T>& right)
|
||||
{
|
||||
return !(left == right);
|
||||
return Equal<Protocols>(left.field2, right.field2);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const SkipStruct<T>& left, const SkipStruct2<T>& right)
|
||||
{
|
||||
return left.field2 == right.field2;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(const SkipStruct<T>& left, const SkipStruct2<T>& right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename Protocols>
|
||||
template <typename Field>
|
||||
void Compare<T>::operator()(const Field&)
|
||||
void Comparer<T, Protocols>::operator()(const Field&)
|
||||
{
|
||||
equal = equal && Equal(Field::GetVariable(left), Field::GetVariable(right));
|
||||
equal = equal && Equal<Protocols>(Field::GetVariable(left), Field::GetVariable(right));
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ TEST_CASE_BEGIN(TransformException)
|
|||
typename Writer::Buffer buffer(4096);
|
||||
|
||||
Factory<Writer>::Call(buffer, bond::v1, boost::bind(
|
||||
bond::Serialize<T, Writer>, InitRandom<T>(2, 2), _1));
|
||||
bond::Serialize<bond::BuiltInProtocols, T, Writer>, InitRandom<T>(2, 2), _1));
|
||||
|
||||
{
|
||||
for (int i = 0;; ++i)
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
#include "precompiled.h"
|
||||
#include "serialization_test.h"
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
inline bool operator==(const ListWithBase& left, const ListOfBase& right)
|
||||
template <typename Protocols>
|
||||
bool Compare(const ListWithBase& left, const ListOfBase& right)
|
||||
{
|
||||
return Equal(left.l1, right.l1)
|
||||
&& Equal(left.vl2, right.vl2)
|
||||
&& Equal(left.v4, right.v4);
|
||||
}
|
||||
|
||||
return Equal<Protocols>(left.l1, right.l1)
|
||||
&& Equal<Protocols>(left.vl2, right.vl2)
|
||||
&& Equal<Protocols>(left.v4, right.v4);
|
||||
}
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
|
|
|
@ -73,7 +73,7 @@ TEST_CASE_BEGIN(StreamDeserializationTest)
|
|||
T record = InitRandom<T>();
|
||||
|
||||
stream.Deserialize(record);
|
||||
UT_AssertIsTrue(Equal(from[i], record));
|
||||
UT_Equal(from[i], record);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,14 +86,14 @@ TEST_CASE_BEGIN(StreamDeserializationTest)
|
|||
r2 = InitRandom<T>();
|
||||
Deserialize(reader, r1);
|
||||
Deserialize(reader, r2);
|
||||
UT_AssertIsTrue(Equal(r1, r2));
|
||||
UT_Equal(r1, r2);
|
||||
|
||||
bond::bonded<T> bonded(reader);
|
||||
r1 = InitRandom<T>();
|
||||
r2 = InitRandom<T>();
|
||||
bonded.Deserialize(r1);
|
||||
bonded.Deserialize(r2);
|
||||
UT_AssertIsTrue(Equal(r1, r2));
|
||||
UT_Equal(r1, r2);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
@ -139,7 +139,7 @@ void StreamTranscoding(uint16_t version = bond::v1)
|
|||
Record record = InitRandom<Record>();
|
||||
|
||||
stream.Deserialize(record);
|
||||
UT_AssertIsTrue(Equal(records[i], record));
|
||||
UT_Equal(records[i], record);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,33 @@
|
|||
#include "precompiled.h"
|
||||
#include "serialization_test.h"
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
bool operator==(const SimpleListsStruct& left, const SimpleListsStructView& right)
|
||||
template <typename Protocols>
|
||||
bool Compare(const SimpleListsStruct& left, const SimpleListsStructView& right)
|
||||
{
|
||||
return left.l_bool == right.l_bool
|
||||
&& left.l_int64 == right.l_int64
|
||||
&& left.l_float == right.l_float
|
||||
&& left.l_string == right.l_string
|
||||
&& left.v_int16 == right.v_int16
|
||||
&& Equal(left.v_double, right.v_double)
|
||||
&& left.v_string == right.v_string
|
||||
&& left.s_uint64 == right.s_uint64
|
||||
&& left.s_string == right.s_string
|
||||
&& left.m_int8_string == right.m_int8_string
|
||||
&& left.m_string_bool == right.m_string_bool;
|
||||
return Compare<Protocols>(left.l_bool, right.l_bool)
|
||||
&& Compare<Protocols>(left.l_int64, right.l_int64)
|
||||
&& Compare<Protocols>(left.l_float, right.l_float)
|
||||
&& Compare<Protocols>(left.l_string, right.l_string)
|
||||
&& Compare<Protocols>(left.v_int16, right.v_int16)
|
||||
&& Equal<Protocols>(left.v_double, right.v_double)
|
||||
&& Compare<Protocols>(left.v_string, right.v_string)
|
||||
&& Compare<Protocols>(left.s_uint64, right.s_uint64)
|
||||
&& Compare<Protocols>(left.s_string, right.s_string)
|
||||
&& Compare<Protocols>(left.m_int8_string, right.m_int8_string)
|
||||
&& Compare<Protocols>(left.m_string_bool, right.m_string_bool);
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const NestedListsStruct& left, const NestedListsStructView& right)
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedListsStruct& left, const NestedListsStructView& right)
|
||||
{
|
||||
return Equal(left.SLS, right.SLS)
|
||||
&& Equal(left.vlSLS, right.vlSLS)
|
||||
&& Equal(left.vvNS, right.vvNS)
|
||||
&& left.lsb == right.lsb
|
||||
&& Equal(left.vmds, right.vmds);
|
||||
return Equal<Protocols>(left.SLS, right.SLS)
|
||||
&& Equal<Protocols>(left.vlSLS, right.vlSLS)
|
||||
&& Equal<Protocols>(left.vvNS, right.vvNS)
|
||||
&& Compare<Protocols>(left.lsb, right.lsb)
|
||||
&& Equal<Protocols>(left.vmds, right.vmds);
|
||||
}
|
||||
|
||||
} // namespace unittest
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
void SimpleListTests(const char* name)
|
||||
|
|
|
@ -9,16 +9,16 @@ void MarshalingTest(uint16_t version = bond::v1)
|
|||
typename Writer::Buffer output_buffer;
|
||||
|
||||
Factory<Writer>::Call(output_buffer, version, boost::bind(
|
||||
bond::Marshal<T, Writer>, from, _1));
|
||||
bond::Marshal<bond::BuiltInProtocols, T, Writer>, from, _1));
|
||||
|
||||
T to;
|
||||
bond::InputBuffer input(output_buffer.GetBuffer());
|
||||
|
||||
bond::Unmarshal(input, to);
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
|
||||
auto to2 = bond::Unmarshal<T>(input);
|
||||
UT_AssertIsTrue(from == to2);
|
||||
UT_Compare(from, to2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ void TranscodingTest(uint16_t version = bond::v1)
|
|||
typename Writer::Buffer output_buffer;
|
||||
|
||||
Factory<Writer>::Call(output_buffer, version, boost::bind(
|
||||
bond::Marshal<T, Writer>, from, _1));
|
||||
bond::Marshal<bond::BuiltInProtocols, T, Writer>, from, _1));
|
||||
|
||||
// Trans-marshal to Simple Protocol using runtime schema
|
||||
bond::OutputBuffer simple_buffer;
|
||||
|
@ -58,7 +58,7 @@ void TranscodingTest(uint16_t version = bond::v1)
|
|||
{
|
||||
bond::InputBuffer input(simple_buffer.GetBuffer());
|
||||
Factory<Writer>::Call(writer_buffer, version, boost::bind(
|
||||
bond::SelectProtocolAndApply<T, bond::InputBuffer, bond::Marshaler<Writer> >, input, boost::bind(bond::MarshalTo<Writer>, _1)));
|
||||
bond::SelectProtocolAndApply<T, bond::BuiltInProtocols, bond::InputBuffer, bond::Marshaler<Writer> >, input, boost::bind(bond::MarshalTo<bond::BuiltInProtocols, Writer>, _1)));
|
||||
}
|
||||
|
||||
T to;
|
||||
|
@ -66,7 +66,7 @@ void TranscodingTest(uint16_t version = bond::v1)
|
|||
bond::InputBuffer input(writer_buffer.GetBuffer());
|
||||
Unmarshal(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ void TranscodingTest(uint16_t version = bond::v1)
|
|||
{
|
||||
bond::InputBuffer input(simple_buffer.GetBuffer());
|
||||
Factory<Writer>::Call(writer_buffer, version, boost::bind(
|
||||
bond::SelectProtocolAndApply<bond::InputBuffer, bond::Marshaler<Writer> >, bond::GetRuntimeSchema<T>(), input, boost::bind(bond::MarshalTo<Writer>, _1)));
|
||||
bond::SelectProtocolAndApply<bond::BuiltInProtocols, bond::InputBuffer, bond::Marshaler<Writer> >, bond::GetRuntimeSchema<T>(), input, boost::bind(bond::MarshalTo<bond::BuiltInProtocols, Writer>, _1)));
|
||||
}
|
||||
|
||||
T to;
|
||||
|
@ -84,7 +84,7 @@ void TranscodingTest(uint16_t version = bond::v1)
|
|||
bond::InputBuffer input(writer_buffer.GetBuffer());
|
||||
Unmarshal(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ TEST_CASE_BEGIN(MapTo)
|
|||
bond::InputBuffer input(output_buffer.GetBuffer());
|
||||
bond::SelectProtocolAndApply<From>(input, bond::MapTo<To>(to, mappings));
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
// Mapping with runtime time schema
|
||||
|
@ -128,7 +128,7 @@ TEST_CASE_BEGIN(MapTo)
|
|||
bond::InputBuffer input(output_buffer.GetBuffer());
|
||||
bond::SelectProtocolAndApply(bond::GetRuntimeSchema<From>(), input, bond::MapTo<To>(to, mappings));
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
|
|
@ -45,8 +45,8 @@ TEST_CASE_BEGIN(DontOmit)
|
|||
Reader reader(input);
|
||||
Deserialize(reader, to);
|
||||
|
||||
UT_AssertIsTrue(from.field1 == to.field1);
|
||||
UT_AssertIsTrue(from.field2 == to.field2);
|
||||
UT_Compare(from.field1, to.field1);
|
||||
UT_Compare(from.field2, to.field2);
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
|
|
@ -6,15 +6,176 @@
|
|||
#include "serialization_test.h"
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T>
|
||||
void Merging(Payload payload, const T& obj, uint16_t version = bond::v1, bool mergeByDeserialize = true)
|
||||
template <typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols, typename Payload, typename T>
|
||||
void Merging(Payload payload, const T& obj, uint16_t version = bond::v1, bool mergeByDeserialize = true);
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T, typename Protocols = bond::BuiltInProtocols>
|
||||
void MergingRandom()
|
||||
{
|
||||
Reader merged = Merge<Reader, Writer>(payload, obj, version);
|
||||
// random values
|
||||
for (uint32_t i = 0; i < c_iterations; ++i)
|
||||
{
|
||||
Merging<Reader, Writer, Protocols>(InitRandom<Payload, Protocols>(), InitRandom<T, Protocols>());
|
||||
Merging<Reader, Writer, Protocols>(InitRandom<Payload, Protocols>(), InitRandom<T, Protocols>(), Reader::version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T, typename Protocols = bond::BuiltInProtocols>
|
||||
void AllMerging()
|
||||
{
|
||||
// default value
|
||||
Merging<Reader, Writer, Protocols>(Payload(), T());
|
||||
Merging<Reader, Writer, Protocols>(Payload(), T(), Reader::version);
|
||||
Merging<Reader, Writer, Protocols>(InitRandom<Payload, Protocols>(), T());
|
||||
Merging<Reader, Writer, Protocols>(InitRandom<Payload, Protocols>(), T(), Reader::version);
|
||||
Merging<Reader, Writer, Protocols>(Payload(), InitRandom<T, Protocols>());
|
||||
Merging<Reader, Writer, Protocols>(Payload(), InitRandom<T, Protocols>(), Reader::version);
|
||||
|
||||
// random values
|
||||
MergingRandom<Reader, Writer, Payload, T, Protocols>();
|
||||
}
|
||||
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1& payload, const T1& merged, const T2& obj);
|
||||
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
typename boost::disable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1&, const T1&, const T2&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Protocols, typename P, typename T1, typename T2, typename T3, typename T4>
|
||||
bool MergedEqual(bond::const_enumerator<P>&, const P& map, const std::pair<T1, T2>& p1, const std::pair<T3, T4>& p2)
|
||||
{
|
||||
if (!Equal<Protocols>(p1.first, p2.first))
|
||||
return false;
|
||||
|
||||
if (map.end() != map.find(p1.first))
|
||||
return MergedEqual<Protocols>(map.find(p1.first)->second, p1.second, p2.second);
|
||||
else
|
||||
return MergedEqual<Protocols>(typename bond::element_type<P>::type::second_type(), p1.second, p2.second);
|
||||
}
|
||||
|
||||
|
||||
template <typename Protocols, typename P, typename T1, typename T2>
|
||||
bool MergedEqual(bond::const_enumerator<P>& items, const P&, const T1& i1, const T2& i2)
|
||||
{
|
||||
if (items.more())
|
||||
return MergedEqual<Protocols>(items.next(), i1, i2);
|
||||
else
|
||||
return MergedEqual<Protocols>(typename bond::element_type<P>::type(), i1, i2);
|
||||
}
|
||||
|
||||
template <typename Protocols, typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1& payload, const T1& merged, const T2& obj)
|
||||
{
|
||||
if (container_size(obj) != container_size(merged))
|
||||
return false;
|
||||
|
||||
bond::const_enumerator<T1> payload_items(payload);
|
||||
bond::const_enumerator<T1> merged_items(merged);
|
||||
bond::const_enumerator<T2> obj_items(obj);
|
||||
|
||||
while (merged_items.more())
|
||||
if (!MergedEqual<Protocols>(payload_items, payload, merged_items.next(), obj_items.next()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Protocols>
|
||||
bool MergedEqual(const SimpleListsStruct& payload, const SimpleListsStruct& merged, const SimpleListsStructView& obj)
|
||||
{
|
||||
return Compare<Protocols>(merged.l_bool, obj.l_bool)
|
||||
&& Compare<Protocols>(merged.l_int64, obj.l_int64)
|
||||
&& Compare<Protocols>(merged.l_float, obj.l_float)
|
||||
&& Compare<Protocols>(merged.l_string, obj.l_string)
|
||||
&& Compare<Protocols>(merged.v_int16, obj.v_int16)
|
||||
&& Compare<Protocols>(merged.v_double, obj.v_double)
|
||||
&& Compare<Protocols>(merged.v_string, obj.v_string)
|
||||
&& Compare<Protocols>(merged.s_uint64, obj.s_uint64)
|
||||
&& Compare<Protocols>(merged.s_string, obj.s_string)
|
||||
&& Compare<Protocols>(merged.m_int8_string, obj.m_int8_string)
|
||||
&& Compare<Protocols>(merged.m_string_bool, obj.m_string_bool)
|
||||
|
||||
&& Compare<Protocols>(merged.l_uint32, payload.l_uint32)
|
||||
&& Compare<Protocols>(merged.l_int16, payload.l_int16)
|
||||
&& Compare<Protocols>(merged.v_bool, payload.v_bool)
|
||||
&& Compare<Protocols>(merged.v_uint8, payload.v_uint8)
|
||||
&& Compare<Protocols>(merged.v_int64, payload.v_int64)
|
||||
&& Compare<Protocols>(merged.s_bool, payload.s_bool)
|
||||
&& Compare<Protocols>(merged.s_float, payload.s_float)
|
||||
&& Compare<Protocols>(merged.m_float_uint16, payload.m_float_uint16);
|
||||
}
|
||||
|
||||
template <typename Protocols>
|
||||
bool MergedEqual(const NestedStruct& payload, const NestedStruct& merged, const NestedStructView& obj)
|
||||
{
|
||||
return Compare<Protocols>(merged.m_int8, obj.m_int8)
|
||||
&& Compare<Protocols>(merged.n1, obj.n1)
|
||||
&& Compare<Protocols>(merged.m_int16, obj.m_int16)
|
||||
|
||||
&& Compare<Protocols>(merged.n3, payload.n3)
|
||||
&& Compare<Protocols>(merged.m_bool, payload.m_bool)
|
||||
&& Compare<Protocols>(merged.n2, payload.n2)
|
||||
&& Compare<Protocols>(merged.m_int32, payload.m_int32)
|
||||
&& Compare<Protocols>(merged.m_int64, payload.m_int64)
|
||||
&& Compare<Protocols>(merged.m_uint8, payload.m_uint8)
|
||||
&& Compare<Protocols>(merged.m_uint16, payload.m_uint16)
|
||||
&& Compare<Protocols>(merged.m_uint32, payload.m_uint32)
|
||||
&& Compare<Protocols>(merged.m_uint64, payload.m_uint64)
|
||||
&& Compare<Protocols>(merged.m_double, payload.m_double)
|
||||
&& Compare<Protocols>(merged.m_float, payload.m_float)
|
||||
&& Compare<Protocols>(merged.m_enum1, payload.m_enum1)
|
||||
&& Compare<Protocols>(merged.m_str, payload.m_str);
|
||||
}
|
||||
|
||||
template <typename Protocols>
|
||||
bool MergedEqual(const NestedMaps& payload, const NestedMaps& merged, const NestedMapsView& obj)
|
||||
{
|
||||
return Equal<Protocols>(payload.m64ls, merged.m64ls)
|
||||
|
||||
&& MergedEqual<Protocols>(payload.msSLS, merged.msSLS, obj.msSLS)
|
||||
&& MergedEqual<Protocols>(payload.m32lNS, merged.m32lNS, obj.m32lNS);
|
||||
}
|
||||
|
||||
template <typename Protocols>
|
||||
bool MergedEqual(const NestedListsStruct& payload, const NestedListsStruct& merged, const NestedListsView& obj)
|
||||
{
|
||||
return Equal<Protocols>(payload.ll8, merged.ll8)
|
||||
&& Equal<Protocols>(payload.lvls, merged.lvls)
|
||||
&& Equal<Protocols>(payload.SLS, merged.SLS)
|
||||
&& Equal<Protocols>(payload.vf, merged.vf)
|
||||
&& Equal<Protocols>(payload.vss, merged.vss)
|
||||
&& Equal<Protocols>(payload.lsb, merged.lsb)
|
||||
&& Equal<Protocols>(payload.m64ls, merged.m64ls)
|
||||
&& Equal<Protocols>(payload.vmds, merged.vmds)
|
||||
|
||||
&& MergedEqual<Protocols>(payload.lSLS, merged.lSLS, obj.lSLS)
|
||||
&& MergedEqual<Protocols>(payload.vlSLS, merged.vlSLS, obj.vlSLS)
|
||||
&& MergedEqual<Protocols>(payload.vvNS, merged.vvNS, obj.vvNS);
|
||||
}
|
||||
|
||||
} // namespace unittest
|
||||
|
||||
template <typename Reader, typename Writer, typename Protocols, typename Payload, typename T>
|
||||
void Merging(Payload payload, const T& obj, uint16_t version, bool mergeByDeserialize)
|
||||
{
|
||||
Reader merged = Merge<Reader, Writer, Protocols>(payload, obj, version);
|
||||
|
||||
// Deserialize merged into T and compare against obj
|
||||
{
|
||||
T to;
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||
|
@ -25,13 +186,13 @@ void Merging(Payload payload, const T& obj, uint16_t version = bond::v1, bool me
|
|||
#endif
|
||||
|
||||
{
|
||||
to = InitRandom<T>();
|
||||
to = InitRandom<T, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Deserialize(merged, to);
|
||||
bond::Deserialize<Protocols>(merged, to);
|
||||
|
||||
UT_AssertIsTrue(Equal(obj, to));
|
||||
UT_Equal_P(obj, to, Protocols);
|
||||
}
|
||||
|
||||
// Deserialize merged into Payload and compare against combination of the
|
||||
|
@ -48,185 +209,28 @@ void Merging(Payload payload, const T& obj, uint16_t version = bond::v1, bool me
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
to = InitRandom<Payload>();
|
||||
to = InitRandom<Payload, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Deserialize(merged, to);
|
||||
bond::Deserialize<Protocols>(merged, to);
|
||||
|
||||
if (mergeByDeserialize)
|
||||
{
|
||||
// Will fail an assert without
|
||||
// #define BOND_UNIT_TEST_ONLY_PERMIT_OBJECT_REUSE
|
||||
Deserialize(Serialize<Reader, Writer>(obj, version), payload);
|
||||
bond::Deserialize<Protocols>(Serialize<Reader, Writer, Protocols>(obj, version), payload);
|
||||
|
||||
UT_AssertIsTrue(Equal(payload, to));
|
||||
UT_Equal_P(payload, to, Protocols);
|
||||
}
|
||||
else
|
||||
{
|
||||
UT_AssertIsTrue(MergedEqual(payload, to, obj));
|
||||
UT_AssertIsTrue(unittest::MergedEqual<Protocols>(payload, to, obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T>
|
||||
void MergingRandom()
|
||||
{
|
||||
// random values
|
||||
for (uint32_t i = 0; i < c_iterations; ++i)
|
||||
{
|
||||
Merging<Reader, Writer>(InitRandom<Payload>(), InitRandom<T>());
|
||||
Merging<Reader, Writer>(InitRandom<Payload>(), InitRandom<T>(), Reader::version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T>
|
||||
void AllMerging()
|
||||
{
|
||||
// default value
|
||||
Merging<Reader, Writer>(Payload(), T());
|
||||
Merging<Reader, Writer>(Payload(), T(), Reader::version);
|
||||
Merging<Reader, Writer>(InitRandom<Payload>(), T());
|
||||
Merging<Reader, Writer>(InitRandom<Payload>(), T(), Reader::version);
|
||||
Merging<Reader, Writer>(Payload(), InitRandom<T>());
|
||||
Merging<Reader, Writer>(Payload(), InitRandom<T>(), Reader::version);
|
||||
|
||||
// random values
|
||||
MergingRandom<Reader, Writer, Payload, T>();
|
||||
}
|
||||
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
template <typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1& payload, const T1& merged, const T2& obj);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
typename boost::disable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1&, const T1&, const T2&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename P, typename T1, typename T2, typename T3, typename T4>
|
||||
bool MergedEqual(bond::const_enumerator<P>&, const P& map, const std::pair<T1, T2>& p1, const std::pair<T3, T4>& p2)
|
||||
{
|
||||
if (!Equal(p1.first, p2.first))
|
||||
return false;
|
||||
|
||||
if (map.end() != map.find(p1.first))
|
||||
return MergedEqual(map.find(p1.first)->second, p1.second, p2.second);
|
||||
else
|
||||
return MergedEqual(typename bond::element_type<P>::type::second_type(), p1.second, p2.second);
|
||||
}
|
||||
|
||||
|
||||
template <typename P, typename T1, typename T2>
|
||||
bool MergedEqual(bond::const_enumerator<P>& items, const P&, const T1& i1, const T2& i2)
|
||||
{
|
||||
if (items.more())
|
||||
return MergedEqual(items.next(), i1, i2);
|
||||
else
|
||||
return MergedEqual(typename bond::element_type<P>::type(), i1, i2);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
typename boost::enable_if<bond::is_container<T1>, bool>::type
|
||||
MergedEqual(const T1& payload, const T1& merged, const T2& obj)
|
||||
{
|
||||
if (container_size(obj) != container_size(merged))
|
||||
return false;
|
||||
|
||||
bond::const_enumerator<T1> payload_items(payload);
|
||||
bond::const_enumerator<T1> merged_items(merged);
|
||||
bond::const_enumerator<T2> obj_items(obj);
|
||||
|
||||
while (merged_items.more())
|
||||
if (!MergedEqual(payload_items, payload, merged_items.next(), obj_items.next()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MergedEqual(const SimpleListsStruct& payload, const SimpleListsStruct& merged, const SimpleListsStructView& obj)
|
||||
{
|
||||
return merged.l_bool == obj.l_bool
|
||||
&& merged.l_int64 == obj.l_int64
|
||||
&& merged.l_float == obj.l_float
|
||||
&& merged.l_string == obj.l_string
|
||||
&& merged.v_int16 == obj.v_int16
|
||||
&& merged.v_double == obj.v_double
|
||||
&& merged.v_string == obj.v_string
|
||||
&& merged.s_uint64 == obj.s_uint64
|
||||
&& merged.s_string == obj.s_string
|
||||
&& merged.m_int8_string == obj.m_int8_string
|
||||
&& merged.m_string_bool == obj.m_string_bool
|
||||
|
||||
&& merged.l_uint32 == payload.l_uint32
|
||||
&& merged.l_int16 == payload.l_int16
|
||||
&& merged.v_bool == payload.v_bool
|
||||
&& merged.v_uint8 == payload.v_uint8
|
||||
&& merged.v_int64 == payload.v_int64
|
||||
&& merged.s_bool == payload.s_bool
|
||||
&& merged.s_float == payload.s_float
|
||||
&& merged.m_float_uint16 == payload.m_float_uint16;
|
||||
}
|
||||
|
||||
|
||||
bool MergedEqual(const NestedStruct& payload, const NestedStruct& merged, const NestedStructView& obj)
|
||||
{
|
||||
return merged.m_int8 == obj.m_int8
|
||||
&& merged.n1 == obj.n1
|
||||
&& merged.m_int16 == obj.m_int16
|
||||
|
||||
&& merged.n3 == payload.n3
|
||||
&& merged.m_bool == payload.m_bool
|
||||
&& merged.n2 == payload.n2
|
||||
&& merged.m_int32 == payload.m_int32
|
||||
&& merged.m_int64 == payload.m_int64
|
||||
&& merged.m_uint8 == payload.m_uint8
|
||||
&& merged.m_uint16 == payload.m_uint16
|
||||
&& merged.m_uint32 == payload.m_uint32
|
||||
&& merged.m_uint64 == payload.m_uint64
|
||||
&& merged.m_double == payload.m_double
|
||||
&& merged.m_float == payload.m_float
|
||||
&& merged.m_enum1 == payload.m_enum1
|
||||
&& merged.m_str == payload.m_str;
|
||||
}
|
||||
|
||||
|
||||
bool MergedEqual(const NestedMaps& payload, const NestedMaps& merged, const NestedMapsView& obj)
|
||||
{
|
||||
return Equal(payload.m64ls, merged.m64ls)
|
||||
|
||||
&& MergedEqual(payload.msSLS, merged.msSLS, obj.msSLS)
|
||||
&& MergedEqual(payload.m32lNS, merged.m32lNS, obj.m32lNS);
|
||||
}
|
||||
|
||||
|
||||
bool MergedEqual(const NestedListsStruct& payload, const NestedListsStruct& merged, const NestedListsView& obj)
|
||||
{
|
||||
return Equal(payload.ll8, merged.ll8)
|
||||
&& Equal(payload.lvls, merged.lvls)
|
||||
&& Equal(payload.SLS, merged.SLS)
|
||||
&& Equal(payload.vf, merged.vf)
|
||||
&& Equal(payload.vss, merged.vss)
|
||||
&& Equal(payload.lsb, merged.lsb)
|
||||
&& Equal(payload.m64ls, merged.m64ls)
|
||||
&& Equal(payload.vmds, merged.vmds)
|
||||
|
||||
&& MergedEqual(payload.lSLS, merged.lSLS, obj.lSLS)
|
||||
&& MergedEqual(payload.vlSLS, merged.vlSLS, obj.vlSLS)
|
||||
&& MergedEqual(payload.vvNS, merged.vvNS, obj.vvNS);
|
||||
}
|
||||
|
||||
} // namespace unittest
|
||||
|
||||
|
||||
class ModifyContainers
|
||||
: public bond::ModifyingTransform
|
||||
{
|
||||
|
|
|
@ -2,47 +2,44 @@
|
|||
#include "serialization_test.h"
|
||||
#include "untagged_protocol.h"
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
// These operator== are quite expensive to compile; they are made into function templates
|
||||
// These Compare functions are quite expensive to compile; they are made into function templates
|
||||
// so that the code is not generated when building a single unit test
|
||||
template <typename NestedStruct>
|
||||
inline bool operator==(const NestedStruct& left, const NestedStructBondedView& right)
|
||||
template <typename Protocols, typename NestedStruct>
|
||||
bool Compare(const NestedStruct& left, const NestedStructBondedView& right)
|
||||
{
|
||||
return left.m_bool == right.m_bool
|
||||
&& left.m_int8 == left.m_int8
|
||||
&& Equal(left.n3, right.n3)
|
||||
&& Equal(left.n2, right.n2)
|
||||
&& Equal(left.n1, right.n1);
|
||||
return Compare<Protocols>(left.m_bool, right.m_bool)
|
||||
&& Compare<Protocols>(left.m_int8, left.m_int8)
|
||||
&& Equal<Protocols>(left.n3, right.n3)
|
||||
&& Equal<Protocols>(left.n2, right.n2)
|
||||
&& Equal<Protocols>(left.n1, right.n1);
|
||||
}
|
||||
|
||||
|
||||
template <typename NestedStruct1>
|
||||
inline bool operator==(const NestedStruct1& left, const NestedStruct1BondedView& right)
|
||||
template <typename Protocols>
|
||||
bool Compare(const NestedStruct1& left, const NestedStruct1BondedView& right)
|
||||
{
|
||||
return Equal(left.s, right.s);
|
||||
return Equal<Protocols>(left.s, right.s);
|
||||
}
|
||||
|
||||
|
||||
template <typename NestedListsStruct>
|
||||
inline bool operator==(const NestedListsStruct& left, const NestedListsStructBondedView& right)
|
||||
template <typename Protocols, typename NestedListsStruct>
|
||||
bool Compare(const NestedListsStruct& left, const NestedListsStructBondedView& right)
|
||||
{
|
||||
return Equal(left.lSLS, right.lSLS)
|
||||
&& Equal(left.vlSLS, right.vlSLS)
|
||||
&& Equal(left.vvNS, right.vvNS)
|
||||
&& Equal(left.m64ls, right.m64ls);
|
||||
return Equal<Protocols>(left.lSLS, right.lSLS)
|
||||
&& Equal<Protocols>(left.vlSLS, right.vlSLS)
|
||||
&& Equal<Protocols>(left.vvNS, right.vvNS)
|
||||
&& Equal<Protocols>(left.m64ls, right.m64ls);
|
||||
}
|
||||
|
||||
|
||||
template <typename NestedWithBase1>
|
||||
inline bool operator==(const NestedWithBase1& left, const NestedWithBase1BondedBaseView& right)
|
||||
template <typename Protocols, typename NestedWithBase1>
|
||||
bool Compare(const NestedWithBase1& left, const NestedWithBase1BondedBaseView& right)
|
||||
{
|
||||
return Equal(left.s1, right.s1)
|
||||
&& Equal(left.s2, right.s2);
|
||||
return Equal<Protocols>(left.s1, right.s1)
|
||||
&& Equal<Protocols>(left.s2, right.s2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename T, typename Through, typename BondedType>
|
||||
void PassThrough(uint16_t version = bond::v1)
|
||||
|
@ -68,26 +65,26 @@ void PassThrough(uint16_t version = bond::v1)
|
|||
|
||||
bonded_to.Deserialize(to);
|
||||
|
||||
UT_AssertIsTrue(to == from);
|
||||
UT_Compare(to, from);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To, typename BondedType>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To, typename BondedType, typename Protocols>
|
||||
void Transcoding(uint16_t version1 = bond::v1, uint16_t version2 = bond::v1)
|
||||
{
|
||||
From from = InitRandom<From>();
|
||||
From from = InitRandom<From, Protocols>();
|
||||
|
||||
// Compile-time schema
|
||||
{
|
||||
bond::bonded<BondedType> bonded_from(GetBonded<Reader1, Writer1, BondedType>(from, version1));
|
||||
bond::bonded<BondedType> bonded_from(GetBonded<Reader1, Writer1, BondedType, Protocols>(from, version1));
|
||||
|
||||
bond::bonded<To> bonded_to(GetBonded<Reader2, Writer2, To>(bonded_from, version2));
|
||||
bond::bonded<To> bonded_to(GetBonded<Reader2, Writer2, To, Protocols>(bonded_from, version2));
|
||||
|
||||
To to = InitRandom<To>();
|
||||
To to = InitRandom<To, Protocols>();
|
||||
|
||||
bonded_to.Deserialize(to);
|
||||
bonded_to.template Deserialize<Protocols>(to);
|
||||
|
||||
UT_Equal(from, to);
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
|
||||
// Run-time schema
|
||||
|
@ -95,15 +92,15 @@ void Transcoding(uint16_t version1 = bond::v1, uint16_t version2 = bond::v1)
|
|||
bond::bonded<void> bonded_from(GetBonded<Reader1, Writer1,
|
||||
typename boost::mpl::if_<bond::has_schema<BondedType>,
|
||||
BondedType,
|
||||
From>::type>(from, version1));
|
||||
From>::type, Protocols>(from, version1));
|
||||
|
||||
bond::bonded<To> bonded_to(GetBonded<Reader2, Writer2, To>(bonded_from, version2));
|
||||
bond::bonded<To> bonded_to(GetBonded<Reader2, Writer2, To, Protocols>(bonded_from, version2));
|
||||
|
||||
To to = InitRandom<To>();
|
||||
To to = InitRandom<To, Protocols>();
|
||||
|
||||
bonded_to.Deserialize(to);
|
||||
bonded_to.template Deserialize<Protocols>(to);
|
||||
|
||||
UT_Equal(from, to);
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +124,7 @@ void BondedSerialize(uint16_t version = bond::v1)
|
|||
|
||||
bonded_pass_through.Deserialize(to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
// Run-time schema
|
||||
|
@ -138,7 +135,7 @@ void BondedSerialize(uint16_t version = bond::v1)
|
|||
|
||||
bonded_pass_through.Deserialize(to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,30 +170,30 @@ void AllProtoBondedSerialize()
|
|||
}
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::disable_if_c<bond::uses_static_parser<Reader1>::value || bond::uses_static_parser<Reader2>::value || std::is_same<Reader2, bond::SimpleJsonReader<typename Reader2::Buffer> >::value>::type
|
||||
AllTypesTranscoding()
|
||||
{
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(bond::v1, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(Reader1::version, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly>(Reader1::version, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly, Protocols>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(bond::v1, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(Reader1::version, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly, Protocols>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, ForwardDeclarationOnly, Protocols>(Reader1::version, Reader2::version);
|
||||
}
|
||||
|
||||
|
||||
// Simple JSON flattens inheritance hierarchy and thus doesn't always supprot transcoding with w/o schema becase
|
||||
// ordinal used for fields in JSON when names are not available can collide.
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<bond::uses_static_parser<Reader1>::value || bond::uses_static_parser<Reader2>::value || std::is_same<Reader2, bond::SimpleJsonReader<typename Reader2::Buffer> >::value>::type
|
||||
AllTypesTranscoding()
|
||||
{
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(bond::v1, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From>(Reader1::version, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>();
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(Reader1::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(bond::v1, Reader2::version);
|
||||
Transcoding<Reader1, Writer1, Reader2, Writer2, From, To, From, Protocols>(Reader1::version, Reader2::version);
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,10 +260,10 @@ TEST_CASE_BEGIN(AllTranscoding)
|
|||
TEST_CASE_END
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename From, typename To, typename Protocols>
|
||||
TEST_CASE_BEGIN(TranscodingTest)
|
||||
{
|
||||
AllTypesTranscoding<Reader1, Writer1, Reader2, Writer2, From, To>();
|
||||
AllTypesTranscoding<Reader1, Writer1, Reader2, Writer2, From, To, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
@ -301,7 +298,7 @@ TEST_CASE_BEGIN(BasicTypesTranscoding)
|
|||
NestedStruct1 n1;
|
||||
NestedStruct1BondedView n2;
|
||||
|
||||
UT_AssertIsTrue(n1 == n2);
|
||||
UT_Compare(n1, n2);
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
@ -342,12 +339,12 @@ namespace bond
|
|||
}
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename Bonded, typename T>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename Bonded, typename Protocols, typename T>
|
||||
void DefaultValuesTranscodingTest(T to, uint16_t version1 = bond::v1, uint16_t version2 = bond::v1)
|
||||
{
|
||||
T from;
|
||||
|
||||
bond::bonded<Bonded> bonded1(GetBonded<Reader1, Writer1, T>(from, version1));
|
||||
bond::bonded<Bonded> bonded1(GetBonded<Reader1, Writer1, T, Protocols>(from, version1));
|
||||
|
||||
// OutputBuffer is not really designed to allow writing before current pointer
|
||||
// which is required for our test untagged protocol. However it works if
|
||||
|
@ -355,18 +352,18 @@ void DefaultValuesTranscodingTest(T to, uint16_t version1 = bond::v1, uint16_t v
|
|||
typename Writer2::Buffer output_buffer(4096);
|
||||
|
||||
Factory<Writer2>::Call(output_buffer, version2, boost::bind(
|
||||
&bond::bonded<Bonded>::template Serialize<Writer2>, bonded1, _1));
|
||||
&bond::bonded<Bonded>::template Serialize<Protocols, Writer2>, bonded1, _1));
|
||||
|
||||
typename Reader2::Buffer input_buffer(output_buffer.GetBuffer());
|
||||
Reader2 input = Factory<Reader2>::Create(input_buffer, version2);
|
||||
|
||||
bond::Deserialize(input, to);
|
||||
bond::Deserialize<Protocols>(input, to);
|
||||
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare_P(from, to, Protocols);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename Protocols>
|
||||
TEST_CASE_BEGIN(DefaultValuesTranscoding)
|
||||
{
|
||||
typedef OptionalContainers T;
|
||||
|
@ -387,23 +384,23 @@ TEST_CASE_BEGIN(DefaultValuesTranscoding)
|
|||
init = InitRandom<T>();
|
||||
}
|
||||
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void>(init);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void>(init, bond::v1, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void>(init, Reader1::version, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void, Protocols>(init);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void, Protocols>(init, bond::v1, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, void, Protocols>(init, Reader1::version, Reader2::version);
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2>
|
||||
template <typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename Protocols>
|
||||
TEST_CASE_BEGIN(OmittedDefaultValuesTranscoding)
|
||||
{
|
||||
typedef OptionalNothing T;
|
||||
|
||||
T init;
|
||||
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T>(init);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T>(init, bond::v1, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T>(init, Reader1::version, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T, Protocols>(init);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T, Protocols>(init, bond::v1, Reader2::version);
|
||||
DefaultValuesTranscodingTest<Reader1, Writer1, Reader2, Writer2, T, Protocols>(init, Reader1::version, Reader2::version);
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
@ -441,7 +438,7 @@ void PassThroughTests(const char* name)
|
|||
BasicTypesTranscoding, Reader1, Writer1, Reader2, Writer2>(suite, "Transcoding basic types");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2>(suite, "Transcoding default values");
|
||||
DefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2, bond::BuiltInProtocols>(suite, "Transcoding default values");
|
||||
}
|
||||
|
||||
|
||||
|
@ -452,20 +449,20 @@ void PassThroughTests(const char* name)
|
|||
}
|
||||
|
||||
|
||||
template <uint16_t N, typename Reader1, typename Writer1, typename Reader2, typename Writer2>
|
||||
template <uint16_t N, typename Reader1, typename Writer1, typename Reader2, typename Writer2, typename Protocols = bond::BuiltInProtocols>
|
||||
void TranscodingTests(const char* name)
|
||||
{
|
||||
UnitTestSuite suite(name);
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
TranscodingTest, Reader1, Writer1, Reader2, Writer2,
|
||||
unittest::NestedWithBase, unittest::NestedWithBase>(suite, "Transcoding with inheritance");
|
||||
unittest::NestedWithBase, unittest::NestedWithBase, Protocols>(suite, "Transcoding with inheritance");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2>(suite, "Transcoding default values");
|
||||
DefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2, Protocols>(suite, "Transcoding default values");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
OmittedDefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2>(suite, "Transcoding omitted values");
|
||||
OmittedDefaultValuesTranscoding, Reader1, Writer1, Reader2, Writer2, Protocols>(suite, "Transcoding omitted values");
|
||||
}
|
||||
|
||||
|
||||
|
@ -520,7 +517,8 @@ void PassThroughTestsInit()
|
|||
bond::CompactBinaryReader<bond::InputBuffer>,
|
||||
bond::CompactBinaryWriter<bond::OutputBuffer>,
|
||||
UntaggedProtocolReader<bond::InputBuffer>,
|
||||
UntaggedProtocolWriter<bond::OutputBuffer> >("CompactBinary-UntaggedProtocol transcoding");
|
||||
UntaggedProtocolWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<UntaggedProtocolReader<bond::InputBuffer> > >("CompactBinary-UntaggedProtocol transcoding");
|
||||
);
|
||||
|
||||
|
||||
|
@ -540,7 +538,8 @@ void PassThroughTestsInit()
|
|||
UntaggedProtocolReader<bond::InputBuffer>,
|
||||
UntaggedProtocolWriter<bond::OutputBuffer>,
|
||||
UntaggedProtocolReader<bond::InputBuffer>,
|
||||
UntaggedProtocolWriter<bond::OutputBuffer> >("UntaggedProtocol-UntaggedProtocol transcoding");
|
||||
UntaggedProtocolWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<UntaggedProtocolReader<bond::InputBuffer> > >("UntaggedProtocol-UntaggedProtocol transcoding");
|
||||
}
|
||||
|
||||
bool init_unit_test()
|
||||
|
|
|
@ -2,33 +2,31 @@
|
|||
#include "serialization_test.h"
|
||||
#include "untagged_protocol.h"
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
inline bool operator==(const Required& left, const RequiredViewGood& right)
|
||||
template <typename Protocols>
|
||||
bool Compare(const Required& left, const RequiredViewGood& right)
|
||||
{
|
||||
return left.x == right.x
|
||||
&& Equal(left.x2, right.x2)
|
||||
&& (uint64_t)left.z2 == right.z2;
|
||||
return Compare<Protocols>(left.x, right.x)
|
||||
&& Equal<Protocols>(left.x2, right.x2)
|
||||
&& Compare<Protocols>((uint64_t)left.z2, right.z2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols>
|
||||
void RequiredFieldsTest(const From& from)
|
||||
{
|
||||
typename Writer::Buffer buffer(1024);
|
||||
Writer writer(buffer);
|
||||
|
||||
bond::Serialize(from, writer);
|
||||
bond::Serialize<Protocols>(from, writer);
|
||||
|
||||
{
|
||||
To to;
|
||||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<From, Reader&> bonded(reader);
|
||||
|
||||
bonded.Deserialize(to);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
bonded.template Deserialize<Protocols>(to);
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -36,35 +34,35 @@ void RequiredFieldsTest(const From& from)
|
|||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<void, Reader&> bonded(reader, bond::GetRuntimeSchema<From>());
|
||||
|
||||
bonded.Deserialize(to);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
bonded.template Deserialize<Protocols>(to);
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols>
|
||||
TEST_CASE_BEGIN(RequiredFields)
|
||||
{
|
||||
RequiredFieldsTest<Reader, Writer, From, To>(From());
|
||||
RequiredFieldsTest<Reader, Writer, From, To>(InitRandom<From>());
|
||||
RequiredFieldsTest<Reader, Writer, From, To, Protocols>(From());
|
||||
RequiredFieldsTest<Reader, Writer, From, To, Protocols>(InitRandom<From, Protocols>());
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols>
|
||||
void MissingRequiredFieldsTest(const From& from)
|
||||
{
|
||||
typename Writer::Buffer buffer(1024);
|
||||
Writer writer(buffer);
|
||||
|
||||
bond::Serialize(from, writer);
|
||||
bond::Serialize<Protocols>(from, writer);
|
||||
|
||||
{
|
||||
To to;
|
||||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<From, Reader&> bonded(reader);
|
||||
|
||||
UT_AssertThrows((bonded.Deserialize(to)), bond::CoreException);
|
||||
UT_AssertThrows((bonded.template Deserialize<Protocols>(to)), bond::CoreException);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -72,21 +70,21 @@ void MissingRequiredFieldsTest(const From& from)
|
|||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<void, Reader&> bonded(reader, bond::GetRuntimeSchema<From>());
|
||||
|
||||
UT_AssertThrows((bonded.Deserialize(to)), bond::CoreException);
|
||||
UT_AssertThrows((bonded.template Deserialize<Protocols>(to)), bond::CoreException);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols>
|
||||
TEST_CASE_BEGIN(MissingRequiredFields)
|
||||
{
|
||||
MissingRequiredFieldsTest<Reader, Writer, From, To>(From());
|
||||
MissingRequiredFieldsTest<Reader, Writer, From, To>(InitRandom<From>());
|
||||
MissingRequiredFieldsTest<Reader, Writer, From, To, Protocols>(From());
|
||||
MissingRequiredFieldsTest<Reader, Writer, From, To, Protocols>(InitRandom<From, Protocols>());
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
template <typename Reader, typename Writer, typename T, typename Protocols>
|
||||
TEST_CASE_BEGIN(OptionalToRequired)
|
||||
{
|
||||
typedef BondStructOptional<T> From;
|
||||
|
@ -97,14 +95,14 @@ TEST_CASE_BEGIN(OptionalToRequired)
|
|||
typename Writer::Buffer buffer(1024);
|
||||
|
||||
Factory<Writer>::Call(buffer, bond::v1, boost::bind(
|
||||
bond::Serialize<From, Writer>, from, _1));
|
||||
bond::Serialize<Protocols, From, Writer>, from, _1));
|
||||
|
||||
{
|
||||
To to;
|
||||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<To, Reader&> bonded(reader);
|
||||
|
||||
UT_AssertThrows((bonded.Deserialize(to)), bond::CoreException);
|
||||
UT_AssertThrows((bonded.template Deserialize<Protocols>(to)), bond::CoreException);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -112,48 +110,48 @@ TEST_CASE_BEGIN(OptionalToRequired)
|
|||
Reader reader(buffer.GetBuffer());
|
||||
bond::bonded<void, Reader&> bonded(reader, bond::GetRuntimeSchema<To>());
|
||||
|
||||
UT_AssertThrows((bonded.Deserialize(to)), bond::CoreException);
|
||||
UT_AssertThrows((bonded.template Deserialize<Protocols>(to)), bond::CoreException);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
template <uint16_t N, typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols>
|
||||
void RequiredTests(const char* name)
|
||||
{
|
||||
UnitTestSuite suite(name);
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
RequiredFields, Reader, Writer, Required, Required>(suite, "Struct with required fields");
|
||||
RequiredFields, Reader, Writer, Required, Required, Protocols>(suite, "Struct with required fields");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
RequiredFields, Reader, Writer, Required, RequiredViewGood>(suite, "View with required fields");
|
||||
RequiredFields, Reader, Writer, Required, RequiredViewGood, Protocols>(suite, "View with required fields");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
RequiredFields, Reader, Writer, RequiredViewGood, RequiredViewGood>(suite, "Required and optional fields");
|
||||
RequiredFields, Reader, Writer, RequiredViewGood, RequiredViewGood, Protocols>(suite, "Required and optional fields");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingLast>(suite, "Missing last required field");
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingLast, Protocols>(suite, "Missing last required field");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingFirst>(suite, "Missing first required field");
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingFirst, Protocols>(suite, "Missing first required field");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMismatchType>(suite, "Mimatched type required field");
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMismatchType, Protocols>(suite, "Mimatched type required field");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingInNested>(suite, "Required in nested fields");
|
||||
MissingRequiredFields, Reader, Writer, Required, RequiredViewMissingInNested, Protocols>(suite, "Required in nested fields");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
MissingRequiredFields, Reader, Writer, bond::Void, RequiredViewMissingLast>(suite, "Missing all fields");
|
||||
MissingRequiredFields, Reader, Writer, bond::Void, RequiredViewMissingLast, Protocols>(suite, "Missing all fields");
|
||||
|
||||
if (bond::may_omit_fields<Writer>::value)
|
||||
{
|
||||
AddTestCase<TEST_ID(N),
|
||||
OptionalToRequired, Reader, Writer, bool>(suite, "Optional bool to required");
|
||||
OptionalToRequired, Reader, Writer, bool, Protocols>(suite, "Optional bool to required");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
OptionalToRequired, Reader, Writer, list<float> >(suite, "Optional list to required");
|
||||
OptionalToRequired, Reader, Writer, list<float>, Protocols>(suite, "Optional list to required");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +189,8 @@ void RequiredTestsInit()
|
|||
RequiredTests<
|
||||
0x1405,
|
||||
UntaggedProtocolReader<bond::InputBuffer>,
|
||||
UntaggedProtocolWriter<bond::OutputBuffer> >("Required fields tests for untagged protocol");
|
||||
UntaggedProtocolWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<UntaggedProtocolReader<bond::InputBuffer> > >("Required fields tests for untagged protocol");
|
||||
}
|
||||
|
||||
bool init_unit_test()
|
||||
|
|
|
@ -13,6 +13,12 @@ rebind_buffer_by_reference<Reader<Buffer> >
|
|||
typedef Reader<Buffer&> type;
|
||||
};
|
||||
|
||||
template <template <typename T, typename U> class Reader, typename Buffer, typename MarshaledBondedProtocols> struct
|
||||
rebind_buffer_by_reference<Reader<Buffer, MarshaledBondedProtocols>>
|
||||
{
|
||||
typedef Reader<Buffer&, MarshaledBondedProtocols> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
TEST_CASE_BEGIN(Streaming)
|
||||
|
@ -49,8 +55,8 @@ TEST_CASE_BEGIN(Streaming)
|
|||
|
||||
UT_AssertIsTrue(reader.GetBuffer().IsEof());
|
||||
|
||||
UT_AssertIsTrue(from1 == to1);
|
||||
UT_AssertIsTrue(from2 == to2);
|
||||
UT_Compare(from1, to1);
|
||||
UT_Compare(from2, to2);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -67,8 +73,8 @@ TEST_CASE_BEGIN(Streaming)
|
|||
|
||||
UT_AssertIsTrue(buffer.IsEof());
|
||||
|
||||
UT_AssertIsTrue(from1 == to1);
|
||||
UT_AssertIsTrue(from2 == to2);
|
||||
UT_Compare(from1, to1);
|
||||
UT_Compare(from2, to2);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
@ -94,7 +100,7 @@ untagged_payload_size<bond::no_base>
|
|||
};
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
template <typename Reader, typename Writer, typename T, typename Protocols>
|
||||
TEST_CASE_BEGIN(DefaultValues)
|
||||
{
|
||||
T obj;
|
||||
|
@ -106,7 +112,7 @@ TEST_CASE_BEGIN(DefaultValues)
|
|||
Writer output(output_buffer);
|
||||
|
||||
// serialize value to output
|
||||
bond::Serialize(obj, output);
|
||||
bond::Serialize<Protocols>(obj, output);
|
||||
|
||||
if (bond::uses_dynamic_parser<Reader>::value)
|
||||
{
|
||||
|
@ -123,8 +129,8 @@ TEST_CASE_BEGIN(DefaultValues)
|
|||
T to;
|
||||
Reader reader(output_buffer.GetBuffer());
|
||||
|
||||
bond::Deserialize(reader, to);
|
||||
UT_AssertIsTrue(obj == to);
|
||||
bond::Deserialize<Protocols>(reader, to);
|
||||
UT_Compare_P(obj, to, Protocols);
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
|
@ -144,23 +150,23 @@ TEST_CASE_BEGIN(SerializeAPIs)
|
|||
{
|
||||
T to;
|
||||
Deserialize(reader, to);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
T to;
|
||||
Deserialize(reader, to, bond::GetRuntimeSchema<T>());
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
auto to = bond::Deserialize<T>(reader);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
auto to = bond::Deserialize<T>(reader, bond::GetRuntimeSchema<T>());
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -182,35 +188,35 @@ TEST_CASE_BEGIN(MarshalAPIs)
|
|||
{
|
||||
T to;
|
||||
Unmarshal(input, to);
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
bond::bonded<T> to;
|
||||
Unmarshal(input, to);
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
T to;
|
||||
Unmarshal(input, to, bond::GetRuntimeSchema<T>());
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
bond::bonded<T> to;
|
||||
Unmarshal(input, to, bond::GetRuntimeSchema<T>());
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
auto to = bond::Unmarshal<T>(input);
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
|
||||
{
|
||||
auto to = bond::Unmarshal<T>(input, bond::GetRuntimeSchema<T>());
|
||||
UT_AssertIsTrue(from == to);
|
||||
UT_Compare(from, to);
|
||||
}
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
@ -234,10 +240,10 @@ void SimpleStructTests(const char* name)
|
|||
AllBindingAndMapping1, Reader, Writer, UsingImport>(suite, "Imported struct");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValues, Reader, Writer, StructWithDefaults>(suite, "Omitting default values");
|
||||
DefaultValues, Reader, Writer, StructWithDefaults, bond::BuiltInProtocols>(suite, "Omitting default values");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValues, Reader, Writer, OptionalContainers>(suite, "Omitting empty containers");
|
||||
DefaultValues, Reader, Writer, OptionalContainers, bond::BuiltInProtocols>(suite, "Omitting empty containers");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
AllBindingAndMapping2, Reader, Writer, NestedStruct1, NestedStruct1OptionalBondedView>(suite, "Optional bonded field");
|
||||
|
@ -259,19 +265,19 @@ void SimpleStructTests(const char* name)
|
|||
}
|
||||
|
||||
|
||||
template <uint16_t N, typename Reader, typename Writer>
|
||||
template <uint16_t N, typename Reader, typename Writer, typename Protocols>
|
||||
void OmittingDefaultsTests(const char* name)
|
||||
{
|
||||
UnitTestSuite suite(name);
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValues, Reader, Writer, StructWithDefaults>(suite, "Omitting default values");
|
||||
DefaultValues, Reader, Writer, StructWithDefaults, Protocols>(suite, "Omitting default values");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValues, Reader, Writer, OptionalContainers>(suite, "Omitting empty containers");
|
||||
DefaultValues, Reader, Writer, OptionalContainers, Protocols>(suite, "Omitting empty containers");
|
||||
|
||||
AddTestCase<TEST_ID(N),
|
||||
DefaultValues, Reader, Writer, OptionalNothing>(suite, "Omitting nothing");
|
||||
DefaultValues, Reader, Writer, OptionalNothing, Protocols>(suite, "Omitting nothing");
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,7 +314,8 @@ void SerializationTest::SimpleStructTestsInit()
|
|||
OmittingDefaultsTests<
|
||||
0x905,
|
||||
UntaggedProtocolReader<bond::InputBuffer>,
|
||||
UntaggedProtocolWriter<bond::OutputBuffer> >("Omitting defaults for untagged protocol");
|
||||
UntaggedProtocolWriter<bond::OutputBuffer>,
|
||||
bond::BuiltInProtocols::Append<UntaggedProtocolReader<bond::InputBuffer> > >("Omitting defaults for untagged protocol");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,83 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
namespace unittest
|
||||
{
|
||||
|
||||
inline bool operator==(const SimpleStruct& left, const SimpleStructView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const SimpleStruct& left, const SimpleStructView& right)
|
||||
{
|
||||
return left.m_bool == right.m_bool
|
||||
&& left.m_str == right.m_str
|
||||
&& left.m_int8 == right.m_int8
|
||||
&& left.m_uint64 == right.m_uint64
|
||||
&& left.m_float == right.m_float
|
||||
&& left.m_enum1 == right.m_enum1;
|
||||
return Compare<Protocols>(left.m_bool, right.m_bool)
|
||||
&& Compare<Protocols>(left.m_str, right.m_str)
|
||||
&& Compare<Protocols>(left.m_int8, right.m_int8)
|
||||
&& Compare<Protocols>(left.m_uint64, right.m_uint64)
|
||||
&& Compare<Protocols>(left.m_float, right.m_float)
|
||||
&& Compare<Protocols>(left.m_enum1, right.m_enum1);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const NestedStruct& left, const NestedStructView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const NestedStruct& left, const NestedStructView& right)
|
||||
{
|
||||
return left.m_int8 == right.m_int8
|
||||
&& left.m_int16 == right.m_int16
|
||||
&& Equal(left.n1, right.n1);
|
||||
return Compare<Protocols>(left.m_int8, right.m_int8)
|
||||
&& Compare<Protocols>(left.m_int16, right.m_int16)
|
||||
&& Equal<Protocols>(left.n1, right.n1);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const StructWithBase& left, const SimpleStruct& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const StructWithBase& left, const SimpleStruct& right)
|
||||
{
|
||||
return Equal(static_cast<SimpleStruct>(left), right);
|
||||
return Equal<Protocols>(static_cast<SimpleStruct>(left), right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const StructWithBase& left, const SimpleBase& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const StructWithBase& left, const SimpleBase& right)
|
||||
{
|
||||
return Equal(static_cast<SimpleBase>(left), right);
|
||||
return Equal<Protocols>(static_cast<SimpleBase>(left), right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const SimpleBase& left, const SimpleBaseView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const SimpleBase& left, const SimpleBaseView& right)
|
||||
{
|
||||
return left.m_int32 == right.m_int32
|
||||
&& left.m_enum1 == right.m_enum1
|
||||
&& BaseIsEqual(left, right);
|
||||
return Compare<Protocols>(left.m_int32, right.m_int32)
|
||||
&& Compare<Protocols>(left.m_enum1, right.m_enum1)
|
||||
&& BaseIsEqual<Protocols>(left, right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const StructWithBase& left, const StructWithBaseView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const StructWithBase& left, const StructWithBaseView& right)
|
||||
{
|
||||
return left.m_str == right.m_str
|
||||
&& left.m_uint32 == right.m_uint32
|
||||
&& BaseIsEqual(left, right);
|
||||
return Compare<Protocols>(left.m_str, right.m_str)
|
||||
&& Compare<Protocols>(left.m_uint32, right.m_uint32)
|
||||
&& BaseIsEqual<Protocols>(left, right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const NestedWithBase& left, const NestedWithBaseView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const NestedWithBase& left, const NestedWithBaseView& right)
|
||||
{
|
||||
return Equal(left.n2, right.n2)
|
||||
&& Equal(left.d, right.d)
|
||||
&& BaseIsEqual(left, right);
|
||||
return Equal<Protocols>(left.n2, right.n2)
|
||||
&& Equal<Protocols>(left.d, right.d)
|
||||
&& BaseIsEqual<Protocols>(left, right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const NestedWithBase& left, const NestedWithBase2& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const NestedWithBase& left, const NestedWithBase2& right)
|
||||
{
|
||||
return Equal(static_cast<NestedWithBase2>(left), right);
|
||||
return Equal<Protocols>(static_cast<NestedWithBase2>(left), right);
|
||||
}
|
||||
|
||||
|
||||
inline bool operator==(const ListWithBase& left, const ListWithBaseView& right)
|
||||
template <typename Protocols>
|
||||
inline bool Compare(const ListWithBase& left, const ListWithBaseView& right)
|
||||
{
|
||||
return Equal(left.l1, right.l1)
|
||||
&& Equal(left.v3, right.v3);
|
||||
return Equal<Protocols>(left.l1, right.l1)
|
||||
&& Equal<Protocols>(left.v3, right.v3);
|
||||
}
|
||||
|
||||
|
||||
template <typename NestedStruct1>
|
||||
inline bool operator==(const NestedStruct1& left, const NestedStruct1OptionalBondedView& right)
|
||||
template <typename Protocols, typename NestedStruct1>
|
||||
inline bool Compare(const NestedStruct1& left, const NestedStruct1OptionalBondedView& right)
|
||||
{
|
||||
return Equal(left.s, right.s);
|
||||
return Equal<Protocols>(left.s, right.s);
|
||||
}
|
||||
|
||||
} // namespace unittest
|
||||
|
||||
class SerializationTest
|
||||
{
|
||||
|
|
|
@ -113,171 +113,34 @@ private:
|
|||
};
|
||||
|
||||
|
||||
// Unspecialized unit test wrappers
|
||||
template <bool Enable, typename Test>
|
||||
struct TestCase
|
||||
template <uint32_t Key, typename Test>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name, std::true_type)
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test::Run, key, name);
|
||||
}
|
||||
};
|
||||
suite.Add(Test::Run, Key, name);
|
||||
}
|
||||
|
||||
template <bool Enable, template <typename T1> class Test, typename T1>
|
||||
struct TestCase1
|
||||
template <uint32_t Key, typename Test>
|
||||
inline void AddTestCase(UnitTestSuite& /*suite*/, const char* /*name*/, std::false_type)
|
||||
{}
|
||||
|
||||
template <uint32_t Key, template <typename...> class Test, typename... T>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name, std::true_type)
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1>::Run, key, name);
|
||||
}
|
||||
};
|
||||
suite.Add(Test<T...>::Run, Key, name);
|
||||
}
|
||||
|
||||
template <bool Enable, template <typename T1, typename T2> class Test, typename T1, typename T2>
|
||||
struct TestCase2
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1, T2>::Run, key, name);
|
||||
}
|
||||
};
|
||||
template <uint32_t Key, template <typename...> class Test, typename... T>
|
||||
inline void AddTestCase(UnitTestSuite& /*suite*/, const char* /*name*/, std::false_type)
|
||||
{}
|
||||
|
||||
template <bool Enable, template <typename T1, typename T2, typename T3> class Test, typename T1, typename T2, typename T3>
|
||||
struct TestCase3
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1, T2, T3>::Run, key, name);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool Enable, template <typename T1, typename T2, typename T3, typename T4> class Test, typename T1, typename T2, typename T3, typename T4>
|
||||
struct TestCase4
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1, T2, T3, T4>::Run, key, name);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool Enable, template <typename T1, typename T2, typename T3, typename T4, typename T5> class Test, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
struct TestCase5
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1, T2, T3, T4, T5>::Run, key, name);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool Enable, template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> class Test, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
struct TestCase6
|
||||
{
|
||||
static void Register(UnitTestSuite& suite, uint32_t key, const char* name)
|
||||
{
|
||||
suite.Add(Test<T1, T2, T3, T4, T5, T6>::Run, key, name);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Unit test wrapper specialization for disabled tests
|
||||
template <typename Test>
|
||||
struct TestCase<false, Test>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename T1> class Test, typename T1>
|
||||
struct TestCase1<false, Test, T1>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <template <typename T1, typename T2> class Test, typename T1, typename T2>
|
||||
struct TestCase2<false, Test, T1, T2>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <template <typename T1, typename T2, typename T3> class Test, typename T1, typename T2, typename T3>
|
||||
struct TestCase3<false, Test, T1, T2, T3>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename T1, typename T2, typename T3, typename T4> class Test, typename T1, typename T2, typename T3, typename T4>
|
||||
struct TestCase4<false, Test, T1, T2, T3, T4>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename T1, typename T2, typename T3, typename T4, typename T5> class Test, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
struct TestCase5<false, Test, T1, T2, T3, T4 ,T5>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> class Test, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
struct TestCase6<false, Test, T1, T2, T3, T4 ,T5, T6>
|
||||
{
|
||||
static void Register(UnitTestSuite& /*suite*/, uint32_t /*key*/, const char* /*name*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Helper function to add a unit test
|
||||
template <bool Pred, uint32_t Key, typename Test>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase<ENABLE(Pred, Key), Test>().Register(suite, Key, name);
|
||||
AddTestCase<Key, Test>(suite, name, std::integral_constant<bool, ENABLE(Pred, Key)>{});
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1> class Test, typename T1>
|
||||
template <bool Pred, uint32_t Key, template <typename...> class Test, typename... T>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase1<ENABLE(Pred, Key), Test, T1>().Register(suite, Key, name);
|
||||
AddTestCase<Key, Test, T...>(suite, name, std::integral_constant<bool, ENABLE(Pred, Key)>{});
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1, typename T2> class Test, typename T1, typename T2>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase2<ENABLE(Pred, Key), Test, T1, T2>().Register(suite, Key, name);
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1, typename T2, typename T3> class Test, typename T1, typename T2, typename T3>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase3<ENABLE(Pred, Key), Test, T1, T2, T3>().Register(suite, Key, name);
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1, typename T2, typename T3, typename T4> class Test, typename T1, typename T2, typename T3, typename T4>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase4<ENABLE(Pred, Key), Test, T1, T2, T3, T4>().Register(suite, Key, name);
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1, typename T2, typename T3, typename T4, typename T5> class Test, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase5<ENABLE(Pred, Key), Test, T1, T2, T3, T4, T5>().Register(suite, Key, name);
|
||||
}
|
||||
|
||||
template <bool Pred, uint32_t Key, template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> class Test, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
inline void AddTestCase(UnitTestSuite& suite, const char* name)
|
||||
{
|
||||
TestCase6<ENABLE(Pred, Key), Test, T1, T2, T3, T4, T5, T6>().Register(suite, Key, name);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,19 @@ struct SkipTypes
|
|||
};
|
||||
|
||||
|
||||
template <typename T> struct
|
||||
is_protocols
|
||||
: std::false_type {};
|
||||
|
||||
template <typename... T> struct
|
||||
is_protocols<bond::Protocols<T...>>
|
||||
: std::true_type {};
|
||||
|
||||
template <> struct
|
||||
is_protocols<bond::BuiltInProtocols>
|
||||
: std::true_type {};
|
||||
|
||||
|
||||
template <typename T>
|
||||
const std::vector<T>& IntegerConstants()
|
||||
{
|
||||
|
@ -112,6 +125,7 @@ const std::vector<T>& IntegerConstants()
|
|||
|
||||
// CreateSelfMappings creates mappings compatible with MapTo<T> transform
|
||||
// for every field of the specified bond structure.
|
||||
template <typename Protocols>
|
||||
class CreateSelfMappings
|
||||
: public bond::SerializingTransform
|
||||
{
|
||||
|
@ -135,7 +149,7 @@ public:
|
|||
bool Base(const T& value) const
|
||||
{
|
||||
_path.push_back(bond::mapping_base);
|
||||
bond::Apply(CreateSelfMappings(_mappings[bond::mapping_base].fields, _path), value);
|
||||
bond::Apply<Protocols>(CreateSelfMappings(_mappings[bond::mapping_base].fields, _path), value);
|
||||
_path.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
@ -156,7 +170,7 @@ public:
|
|||
Field(uint16_t id, const bond::Metadata& /*metadata*/, const T& value) const
|
||||
{
|
||||
_path.push_back(id);
|
||||
bond::Apply(CreateSelfMappings(_mappings[id].fields, _path), value);
|
||||
bond::Apply<Protocols>(CreateSelfMappings(_mappings[id].fields, _path), value);
|
||||
_path.pop_back();
|
||||
|
||||
return false;
|
||||
|
@ -247,45 +261,45 @@ struct Factory<bond::CompactBinaryWriter<Buffer> >
|
|||
};
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
template <typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
Reader Serialize(const T& x, uint16_t version = bond::v1)
|
||||
{
|
||||
typename Writer::Buffer output_buffer(4096);
|
||||
|
||||
// serialize value to output
|
||||
Factory<Writer>::Call(output_buffer, version, boost::bind(
|
||||
bond::Serialize<T, Writer>, x, _1));
|
||||
bond::Serialize<Protocols, T, Writer>, x, _1));
|
||||
|
||||
typename Reader::Buffer input_buffer(output_buffer.GetBuffer());
|
||||
return Factory<Reader>::Create(input_buffer, version);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols, typename From, typename To>
|
||||
typename boost::disable_if<bond::uses_static_parser<Reader> >::type
|
||||
SerializeDeserialize(const From& from, To& to, uint16_t version = bond::v1)
|
||||
{
|
||||
bond::Deserialize(Serialize<Reader, Writer>(from, version), to);
|
||||
bond::Deserialize<Protocols>(Serialize<Reader, Writer, Protocols>(from, version), to);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols, typename From, typename To>
|
||||
typename boost::enable_if<bond::uses_static_parser<Reader> >::type
|
||||
SerializeDeserialize(const From& from, To& to, uint16_t version = bond::v1)
|
||||
{
|
||||
bond::bonded<void>(Serialize<Reader, Writer>(from, version), bond::GetRuntimeSchema<From>()).Deserialize(to);
|
||||
bond::bonded<void>(Serialize<Reader, Writer, Protocols>(from, version), bond::GetRuntimeSchema<From>()).template Deserialize<Protocols>(to);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename Payload, typename T>
|
||||
template <typename Reader, typename Writer, typename Protocols = bond::BuiltInProtocols, typename Payload, typename T>
|
||||
Reader Merge(const Payload& payload, const T& x, uint16_t version = bond::v1)
|
||||
{
|
||||
typename Writer::Buffer output_buffer;
|
||||
|
||||
// merge x with serialized payload into output
|
||||
Factory<Writer>::Call(output_buffer, version, boost::bind(
|
||||
bond::Merge<T, Reader, Writer>, x, Serialize<Reader, Writer>(payload, version), _1));
|
||||
bond::Merge<Protocols, T, Reader, Writer>, x, Serialize<Reader, Writer, Protocols>(payload, version), _1));
|
||||
|
||||
typename Reader::Buffer input_buffer(output_buffer.GetBuffer());
|
||||
|
||||
|
@ -293,14 +307,14 @@ Reader Merge(const Payload& payload, const T& x, uint16_t version = bond::v1)
|
|||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename BondedType, typename T>
|
||||
template <typename Reader, typename Writer, typename BondedType, typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
bond::bonded<BondedType> GetBonded(T x, uint16_t version = bond::v1)
|
||||
{
|
||||
return bond::bonded<BondedType>(Serialize<Reader, Writer>(x, version));
|
||||
return bond::bonded<BondedType>(Serialize<Reader, Writer, Protocols>(x, version));
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
void InitRandom(T& x, uint32_t max_string_length = c_max_string_length, uint32_t max_list_size = c_max_list_size)
|
||||
{
|
||||
// Instead of deserializing directly from RandomProtocolReader to instance of T
|
||||
|
@ -314,11 +328,11 @@ void InitRandom(T& x, uint32_t max_string_length = c_max_string_length, uint32_t
|
|||
bond::OutputBuffer buffer(1024);
|
||||
bond::FastBinaryWriter<bond::OutputBuffer> writer(buffer);
|
||||
|
||||
random.Serialize(writer);
|
||||
random.template Serialize<Protocols>(writer);
|
||||
|
||||
bond::FastBinaryReader<bond::InputBuffer> reader(buffer.GetBuffer());
|
||||
|
||||
bond::Deserialize(reader, x);
|
||||
bond::Deserialize<Protocols>(reader, x);
|
||||
}
|
||||
|
||||
|
||||
|
@ -336,12 +350,12 @@ void Fixup(SkipStruct<T>& x)
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename Protocols = bond::BuiltInProtocols>
|
||||
T InitRandom(uint32_t max_string_length = c_max_string_length, uint32_t max_list_size = c_max_list_size)
|
||||
{
|
||||
T x;
|
||||
|
||||
InitRandom(x, max_string_length, max_list_size);
|
||||
InitRandom<Protocols>(x, max_string_length, max_list_size);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
@ -352,21 +366,21 @@ is_optional_field
|
|||
: std::is_same<typename Field::field_modifier, bond::reflection::optional_field_modifier> {};
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename Protocols = bond::BuiltInProtocols, typename T>
|
||||
void CopyAndMove(const T& src)
|
||||
{
|
||||
T x(src);
|
||||
UT_AssertIsTrue(Equal(x, src));
|
||||
UT_Equal_P(x, src, Protocols);
|
||||
|
||||
#ifndef BOND_NO_CXX11_RVALUE_REFERENCES
|
||||
T y(std::move(x));
|
||||
UT_AssertIsTrue(Equal(y, src));
|
||||
UT_Equal_P(y, src, Protocols);
|
||||
UT_AssertIsTrue(moved(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
void Binding(const From& from, uint16_t version = bond::v1)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((std::is_same<BondedType, From>::value
|
||||
|
@ -374,7 +388,7 @@ void Binding(const From& from, uint16_t version = bond::v1)
|
|||
|
||||
// Compile-time schema
|
||||
{
|
||||
bond::bonded<BondedType> bonded(GetBonded<Reader, Writer, BondedType>(from, version));
|
||||
bond::bonded<BondedType> bonded(GetBonded<Reader, Writer, BondedType, Protocols>(from, version));
|
||||
|
||||
To to;
|
||||
|
||||
|
@ -387,18 +401,18 @@ void Binding(const From& from, uint16_t version = bond::v1)
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
to = InitRandom<To>();
|
||||
to = InitRandom<To, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Apply(bond::To<To>(to), bonded);
|
||||
bond::Apply<Protocols>(bond::To<To, Protocols>(to), bonded);
|
||||
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
|
||||
// Runtime schema
|
||||
{
|
||||
bond::bonded<void> bonded(GetBonded<Reader, Writer, BondedType>(from, version));
|
||||
bond::bonded<void> bonded(GetBonded<Reader, Writer, BondedType, Protocols>(from, version));
|
||||
|
||||
To to;
|
||||
|
||||
|
@ -411,41 +425,41 @@ void Binding(const From& from, uint16_t version = bond::v1)
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
to = InitRandom<To>();
|
||||
to = InitRandom<To, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Apply(bond::To<To>(to), bonded);
|
||||
bond::Apply<Protocols>(bond::To<To, Protocols>(to), bonded);
|
||||
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
|
||||
CopyAndMove(from);
|
||||
CopyAndMove<Protocols>(from);
|
||||
}
|
||||
|
||||
|
||||
template <typename To, typename BondedType>
|
||||
template <typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<(bond::detail::hierarchy_depth<typename BondedType::Schema>::value
|
||||
== bond::detail::hierarchy_depth<typename To::Schema>::value)>::type
|
||||
InitMappings(bond::Mappings& mappings)
|
||||
{
|
||||
To to;
|
||||
bond::Apply(CreateSelfMappings(mappings), to);
|
||||
bond::Apply<Protocols>(CreateSelfMappings<Protocols>(mappings), to);
|
||||
}
|
||||
|
||||
|
||||
template <typename To, typename BondedType>
|
||||
template <typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<(bond::detail::hierarchy_depth<typename BondedType::Schema>::value
|
||||
> bond::detail::hierarchy_depth<typename To::Schema>::value)>::type
|
||||
InitMappings(bond::Mappings& mappings)
|
||||
{
|
||||
// The data we are deserializing has deeper hierarchy than the target variable
|
||||
// so we will only map fields of the base struct, and recurse to next level.
|
||||
InitMappings<To, typename BondedType::Schema::base>(mappings[bond::mapping_base].fields);
|
||||
InitMappings<To, typename BondedType::Schema::base, Protocols>(mappings[bond::mapping_base].fields);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
void Mapping(const From& from, uint16_t version = bond::v1)
|
||||
{
|
||||
#ifdef UNIT_TEST_MAPPING
|
||||
|
@ -458,36 +472,36 @@ void Mapping(const From& from, uint16_t version = bond::v1)
|
|||
|
||||
// Compile-time schema
|
||||
{
|
||||
bond::bonded<BondedType> bonded(GetBonded<Reader, Writer, BondedType>(from, version));
|
||||
bond::bonded<BondedType> bonded(GetBonded<Reader, Writer, BondedType, Protocols>(from, version));
|
||||
|
||||
To to;
|
||||
|
||||
if (boost::mpl::count_if<From::Schema::fields, is_optional_field<_> >::value == 0)
|
||||
{
|
||||
to = InitRandom<To>();
|
||||
to = InitRandom<To, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Apply(bond::MapTo<To>(to, mappings), bonded);
|
||||
bond::Apply<Protocols>(bond::MapTo<To, Protocols>(to, mappings), bonded);
|
||||
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
|
||||
// Runtime schema
|
||||
{
|
||||
bond::bonded<void> bonded(GetBonded<Reader, Writer, BondedType>(from, version));
|
||||
bond::bonded<void> bonded(GetBonded<Reader, Writer, BondedType, Protocols>(from, version));
|
||||
|
||||
To to;
|
||||
|
||||
if (boost::mpl::count_if<From::Schema::fields, is_optional_field<_> >::value == 0)
|
||||
{
|
||||
to = InitRandom<To>();
|
||||
to = InitRandom<To, Protocols>();
|
||||
Fixup(to);
|
||||
}
|
||||
|
||||
Apply(bond::MapTo<To>(to, mappings), bonded);
|
||||
bond::Apply<Protocols>(bond::MapTo<To, Protocols>(to, mappings), bonded);
|
||||
|
||||
UT_AssertIsTrue(Equal(from, to));
|
||||
UT_Equal_P(from, to, Protocols);
|
||||
}
|
||||
#else
|
||||
(void)from;
|
||||
|
@ -496,101 +510,102 @@ void Mapping(const From& from, uint16_t version = bond::v1)
|
|||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
void AllBinding()
|
||||
{
|
||||
// default value
|
||||
Binding<Reader, Writer, From, To, BondedType>(From());
|
||||
Binding<Reader, Writer, From, To, BondedType>(From(), Reader::version);
|
||||
Binding<Reader, Writer, From, To, BondedType, Protocols>(From());
|
||||
Binding<Reader, Writer, From, To, BondedType, Protocols>(From(), Reader::version);
|
||||
|
||||
// random values
|
||||
for (uint32_t i = 0; i < c_iterations; ++i)
|
||||
{
|
||||
Binding<Reader, Writer, From, To, BondedType>(InitRandom<From>());
|
||||
Binding<Reader, Writer, From, To, BondedType>(InitRandom<From>(), Reader::version);
|
||||
Binding<Reader, Writer, From, To, BondedType, Protocols>(InitRandom<From, Protocols>());
|
||||
Binding<Reader, Writer, From, To, BondedType, Protocols>(InitRandom<From, Protocols>(), Reader::version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
void AllMapping()
|
||||
{
|
||||
// default value
|
||||
Mapping<Reader, Writer, From, To, BondedType>(From());
|
||||
Mapping<Reader, Writer, From, To, BondedType>(From(), Reader::version);
|
||||
Mapping<Reader, Writer, From, To, BondedType, Protocols>(From());
|
||||
Mapping<Reader, Writer, From, To, BondedType, Protocols>(From(), Reader::version);
|
||||
|
||||
// random values
|
||||
for (uint32_t i = 0; i < c_iterations; ++i)
|
||||
{
|
||||
Mapping<Reader, Writer, From, To, BondedType>(InitRandom<From>());
|
||||
Mapping<Reader, Writer, From, To, BondedType>(InitRandom<From>(), Reader::version);
|
||||
Mapping<Reader, Writer, From, To, BondedType, Protocols>(InitRandom<From, Protocols>());
|
||||
Mapping<Reader, Writer, From, To, BondedType, Protocols>(InitRandom<From, Protocols>(), Reader::version);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::disable_if<bond::uses_static_parser<Reader> >::type
|
||||
BindingAndMapping(const From& from)
|
||||
{
|
||||
Binding<Reader, Writer, From, To, From>(from);
|
||||
Mapping<Reader, Writer, From, To, From>(from);
|
||||
Binding<Reader, Writer, From, To, From, Protocols>(from);
|
||||
Mapping<Reader, Writer, From, To, From, Protocols>(from);
|
||||
|
||||
// For dynamic parser the schema doesn't have to exactly match the payload
|
||||
Binding<Reader, Writer, From, To, To>(from);
|
||||
Mapping<Reader, Writer, From, To, To>(from);
|
||||
Binding<Reader, Writer, From, To, To, Protocols>(from);
|
||||
Mapping<Reader, Writer, From, To, To, Protocols>(from);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if<bond::uses_static_parser<Reader> >::type
|
||||
BindingAndMapping(const From& from)
|
||||
{
|
||||
Binding<Reader, Writer, From, To, From>(from);
|
||||
Mapping<Reader, Writer, From, To, From>(from);
|
||||
Binding<Reader, Writer, From, To, From, Protocols>(from);
|
||||
Mapping<Reader, Writer, From, To, From, Protocols>(from);
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
void AllBindingAndMapping()
|
||||
{
|
||||
AllBinding<Reader, Writer, T, T, T>();
|
||||
AllMapping<Reader, Writer, T, T, T>();
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
typename boost::disable_if<bond::uses_static_parser<Reader> >::type
|
||||
template <typename Reader, typename Writer, typename T, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<!is_protocols<T>::value && is_protocols<Protocols>::value>::type
|
||||
AllBindingAndMapping()
|
||||
{
|
||||
AllBinding<Reader, Writer, From, To, From>();
|
||||
AllMapping<Reader, Writer, From, To, From>();
|
||||
AllBinding<Reader, Writer, T, T, T, Protocols>();
|
||||
AllMapping<Reader, Writer, T, T, T, Protocols>();
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<!bond::uses_static_parser<Reader>::value && !is_protocols<To>::value && is_protocols<Protocols>::value>::type
|
||||
AllBindingAndMapping()
|
||||
{
|
||||
AllBinding<Reader, Writer, From, To, From, Protocols>();
|
||||
AllMapping<Reader, Writer, From, To, From, Protocols>();
|
||||
|
||||
// For dynamic parser the schema doesn't have to exactly match the payload
|
||||
AllBinding<Reader, Writer, From, To, To>();
|
||||
AllMapping<Reader, Writer, From, To, To>();
|
||||
AllBinding<Reader, Writer, From, To, To, Protocols>();
|
||||
AllMapping<Reader, Writer, From, To, To, Protocols>();
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
typename boost::enable_if<bond::uses_static_parser<Reader> >::type
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<bond::uses_static_parser<Reader>::value && !is_protocols<To>::value && is_protocols<Protocols>::value>::type
|
||||
AllBindingAndMapping()
|
||||
{
|
||||
AllBinding<Reader, Writer, From, To, From>();
|
||||
AllMapping<Reader, Writer, From, To, From>();
|
||||
AllBinding<Reader, Writer, From, To, From, Protocols>();
|
||||
AllMapping<Reader, Writer, From, To, From, Protocols>();
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
typename boost::disable_if<bond::uses_static_parser<Reader> >::type
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<!bond::uses_static_parser<Reader>::value && !is_protocols<BondedType>::value && is_protocols<Protocols>::value>::type
|
||||
AllBindingAndMapping()
|
||||
{
|
||||
AllBinding<Reader, Writer, From, To, BondedType>();
|
||||
AllMapping<Reader, Writer, From, To, BondedType>();
|
||||
AllBinding<Reader, Writer, From, To, BondedType, Protocols>();
|
||||
AllMapping<Reader, Writer, From, To, BondedType, Protocols>();
|
||||
}
|
||||
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
typename boost::enable_if<bond::uses_static_parser<Reader> >::type
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
typename boost::enable_if_c<bond::uses_static_parser<Reader>::value && !is_protocols<BondedType>::value && is_protocols<Protocols>::value>::type
|
||||
AllBindingAndMapping()
|
||||
{
|
||||
// This function is noop for static parser.
|
||||
|
@ -601,23 +616,72 @@ AllBindingAndMapping()
|
|||
|
||||
|
||||
// Unit test wrappers for AllBindingAndMapping
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
template <typename Reader, typename Writer, typename T, typename Protocols = bond::BuiltInProtocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping1)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, T, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols = bond::BuiltInProtocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping2)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols = bond::BuiltInProtocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping3)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To, BondedType, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
#else
|
||||
|
||||
template <typename Reader, typename Writer, typename T>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping1)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, T>();
|
||||
AllBindingAndMapping<Reader, Writer, T, bond::BuiltInProtocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename T, typename Protocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping1_CustomProtocols)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, T, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping2)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To>();
|
||||
AllBindingAndMapping<Reader, Writer, From, To, bond::BuiltInProtocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename Protocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping2_CustomProtocols)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping3)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To, BondedType>();
|
||||
AllBindingAndMapping<Reader, Writer, From, To, BondedType, bond::BuiltInProtocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
template <typename Reader, typename Writer, typename From, typename To, typename BondedType, typename Protocols>
|
||||
TEST_CASE_BEGIN(AllBindingAndMapping3_CustomProtocols)
|
||||
{
|
||||
AllBindingAndMapping<Reader, Writer, From, To, BondedType, Protocols>();
|
||||
}
|
||||
TEST_CASE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <bond/core/null.h>
|
||||
#include <bond/core/detail/protocol_visitors.h>
|
||||
#include <bond/protocol/simple_binary.h>
|
||||
|
||||
#include <stack>
|
||||
|
@ -12,9 +13,9 @@
|
|||
template <typename Buffer>
|
||||
class UntaggedProtocolWriter;
|
||||
|
||||
template <typename Buffer>
|
||||
template <typename Buffer, typename MarshaledBondedProtocols = bond::Protocols<bond::CompactBinaryReader<Buffer> > >
|
||||
class UntaggedProtocolReader
|
||||
: public bond::SimpleBinaryReader<Buffer>
|
||||
: public bond::SimpleBinaryReader<Buffer, MarshaledBondedProtocols>
|
||||
{
|
||||
public:
|
||||
typedef bond::StaticParser<UntaggedProtocolReader&> Parser;
|
||||
|
@ -23,7 +24,7 @@ public:
|
|||
BOND_STATIC_CONSTEXPR uint16_t magic = 0xFFFF;
|
||||
|
||||
UntaggedProtocolReader(typename boost::call_traits<Buffer>::param_type input)
|
||||
: bond::SimpleBinaryReader<Buffer>(input)
|
||||
: bond::SimpleBinaryReader<Buffer, MarshaledBondedProtocols>(input)
|
||||
{}
|
||||
|
||||
bool ReadVersion()
|
||||
|
@ -37,13 +38,12 @@ public:
|
|||
&& this->_version <= UntaggedProtocolReader::version;
|
||||
}
|
||||
|
||||
using bond::SimpleBinaryReader<Buffer>::Skip;
|
||||
using bond::SimpleBinaryReader<Buffer, MarshaledBondedProtocols>::Skip;
|
||||
|
||||
template <typename T>
|
||||
void Skip(const bond::bonded<T, UntaggedProtocolReader&>& bonded)
|
||||
{
|
||||
// Skip the structure field-by-field by applying Null transform
|
||||
Apply(bond::Null(), bonded);
|
||||
bond::detail::Skip(bonded);
|
||||
}
|
||||
|
||||
// ReadStructBegin
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include <bond/core/blob.h>
|
||||
#include <bond/core/exception.h>
|
||||
#include <bond/stream/input_buffer.h>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/transform_view.hpp>
|
||||
#include <boost/mpl/joint_view.hpp>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
@ -54,7 +51,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
InputFile& operator=(const InputFile&);
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
InputFile& operator=(const InputFile& that)
|
||||
{
|
||||
InputFile temp(that);
|
||||
file = std::move(temp.file);
|
||||
name = std::move(temp.name);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator==(const InputFile& that) const
|
||||
{
|
||||
|
@ -90,17 +95,17 @@ public:
|
|||
return std::make_pair(input, input.file.tellg());
|
||||
}
|
||||
|
||||
friend bond::InputBuffer CreateInputBuffer(const InputFile& /*other*/, const bond::blob& blob)
|
||||
{
|
||||
return bond::InputBuffer(blob);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::ifstream file;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
||||
inline bond::InputBuffer CreateInputBuffer(const InputFile& /*other*/, const bond::blob& blob)
|
||||
{
|
||||
return bond::InputBuffer(blob);
|
||||
}
|
||||
|
||||
inline bond::blob GetBufferRange(
|
||||
std::pair<InputFile, std::ifstream::pos_type> begin,
|
||||
const std::pair<InputFile, std::ifstream::pos_type>& end)
|
||||
|
@ -113,45 +118,8 @@ inline bond::blob GetBufferRange(
|
|||
}
|
||||
|
||||
|
||||
template <typename InputBuffer>
|
||||
struct rebind_input_buffer
|
||||
{
|
||||
template <typename T> struct
|
||||
transform
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <template <typename> class Reader, typename Buffer> struct
|
||||
transform<Reader<Buffer>>
|
||||
{
|
||||
typedef Reader<InputBuffer> type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
namespace bond
|
||||
{
|
||||
template <> struct
|
||||
customize<protocols>
|
||||
{
|
||||
template <typename T> struct
|
||||
modify
|
||||
{
|
||||
typedef typename boost::mpl::transform_view<
|
||||
T,
|
||||
typename rebind_input_buffer<InputFile>::template transform<boost::mpl::_>
|
||||
>::type protocols_with_inputfile;
|
||||
BOND_DEFINE_BUFFER_MAGIC(InputFile, 0x4649 /*IF*/);
|
||||
|
||||
typedef typename boost::mpl::transform_view<
|
||||
T,
|
||||
typename rebind_input_buffer<InputFile&>::template transform<boost::mpl::_>
|
||||
>::type protocols_with_inputfile_ref;
|
||||
|
||||
typedef typename boost::mpl::joint_view<T, protocols_with_inputfile>::type type1;
|
||||
|
||||
typedef typename boost::mpl::joint_view<type1, protocols_with_inputfile_ref>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace bond
|
||||
} // namespace bond
|
||||
|
|
|
@ -97,6 +97,21 @@ bool TryProtocol(Reader reader, int confidence = 5)
|
|||
}
|
||||
|
||||
|
||||
// Here using a bond::InputBuffer for marshaled bonded protocols
|
||||
// instead of defaulted one because corresponding CreateInputBuffer
|
||||
// returns bond::InputBuffer instead of InputFile.
|
||||
using MarshaledBondedProtocols = bond::Protocols<bond::CompactBinaryReader<bond::InputBuffer> >;
|
||||
|
||||
using NewProtocols = bond::BuiltInProtocols::Append<
|
||||
bond::CompactBinaryReader<InputFile>,
|
||||
bond::FastBinaryReader<InputFile>,
|
||||
bond::SimpleBinaryReader<InputFile, MarshaledBondedProtocols>,
|
||||
bond::SimpleJsonReader<InputFile>,
|
||||
bond::CompactBinaryReader<InputFile&>,
|
||||
bond::FastBinaryReader<InputFile&>,
|
||||
bond::SimpleBinaryReader<InputFile&, MarshaledBondedProtocols>,
|
||||
bond::SimpleJsonReader<InputFile&> >;
|
||||
|
||||
Protocol Guess(InputFile input)
|
||||
{
|
||||
uint16_t word;
|
||||
|
@ -134,8 +149,8 @@ bond::SchemaDef LoadSchema(const std::string& file)
|
|||
tryJson.Read(c);
|
||||
|
||||
return (c == '{')
|
||||
? bond::Deserialize<bond::SchemaDef>(bond::SimpleJsonReader<InputFile>(input))
|
||||
: bond::Unmarshal<bond::SchemaDef>(input);
|
||||
? bond::Deserialize<bond::SchemaDef, NewProtocols>(bond::SimpleJsonReader<InputFile>(input))
|
||||
: bond::Unmarshal<bond::SchemaDef, NewProtocols>(input);
|
||||
}
|
||||
|
||||
template <typename Reader, typename Writer>
|
||||
|
@ -144,11 +159,11 @@ void TranscodeFromTo(Reader& reader, Writer& writer, const Options& options)
|
|||
if (!options.schema.empty() && !options.schema.front().empty())
|
||||
{
|
||||
bond::SchemaDef schema(LoadSchema(options.schema.front()));
|
||||
bond::bonded<void, bond::ProtocolReader>(reader, bond::RuntimeSchema(schema)).Serialize(writer);
|
||||
bond::bonded<void, bond::ProtocolReader>(reader, bond::RuntimeSchema(schema)).template Serialize<NewProtocols>(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bond::bonded<UnknownSchema, bond::ProtocolReader>(reader).Serialize(writer);
|
||||
bond::bonded<UnknownSchema, bond::ProtocolReader>(reader).template Serialize<NewProtocols>(writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,11 +174,11 @@ void TranscodeFromTo(InputFile& input, Writer& writer, const Options& options)
|
|||
if (!options.schema.empty() && !options.schema.front().empty())
|
||||
{
|
||||
bond::SchemaDef schema(LoadSchema(options.schema.front()));
|
||||
bond::SelectProtocolAndApply(bond::RuntimeSchema(schema), input, SerializeTo(writer));
|
||||
bond::SelectProtocolAndApply<NewProtocols>(bond::RuntimeSchema(schema), input, bond::SerializeTo<NewProtocols>(writer));
|
||||
}
|
||||
else
|
||||
{
|
||||
bond::SelectProtocolAndApply<UnknownSchema>(input, SerializeTo(writer));
|
||||
bond::SelectProtocolAndApply<UnknownSchema, NewProtocols>(input, bond::SerializeTo<NewProtocols>(writer));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ private:
|
|||
.def(boost::python::init<const T&>())
|
||||
.def(schema_base_visitor<T>())
|
||||
.def("Deserialize",
|
||||
static_cast<void (bonded<T>::*)(T&) const>(&bonded<T>::template Deserialize<T>));
|
||||
static_cast<void (bonded<T>::*)(T&) const>(&bonded<T>::template Deserialize<BuiltInProtocols, T>));
|
||||
|
||||
// Expose struct T to Python
|
||||
struct_<T>()
|
||||
|
|
|
@ -367,12 +367,7 @@ private:
|
|||
InputBuffer input(data);
|
||||
// A workaround for GCC 4.8 which doesn't resolve the Apply overload below properly.
|
||||
// Apply<U>(To<U>(obj), input, protocol);
|
||||
bond::detail::NextProtocol<U>(
|
||||
typename FilteredProtocols<InputBuffer>::begin(),
|
||||
typename FilteredProtocols<InputBuffer>::end(),
|
||||
input,
|
||||
To<U>(obj),
|
||||
protocol);
|
||||
bond::detail::NextProtocol<U, bond::BuiltInProtocols>(input, To<U>(obj), protocol);
|
||||
}
|
||||
|
||||
static void deserialize_schema(const bond::blob& data, U& obj, const bond::SchemaDef& schema, uint16_t protocol = COMPACT_PROTOCOL)
|
||||
|
|
Загрузка…
Ссылка в новой задаче