diff --git a/include/cereal/access.hpp b/include/cereal/access.hpp index ca21d4b0..7968faa8 100644 --- a/include/cereal/access.hpp +++ b/include/cereal/access.hpp @@ -112,6 +112,11 @@ namespace cereal static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar)) { t.save(ar); } + // Used during detection of non const member save + template inline + static auto non_const_member_save(Archive & ar, T & t) -> decltype(t.save(ar)) + { t.save(ar); } + template inline static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar)) { t.load(ar); } diff --git a/include/cereal/details/traits.hpp b/include/cereal/details/traits.hpp index dbe42ab9..0dc8853c 100644 --- a/include/cereal/details/traits.hpp +++ b/include/cereal/details/traits.hpp @@ -43,13 +43,13 @@ namespace cereal // Member load_and_allocate template bool constexpr has_member_load_and_allocate() - { return std::is_same( std::declval() ) ), T*>::value; }; + { return std::is_same( std::declval() ) ), T*>::value; } // ###################################################################### // Non Member load_and_allocate template bool constexpr has_non_member_load_and_allocate() - { return std::is_same::load_and_allocate( std::declval() ) ), T*>::value; }; + { return std::is_same::load_and_allocate( std::declval() ) ), T*>::value; } // ###################################################################### // Has either a member or non member allocate @@ -107,12 +107,51 @@ namespace cereal >::type >: std::true_type {}; + // ###################################################################### + // Non-const Member Save + namespace detail + { + // Detection of any (const or non const) member save + template + struct has_member_save_any: std::false_type {}; + + template + struct has_member_save_any< T, A, + typename Void< + decltype( access::non_const_member_save(std::declval(), std::declval::type &>() ) ) + >::type + >: std::true_type {}; + } + + // Returns true if we detect a member save function that is not const + template + constexpr bool is_non_const_member_save() + { + return !has_member_save() && detail::has_member_save_any(); + } + // ###################################################################### // Non Member Save char & save(...); template bool constexpr has_non_member_save() - { return std::is_void(), std::declval()))>::value; }; + { return std::is_void(), std::declval()))>::value; } + + // ###################################################################### + // Non-const Non member Save + namespace detail + { + template + bool constexpr has_non_member_save_any() + { return std::is_void(), std::declval::type &>()))>::value; } + } + + // Returns true if we detect a non-member save function that is not const + template + bool constexpr is_non_const_non_member_save() + { return !has_non_member_save() && detail::has_non_member_save_any(); } + + // ###################################################################### template diff --git a/include/cereal/types/queue.hpp b/include/cereal/types/queue.hpp index d1f200c7..8c42ce8b 100644 --- a/include/cereal/types/queue.hpp +++ b/include/cereal/types/queue.hpp @@ -84,7 +84,7 @@ namespace cereal template inline void save( Archive & ar, std::queue const & queue ) { - ar( queue_detail::container( queue ) ); + ar( _CEREAL_NVP("container", queue_detail::container( queue )) ); } //! Loading for std::queue @@ -100,8 +100,8 @@ namespace cereal template inline void save( Archive & ar, std::priority_queue const & priority_queue ) { - ar( queue_detail::comparator( priority_queue ) ); - ar( queue_detail::container( priority_queue ) ); + ar( _CEREAL_NVP("comparator", queue_detail::comparator( priority_queue )) ); + ar( _CEREAL_NVP("container", queue_detail::container( priority_queue )) ); } //! Loading for std::priority_queue diff --git a/include/cereal/types/stack.hpp b/include/cereal/types/stack.hpp index b2e49ec8..b6a3bc30 100644 --- a/include/cereal/types/stack.hpp +++ b/include/cereal/types/stack.hpp @@ -54,7 +54,7 @@ namespace cereal template inline void save( Archive & ar, std::stack const & stack ) { - ar( stack_detail::container( stack ) ); + ar( _CEREAL_NVP("container", stack_detail::container( stack )) ); } //! Loading for std::stack diff --git a/include/cereal/types/tuple.hpp b/include/cereal/types/tuple.hpp index 05cae946..fc6986d3 100644 --- a/include/cereal/types/tuple.hpp +++ b/include/cereal/types/tuple.hpp @@ -41,7 +41,7 @@ namespace cereal template inline static void apply( Archive & ar, std::tuple & tuple ) { - ar( std::get( tuple ) ); + ar( _CEREAL_NVP("tuple_element", std::get( tuple )) ); serialize::template apply( ar, tuple ); } }; @@ -51,7 +51,7 @@ namespace cereal struct serialize<0> { template inline - static void apply( Archive & ar, std::tuple & tuple ) + static void apply( Archive &, std::tuple & ) { } }; } diff --git a/include/cereal/types/utility.hpp b/include/cereal/types/utility.hpp index df20ef5f..6d9f62e1 100644 --- a/include/cereal/types/utility.hpp +++ b/include/cereal/types/utility.hpp @@ -36,8 +36,8 @@ namespace cereal template inline void serialize( Archive & ar, std::pair & pair ) { - ar( pair.first, - pair.second ); + ar( _CEREAL_NVP("first", pair.first), + _CEREAL_NVP("second", pair.second) ); } } // namespace cereal diff --git a/sandbox.cpp b/sandbox.cpp index 51f4ef68..0e260313 100644 --- a/sandbox.cpp +++ b/sandbox.cpp @@ -37,6 +37,9 @@ #include #include #include +#include +#include +#include #include #include @@ -56,6 +59,8 @@ class Base ar( x ); } + virtual void foo() = 0; + int x; }; @@ -78,15 +83,18 @@ class Derived : public Base ar( y ); } + void foo() {} + int y; }; namespace cereal { template struct specialize {}; - //template struct specialize {}; } +CEREAL_REGISTER_TYPE(Derived); + // ################################### struct Test1 { @@ -213,7 +221,7 @@ struct Everything struct EmptyStruct { template - void serialize(Archive & ar) + void serialize(Archive &) { std::cout << "Side effects!" << std::endl; }; @@ -233,7 +241,7 @@ struct NoDefaultCtor int y; template - void serialize( Archive & archive ) + void serialize( Archive & ) { } @@ -250,7 +258,7 @@ namespace cereal struct LoadAndAllocate { template - static NoDefaultCtor * load_and_allocate( Archive & ar ) + static NoDefaultCtor * load_and_allocate( Archive & ) { return new NoDefaultCtor(5); } diff --git a/sandbox_rtti.cpp b/sandbox_rtti.cpp index 1c7a6d80..681a3661 100644 --- a/sandbox_rtti.cpp +++ b/sandbox_rtti.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -123,10 +124,63 @@ struct OurType : public OurBase } }; -template void nop(T&&t) {} +struct BaseVirtual +{ + int x; + template + void serialize( Archive & ar ) + { ar( x ); } + virtual void foo() = 0; +}; + +struct DerivedVirtual : public virtual BaseVirtual +{ + int y; + virtual void foo() {} + + template + void save( Archive & ar ) const + { + ar( cereal::virtual_base_class( this ) ); + ar( y ); + } + + template + void load( Archive & ar ) + { + ar( cereal::virtual_base_class( this ) ); + ar( y ); + } +}; + +namespace cereal +{ + template struct specialize {}; +} + +//CEREAL_REGISTER_TYPE(DerivedVirtual); + +template void nop(T&&) {} int main() { + std::cout << std::boolalpha; + + std::cout << cereal::traits::is_specialized_member_load_save() << std::endl; + //std::cout << cereal::traits::is_specialized_non_member_serialize() << std::endl; + std::cout << cereal::traits::is_output_serializable() << std::endl; + //std::cout << cereal::traits::has_non_member_serialize() << std::endl; + //std::cout << cereal::traits::is_specialized_member_serialize() << std::endl; + std::cout << cereal::traits::has_member_serialize() << std::endl; + std::cout << "sssssssssssss" <() << std::endl; + std::cout << cereal::traits::is_non_const_member_save() << std::endl; + std::cout << cereal::traits::detail::has_member_save_any() << std::endl; + std::cout << cereal::traits::has_non_member_save() << std::endl; + std::cout << cereal::traits::has_member_serialize() << std::endl; + std::cout << cereal::traits::has_non_member_serialize() << std::endl; + + { std::ofstream ostream("rtti.txt"); cereal::BinaryOutputArchive oarchive(ostream);