Adding some specialize macros

Adding some macros for specialization in case people feel like
typing less scary looking template specialization code.

Modified static assert to remind people that specialization exists.

See issue #25
This commit is contained in:
Shane Grant
2014-01-24 15:47:33 -08:00
parent 942873c5a1
commit f8ec6251f0
3 changed files with 60 additions and 6 deletions

View File

@@ -320,11 +320,42 @@ namespace cereal
}
@endcode
You can also choose to use the macros CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES or
CEREAL_SPECIALIZE_FOR_ARCHIVE if you want to type a little bit less.
@tparam T The type to specialize the serialization for
@tparam S The specialization type to use for T
@ingroup Access */
template <class Archive, class T, specialization S>
struct specialize : public std::false_type {};
//! Convenienct macro for performing specialization for all archive types
/*! This performs specialization for the specific type for all types of archives.
This macro should be placed at the global namespace.
@begincode{cpp}
struct MyType {};
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( MyType, cereal::specialization::member_load_save );
@endcode
@relates specialize
@ingroup Access */
#define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization ) \
namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
//! Convenienct macro for performing specialization for a single archive type
/*! This performs specialization for the specific type for a single type of archive.
This macro should be placed at the global namespace.
@begincode{cpp}
struct MyType {};
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
@endcode
@relates specialize
@ingroup Access */
#define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization ) \
namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
} // namespace cereal
#endif // CEREAL_ACCESS_HPP_

View File

@@ -416,6 +416,7 @@ namespace cereal
{
static_assert(traits::is_output_serializable<T, ArchiveType>::value, "Trying to serialize an unserializable type with an output archive. \n\n"
"Types must either have a serialize function, or separate save/load functions (but not both). \n"
"Use specialization (see access.hpp) if you need to disambiguate between serialize vs save/load functions. \n"
"In addition, you may not mix versioned with non-versioned serialization functions. \n"
"Serialize functions generally have the following signature: \n\n"
"template<class Archive> \n"
@@ -740,6 +741,7 @@ namespace cereal
{
static_assert(traits::is_output_serializable<T, ArchiveType>::value, "Trying to serialize an unserializable type with an output archive. \n\n"
"Types must either have a serialize function, or separate save/load functions (but not both). \n"
"Use specialization (see access.hpp) if you need to disambiguate between serialize vs save/load functions. \n"
"In addition, you may not mix versioned with non-versioned serialization functions. \n"
"Serialize functions generally have the following signature: \n\n"
"template<class Archive> \n"

View File

@@ -313,6 +313,33 @@ struct OOJson
}
};
enum Bla
{
x,
y
};
template <class Archive>
void save( Archive & ar, Bla const & b )
{
std::cerr << "save" << std::endl;
ar( (const int &)b );
}
template <class Archive>
void load( Archive & ar, Bla & b )
{
std::cerr << "load" << std::endl;
ar( (int&)b );
}
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Bla, cereal::specialization::non_member_load_save )
//namespace cereal
//{
// //template <class Archive> struct specialize<Archive, Bla, cereal::specialization::non_member_load_save> {};
//}
// ######################################################################
int main()
{
@@ -348,12 +375,6 @@ int main()
archive( f );
archive( f2 );
enum Bla
{
x,
y
};
archive( Bla::x );
}