#pragma once #include #include namespace cereal { namespace detail { template struct Void { typedef void type; }; template struct has_serialize: std::false_type {}; template struct has_serialize< T, A, typename Void< decltype( std::declval().serialize( std::declval(), 0 ) ) >::type >: std::true_type {}; template struct has_load: std::false_type {}; template struct has_load< T, A, typename Void< decltype( std::declval().load( std::declval(), 0 ) ) >::type >: std::true_type {}; template struct has_save: std::false_type {}; template struct has_save< T, A, typename Void< decltype( std::declval().save( std::declval(), 0 ) ) >::type >: std::true_type {}; template constexpr bool has_split() { return has_load() && has_save(); } template constexpr bool is_serializable() { return has_split() ^ has_serialize(); } } class BinaryOutputArchive { public: BinaryOutputArchive() {} BinaryOutputArchive(std::ostream & stream) { } template typename std::enable_if() && detail::has_serialize(), BinaryOutputArchive &>::type operator & (T const & t) { std::cout << "Saving non-split member" << std::endl; //t.serialize(*this, detail::version::value) return *this; } template typename std::enable_if() && detail::has_split(), BinaryOutputArchive &>::type operator & (T const & t) { std::cout << "Saving split member" << std::endl; //t.save(*this, detail::version::value); return *this; } template typename std::enable_if(), BinaryOutputArchive &>::type operator & (T const & t) { static_assert(detail::is_serializable(), "Trying to serialize an unserializable type.\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, unsigned int version)\n" " {\n" " ar & member1 & member2 & member3;\n" " }\n\n" ); return *this; } }; }