Skip to content

Commit

Permalink
Merge branch 'develop' for 1.1.1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
AzothAmmo committed Apr 6, 2015
2 parents 81ec271 + 94d49c4 commit a248e3a
Show file tree
Hide file tree
Showing 18 changed files with 215 additions and 116 deletions.
2 changes: 1 addition & 1 deletion include/cereal/access.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ namespace cereal
@code{cpp}
struct MyType {};
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
CEREAL_SPECIALIZE_FOR_ARCHIVE( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
@endcode
@relates specialize
Expand Down
4 changes: 2 additions & 2 deletions include/cereal/archives/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ namespace cereal
{
search();

val = itsIteratorStack.back().value().GetInt();
val = static_cast<T>( itsIteratorStack.back().value().GetInt() );
++itsIteratorStack.back();
}

Expand All @@ -592,7 +592,7 @@ namespace cereal
{
search();

val = itsIteratorStack.back().value().GetUint();
val = static_cast<T>( itsIteratorStack.back().value().GetUint() );
++itsIteratorStack.back();
}

Expand Down
13 changes: 8 additions & 5 deletions include/cereal/archives/xml.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,12 @@ namespace cereal
itsOS << value << std::ends;

const auto strValue = itsOS.str();
// if there is the first or the last character in string is whitespace then add xml:space attribute
// the last character has index length-2 because there is \0 character at end added with std::ends
if( !strValue.empty() && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[strValue.length() - 2] ) ) )

// If the first or last character is a whitespace, add xml:space attribute
// the string always contains a '\0' added by std::ends, so the last character is at len-2 and an 'empty'
// string has a length of 1 or lower
const auto len = strValue.length();
if ( len > 1 && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[len - 2] ) ) )
{
itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "xml:space", "preserve" ) );
}
Expand Down Expand Up @@ -510,13 +513,13 @@ namespace cereal
//! Load an int8_t from the current top node (ensures we parse entire number)
void loadValue( int8_t & value )
{
int32_t val; loadValue( val ); value = val;
int32_t val; loadValue( val ); value = static_cast<int8_t>( val );
}

//! Load a uint8_t from the current top node (ensures we parse entire number)
void loadValue( uint8_t & value )
{
uint32_t val; loadValue( val ); value = val;
uint32_t val; loadValue( val ); value = static_cast<uint8_t>( val );
}

//! Loads a type best represented as an unsigned long from the current top node
Expand Down
50 changes: 32 additions & 18 deletions include/cereal/cereal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ namespace cereal
OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
{ }

OutputArchive & operator=( OutputArchive const & ) = delete;

//! Serializes all passed in data
/*! This is the primary interface for serializing data with an archive */
template <class ... Types> inline
Expand Down Expand Up @@ -364,11 +366,18 @@ namespace cereal
}

//! Helper macro that expands the requirements for activating an overload
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_output_versioning<T, ArchiveType>::value, \
(traits::is_specialized_##name<T, ArchiveType>::value || \
traits::is_output_serializable<T, ArchiveType>::value)> = traits::sfinae
/*! Requirements:
Has the requested serialization function
Does not have version and unversioned at the same time
Is output serializable AND
is specialized for this type of function OR
has no specialization at all */
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_output_versioning<T, ArchiveType>::value, \
(traits::is_output_serializable<T, ArchiveType>::value && \
(traits::is_specialized_##name<T, ArchiveType>::value || \
!traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae

//! Member serialization
template <class T, PROCESS_IF(member_serialize)> inline
Expand Down Expand Up @@ -420,7 +429,6 @@ namespace cereal

//! Empty class specialization
template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
!traits::is_specialized<T, ArchiveType>::value,
!traits::is_output_serializable<T, ArchiveType>::value,
std::is_empty<T>::value> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
Expand All @@ -430,11 +438,10 @@ namespace cereal

//! No matching serialization
/*! Invalid if we have invalid output versioning or
we have no specialization, are not output serializable, and either
we are not output serializable, and either
don't allow empty class ellision or allow it but are not serializing an empty class */
template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
(!traits::is_specialized<T, ArchiveType>::value &&
!traits::is_output_serializable<T, ArchiveType>::value &&
(!traits::is_output_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
Expand Down Expand Up @@ -587,6 +594,8 @@ namespace cereal
itsVersionedTypes()
{ }

InputArchive & operator=( InputArchive const & ) = delete;

//! Serializes all passed in data
/*! This is the primary interface for serializing data with an archive */
template <class ... Types> inline
Expand Down Expand Up @@ -725,11 +734,18 @@ namespace cereal
}

//! Helper macro that expands the requirements for activating an overload
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_input_versioning<T, ArchiveType>::value, \
(traits::is_specialized_##name<T, ArchiveType>::value || \
traits::is_input_serializable<T, ArchiveType>::value)> = traits::sfinae
/*! Requirements:
Has the requested serialization function
Does not have version and unversioned at the same time
Is input serializable AND
is specialized for this type of function OR
has no specialization at all */
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_input_versioning<T, ArchiveType>::value, \
(traits::is_input_serializable<T, ArchiveType>::value && \
(traits::is_specialized_##name<T, ArchiveType>::value || \
!traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae

//! Member serialization
template <class T, PROCESS_IF(member_serialize)> inline
Expand Down Expand Up @@ -787,7 +803,6 @@ namespace cereal

//! Empty class specialization
template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
!traits::is_specialized<T, ArchiveType>::value,
!traits::is_input_serializable<T, ArchiveType>::value,
std::is_empty<T>::value> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
Expand All @@ -797,11 +812,10 @@ namespace cereal

//! No matching serialization
/*! Invalid if we have invalid input versioning or
we have no specialization, are not input serializable, and either
we are not input serializable, and either
don't allow empty class ellision or allow it but are not serializing an empty class */
template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
(!traits::is_specialized<T, ArchiveType>::value &&
!traits::is_input_serializable<T, ArchiveType>::value &&
(!traits::is_input_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
Expand Down
6 changes: 6 additions & 0 deletions include/cereal/details/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ namespace cereal
static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
"Cannot pair a name to a NameValuePair" );

NameValuePair & operator=( NameValuePair const & ) = delete;

public:
//! Constructs a new NameValuePair
/*! @param n The name of the pair
Expand Down Expand Up @@ -254,6 +256,8 @@ namespace cereal
T,
typename std::decay<T>::type>::type;

SizeTag & operator=( SizeTag const & ) = delete;

public:
SizeTag( T && sz ) : size(std::forward<T>(sz)) {}

Expand Down Expand Up @@ -298,6 +302,8 @@ namespace cereal
/*! @internal */
MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}

MapItem & operator=( MapItem const & ) = delete;

KeyType key;
ValueType value;

Expand Down
120 changes: 63 additions & 57 deletions include/cereal/details/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,54 +884,6 @@ namespace cereal
(has_non_member_load<T, InputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
(has_non_member_versioned_load<T, InputArchive>::value && has_non_member_versioned_save<T, OutputArchive>::value)> {};

// ######################################################################
namespace detail
{
template <class T, class OutputArchive>
struct count_output_serializers : std::integral_constant<int,
has_member_save<T, OutputArchive>::value +
has_non_member_save<T, OutputArchive>::value +
has_member_serialize<T, OutputArchive>::value +
has_non_member_serialize<T, OutputArchive>::value +
has_member_save_minimal<T, OutputArchive>::value +
has_non_member_save_minimal<T, OutputArchive>::value +
/*-versioned---------------------------------------------------------*/
has_member_versioned_save<T, OutputArchive>::value +
has_non_member_versioned_save<T, OutputArchive>::value +
has_member_versioned_serialize<T, OutputArchive>::value +
has_non_member_versioned_serialize<T, OutputArchive>::value +
has_member_versioned_save_minimal<T, OutputArchive>::value +
has_non_member_versioned_save_minimal<T, OutputArchive>::value> {};
}

template <class T, class OutputArchive>
struct is_output_serializable : std::integral_constant<bool,
detail::count_output_serializers<T, OutputArchive>::value == 1> {};

// ######################################################################
namespace detail
{
template <class T, class InputArchive>
struct count_input_serializers : std::integral_constant<int,
has_member_load<T, InputArchive>::value +
has_non_member_load<T, InputArchive>::value +
has_member_serialize<T, InputArchive>::value +
has_non_member_serialize<T, InputArchive>::value +
has_member_load_minimal<T, InputArchive>::value +
has_non_member_load_minimal<T, InputArchive>::value +
/*-versioned---------------------------------------------------------*/
has_member_versioned_load<T, InputArchive>::value +
has_non_member_versioned_load<T, InputArchive>::value +
has_member_versioned_serialize<T, InputArchive>::value +
has_non_member_versioned_serialize<T, InputArchive>::value +
has_member_versioned_load_minimal<T, InputArchive>::value +
has_non_member_versioned_load_minimal<T, InputArchive>::value> {};
}

template <class T, class InputArchive>
struct is_input_serializable : std::integral_constant<bool,
detail::count_input_serializers<T, InputArchive>::value == 1> {};

// ######################################################################
template <class T, class OutputArchive>
struct has_invalid_output_versioning : std::integral_constant<bool,
Expand Down Expand Up @@ -970,15 +922,15 @@ namespace cereal

#undef CEREAL_MAKE_IS_SPECIALIZED_IMPL

//! Considered an error if specialization exists for more than one type
//! Number of specializations detected
template <class T, class A>
struct is_specialized_error : std::integral_constant<bool,
(is_specialized_member_serialize<T, A>::value +
is_specialized_member_load_save<T, A>::value +
is_specialized_member_load_save_minimal<T, A>::value +
is_specialized_non_member_serialize<T, A>::value +
is_specialized_non_member_load_save<T, A>::value +
is_specialized_non_member_load_save_minimal<T, A>::value) <= 1> {};
struct count_specializations : std::integral_constant<int,
is_specialized_member_serialize<T, A>::value +
is_specialized_member_load_save<T, A>::value +
is_specialized_member_load_save_minimal<T, A>::value +
is_specialized_non_member_serialize<T, A>::value +
is_specialized_non_member_load_save<T, A>::value +
is_specialized_non_member_load_save_minimal<T, A>::value> {};
} // namespace detail

//! Check if any specialization exists for a type
Expand All @@ -991,7 +943,7 @@ namespace cereal
detail::is_specialized_non_member_load_save<T, A>::value ||
detail::is_specialized_non_member_load_save_minimal<T, A>::value>
{
static_assert(detail::is_specialized_error<T, A>::value, "More than one explicit specialization detected for type.");
static_assert(detail::count_specializations<T, A>::value <= 1, "More than one explicit specialization detected for type.");
};

//! Create the static assertion for some specialization
Expand Down Expand Up @@ -1056,6 +1008,60 @@ namespace cereal
!(is_specialized_member_serialize<T, InputArchive>::value ||
is_specialized_member_load<T, InputArchive>::value))> {};

// ######################################################################
namespace detail
{
//! The number of output serialization functions available
/*! If specialization is being used, we'll count only those; otherwise we'll count everything */
template <class T, class OutputArchive>
struct count_output_serializers : std::integral_constant<int,
count_specializations<T, OutputArchive>::value ? count_specializations<T, OutputArchive>::value :
has_member_save<T, OutputArchive>::value +
has_non_member_save<T, OutputArchive>::value +
has_member_serialize<T, OutputArchive>::value +
has_non_member_serialize<T, OutputArchive>::value +
has_member_save_minimal<T, OutputArchive>::value +
has_non_member_save_minimal<T, OutputArchive>::value +
/*-versioned---------------------------------------------------------*/
has_member_versioned_save<T, OutputArchive>::value +
has_non_member_versioned_save<T, OutputArchive>::value +
has_member_versioned_serialize<T, OutputArchive>::value +
has_non_member_versioned_serialize<T, OutputArchive>::value +
has_member_versioned_save_minimal<T, OutputArchive>::value +
has_non_member_versioned_save_minimal<T, OutputArchive>::value> {};
}

template <class T, class OutputArchive>
struct is_output_serializable : std::integral_constant<bool,
detail::count_output_serializers<T, OutputArchive>::value == 1> {};

// ######################################################################
namespace detail
{
//! The number of input serialization functions available
/*! If specialization is being used, we'll count only those; otherwise we'll count everything */
template <class T, class InputArchive>
struct count_input_serializers : std::integral_constant<int,
count_specializations<T, InputArchive>::value ? count_specializations<T, InputArchive>::value :
has_member_load<T, InputArchive>::value +
has_non_member_load<T, InputArchive>::value +
has_member_serialize<T, InputArchive>::value +
has_non_member_serialize<T, InputArchive>::value +
has_member_load_minimal<T, InputArchive>::value +
has_non_member_load_minimal<T, InputArchive>::value +
/*-versioned---------------------------------------------------------*/
has_member_versioned_load<T, InputArchive>::value +
has_non_member_versioned_load<T, InputArchive>::value +
has_member_versioned_serialize<T, InputArchive>::value +
has_non_member_versioned_serialize<T, InputArchive>::value +
has_member_versioned_load_minimal<T, InputArchive>::value +
has_non_member_versioned_load_minimal<T, InputArchive>::value> {};
}

template <class T, class InputArchive>
struct is_input_serializable : std::integral_constant<bool,
detail::count_input_serializers<T, InputArchive>::value == 1> {};

// ######################################################################
// Base Class Support
namespace detail
Expand Down
11 changes: 11 additions & 0 deletions include/cereal/external/rapidjson/genericstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
#include "rapidjson.h"
#include <iostream>

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable: 4512) // assignment operator could not be generated
#pragma warning(disable: 4100) // unreferenced formal parameter
#endif

namespace rapidjson {

//! Wrapper of std::istream for input.
Expand Down Expand Up @@ -91,4 +98,8 @@ namespace rapidjson {

} // namespace rapidjson

// On MSVC, restore warnings state
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // RAPIDJSON_GENERICSTREAM_H_
1 change: 1 addition & 0 deletions include/cereal/external/rapidjson/reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4702) // uncreachable code
#endif

#ifndef RAPIDJSON_PARSE_ERROR
Expand Down
1 change: 1 addition & 0 deletions include/cereal/external/rapidxml/rapidxml.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4127) // Conditional expression is constant
#pragma warning(disable:4100) // unreferenced formal parameter
#endif

///////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions include/cereal/types/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ namespace cereal
{
PtrWrapper(T && p) : ptr(std::forward<T>(p)) {}
T & ptr;

PtrWrapper & operator=( PtrWrapper const & ) = delete;
};

//! Make a PtrWrapper
Expand Down
Loading

0 comments on commit a248e3a

Please sign in to comment.