#pragma once #include #include #include "traits.hpp" namespace cereal { //! For holding name value pairs template struct NameValuePair { NameValuePair( std::string const & n, T & v ) : name(n), value(v) {} std::string name; T & value; }; //! Creates a name value pair template inline NameValuePair make_nvp( std::string const & name, T & value ) { return {name, value}; } //! Creates a name value pair for the variable T, using the same name #define CEREAL_NVP(T) ::cereal::make_nvp(#T, T); // ###################################################################### //! The base output archive class template class OutputArchive { public: OutputArchive(ArchiveType * const self) : self(self) { } //! Member serialization template typename std::enable_if() && traits::has_member_serialize(), ArchiveType &>::type operator & (T && t) { t.serialize(*self); return *self; } //! Non member serialization template typename std::enable_if() && traits::has_non_member_serialize(), ArchiveType &>::type operator & (T && t) { serialize(*self, std::forward(t)); return *self; } //! Member split (save) template typename std::enable_if() && traits::has_member_save(), ArchiveType &>::type operator & (T const & t) { t.save(*self); return *self; } //! Non member split (save) template typename std::enable_if() && traits::has_non_member_save(), ArchiveType &>::type operator & (T const & t) { save(*self, t); return *self; } //! No matching serialization template typename std::enable_if(), ArchiveType &>::type operator & (T const & t) { static_assert(traits::is_output_serializable(), "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" "Serialize functions generally have the following signature:\n\n" "template\n" " void serialize(int & ar)\n" " {\n" " ar & member1 & member2 & member3;\n" " }\n\n" ); return *self; } private: ArchiveType * const self; }; // class OutputArchive // ###################################################################### //! The base input archive class template class InputArchive { public: InputArchive(ArchiveType * const self) : self(self) { } //! Member serialization template typename std::enable_if() && traits::has_member_serialize(), ArchiveType &>::type operator & (T && t) { t.serialize(*self); return *self; } //! Non member serialization template typename std::enable_if() && traits::has_non_member_serialize(), ArchiveType &>::type operator & (T && t) { serialize(*self, t); return *self; } //! Member split (load) template typename std::enable_if() && traits::has_member_load(), ArchiveType &>::type operator & (T && t) { t.load(*self); return *self; } //! Non member split (load) template typename std::enable_if() && traits::has_non_member_load(), ArchiveType &>::type operator & (T && t) { load(*self, std::forward(t)); return *self; } //! No matching serialization template typename std::enable_if(), ArchiveType &>::type operator & (T & t) { static_assert(traits::is_input_serializable(), "Trying to serialize an unserializable type with an input archive.\n\n" "Types must either have a serialize function, or separate load/load functions (but not both).\n" "Serialize functions generally have the following signature:\n\n" "template\n" " void serialize(int & ar)\n" " {\n" " ar & member1 & member2 & member3;\n" " }\n\n" ); return *self; } private: ArchiveType * const self; }; // class InputArchive }