cereal/sandbox/sandbox_vs.cpp
Shane Grant 94d49c42ac is_in/out_serializable is now aware of specialization
count_in/out_serializers will now count the number of specializations if a type is
specialized, otherwise it will count the number of non-specialized serialization functions.

as a result of this, is_output/input_serializable now works as you would expect from the name
and will return true for correctly configured specialized types too.

this caused some logic changes to need to happen in cereal.hpp, mostly within the PROCESS_IF macro.

added some tests related to this change and #180

fixes #180
2015-04-04 18:19:22 -07:00

278 lines
7.1 KiB
C++

#include <base.hpp>
#include <derived.hpp>
#include <cereal/access.hpp>
#include <cereal/details/traits.hpp>
#include <cereal/details/helpers.hpp>
#include <cereal/types/base_class.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/array.hpp>
#include <cereal/types/bitset.hpp>
#include <cereal/types/chrono.hpp>
#include <cereal/types/common.hpp>
#include <cereal/types/complex.hpp>
#include <cereal/types/deque.hpp>
#include <cereal/types/forward_list.hpp>
#include <cereal/types/list.hpp>
#include <cereal/types/map.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/details/util.hpp>
#include <cereal/details/polymorphic_impl.hpp>
#include <cereal/types/polymorphic.hpp>
#include <cereal/types/queue.hpp>
#include <cereal/types/set.hpp>
#include <cereal/types/stack.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/tuple.hpp>
#include <cereal/types/unordered_map.hpp>
#include <cereal/types/unordered_set.hpp>
#include <cereal/types/utility.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/archives/binary.hpp>
#include <cereal/archives/portable_binary.hpp>
#include <cereal/archives/xml.hpp>
#include <cereal/archives/json.hpp>
#include <iostream>
#include <type_traits>
#include <functional>
//CEREAL_FORCE_LINK_SHARED_LIBRARY(Sandbox)
struct Archive {};
CEREAL_SETUP_ARCHIVE_TRAITS(Archive, Archive)
struct Test
{
template <class Archive>
void serialzize( Archive & )
{
std::cout << "hey there" << std::endl;
}
template <class Archive>
void save( Archive & ) const
{
std::cout << "saved by the bell" << std::endl;
}
template <class Archive>
void load( Archive & )
{
std::cout << "locked and loaded" << std::endl;
}
template <class Archive>
static void load_and_construct( Archive &, cereal::construct<Test> & )
{
}
template <class Archive>
int save_minimal() const
{
return 0;
}
template <class Archive>
int save_minimal(const std::uint32_t) const
{
return 1;
}
template <class Archive>
void load_minimal( int & )
{ }
};
template <class Archive>
void serialize( Archive &, Test & )
{ }
template <class Archive>
void load( Archive &, Test & )
{ }
template <class Archive>
void save( Archive &, Test const & )
{ }
template <class Archive>
int save_minimal( Test const & )
{ return 0; }
template <class Archive>
int save_minimal( Test const &, const std::uint32_t )
{ return 0; }
namespace cereal
{
template <>
struct LoadAndConstruct<Test>
{
template <class Archive>
static void load_and_construct( Archive &, cereal::construct<Test> & construct )
{
construct();
}
};
}
struct A
{
virtual void foo() = 0;
};
struct B : A
{
void foo() {}
template <class Archive>
void serialize( Archive & )
{
std::cout << "i'm in your b" << std::endl;
}
};
struct C
{
char a;
};
CEREAL_REGISTER_TYPE(B)
class MemberMinimal
{
public:
MemberMinimal() = default;
template <class Archive>
int save_minimal( Archive const & ) const
{
return x;
}
template <class Archive>
void load_minimal( Archive const &, int const & str )
{
x = str;
}
public:
int x;
};
int main()
{
typedef Test T;
std::cout << std::boolalpha;
// Test Load and Construct internal/external
std::cout << "\tload_and_construct" << std::endl;
std::cout << cereal::traits::has_member_load_and_construct<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_load_and_construct<T, Archive>::value << std::endl;
// serialize
std::cout << "\tserialize" << std::endl;
std::cout << cereal::traits::has_member_serialize<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_serialize<T, Archive>::value << std::endl;
// load
std::cout << "\tload" << std::endl;
std::cout << cereal::traits::has_member_load<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_load<T, Archive>::value << std::endl;
// load minimal
std::cout << "\tload minimal" << std::endl;
std::cout << cereal::traits::has_member_load<T, Archive>::value << std::endl;
// save
std::cout << "\tsave" << std::endl;
std::cout << cereal::traits::has_member_save<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_save<T, Archive>::value << std::endl;
// save_minimal
std::cout << "\tsave_minimal" << std::endl;
std::cout << cereal::traits::has_member_save_minimal<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_save_minimal<T, Archive>::value << std::endl;
// save_minimal_versioned
std::cout << "\tsave_minimal versioned" << std::endl;
std::cout << cereal::traits::has_member_versioned_save_minimal<T, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_versioned_save_minimal<T, Archive>::value << std::endl;
// splittable
std::cout << "\t splittable" << std::endl;
std::cout << cereal::traits::has_member_split<T, Archive, Archive>::value << std::endl;
std::cout << cereal::traits::has_non_member_split<T, Archive, Archive>::value << std::endl;
// serialiable
std::cout << "\toutput serializable" << std::endl;
std::cout << cereal::traits::is_output_serializable<T, Archive>::value << std::endl;
#if !defined(__INTEL_COMPILER)
//! TODO: This causes icc to crash
std::cout << cereal::traits::is_input_serializable<T, Archive>::value << std::endl;
#endif
// specialized
std::cout << "\tspecialized" << std::endl;
std::cout << cereal::traits::detail::is_specialized_member_serialize<T, Archive>::value << std::endl;
std::cout << cereal::traits::detail::is_specialized_member_load_save<T, Archive>::value << std::endl;
std::cout << cereal::traits::detail::is_specialized_non_member_serialize<T, Archive>::value << std::endl;
std::cout << cereal::traits::detail::is_specialized_non_member_load_save<T, Archive>::value << std::endl;
std::cout << cereal::traits::detail::count_specializations<T, Archive>::value << std::endl;
std::cout << cereal::traits::is_specialized<T, Archive>::value << std::endl;
// array size
std::cout << typeid(A).name() << std::endl;
std::cout << typeid(cereal::traits::has_load_and_construct<int, bool>).name() << std::endl;
// extra testing
std::cout << "\textra" << std::endl;
std::cout << cereal::traits::has_member_save_minimal<MemberMinimal, Archive>::value << std::endl;
std::cout << cereal::traits::has_member_load_minimal<MemberMinimal, Archive>::value << std::endl;
// DLL testing
std::cout << "------DLL TESTING------" << std::endl;
std::stringstream dllSS1;
std::stringstream dllSS2;
{
cereal::XMLOutputArchive out(dllSS1);
VersionTest x{1};
std::shared_ptr<Base> p = std::make_shared<Derived>();
out(x);
out( p );
std::shared_ptr<A> ay = std::make_shared<B>();
out(ay);
}
std::cout << dllSS1.str() << std::endl;
{
VersionTest x;
std::shared_ptr<Base> p;
std::shared_ptr<A> ay;
{
cereal::XMLInputArchive in(dllSS1);
in(x);
in( p );
in( ay );
}
{
cereal::XMLOutputArchive out(dllSS2);
out( x );
out( p );
out( ay );
}
}
std::cout << dllSS2.str() << std::endl;
return 0;
}