Added cereal::access for private members

This commit is contained in:
Randolph Voorhies
2013-06-17 17:57:36 -07:00
parent c4bb0de8b1
commit 5c3c162fd1
4 changed files with 155 additions and 97 deletions

View File

@@ -1,5 +1,5 @@
CPPFLAGS=-std=c++11 -I./include CPPFLAGS=-std=c++11 -I./include
CC=g++ CC=clang++
all: unittests sandbox performance all: unittests sandbox performance

View File

@@ -80,7 +80,7 @@ namespace cereal
ArchiveType &>::type ArchiveType &>::type
operator & (T const & t) operator & (T const & t)
{ {
const_cast<T &>(t).serialize(*self); access::member_serialize(*self, const_cast<T &>(t));
return *self; return *self;
} }

View File

@@ -32,6 +32,21 @@
namespace cereal namespace cereal
{ {
struct access
{
template<class Archive, class T>
static auto member_serialize(Archive & ar, T & t) -> decltype(t.serialize(ar))
{ t.serialize(ar); }
template<class Archive, class T>
static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar))
{ t.save(ar); }
template<class Archive, class T>
static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar))
{ t.load(ar); }
};
namespace traits namespace traits
{ {
template<typename> struct Void { typedef void type; }; template<typename> struct Void { typedef void type; };
@@ -44,7 +59,7 @@ namespace cereal
template<typename T, class A> template<typename T, class A>
struct has_member_serialize< T, A, struct has_member_serialize< T, A,
typename Void< typename Void<
decltype( std::declval<T&>().serialize( std::declval<A&>() ) ) decltype( access::member_serialize(std::declval<A&>(), std::declval<T&>() ) )
>::type >::type
>: std::true_type {}; >: std::true_type {};
@@ -63,7 +78,7 @@ namespace cereal
template<typename T, class A> template<typename T, class A>
struct has_member_load< T, A, struct has_member_load< T, A,
typename Void< typename Void<
decltype( std::declval<T&>().load( std::declval<A&>() ) ) decltype( access::member_load(std::declval<A&>(), std::declval<T&>() ) )
>::type >::type
>: std::true_type {}; >: std::true_type {};
@@ -82,7 +97,7 @@ namespace cereal
template<typename T, class A> template<typename T, class A>
struct has_member_save< T, A, struct has_member_save< T, A,
typename Void< typename Void<
decltype( std::declval<T const &>().save( std::declval<A&>() ) ) decltype( access::member_save(std::declval<A&>(), std::declval<T const &>() ) )
>::type >::type
>: std::true_type {}; >: std::true_type {};

View File

@@ -52,10 +52,14 @@ struct Test1
}; };
// ################################### // ###################################
struct Test2 class Test2
{ {
public:
int a; int a;
private:
friend class cereal::access;
template<class Archive> template<class Archive>
void save(Archive & ar) const void save(Archive & ar) const
{ {
@@ -102,6 +106,23 @@ namespace test4
} }
} }
class Private
{
public:
Private() : a('z') {}
private:
char a;
friend class cereal::access;
template<class Archive>
void serialize(Archive & ar)
{
ar & a;
}
};
struct Everything struct Everything
{ {
int x; int x;
@@ -146,99 +167,121 @@ struct EmptyStruct
}; };
}; };
struct NonEmptyStruct
{
int x, y, z;
};
// ###################################################################### // ######################################################################
int main() int main()
{ {
Everything e_out; //Everything e_out;
e_out.x = 99; //e_out.x = 99;
e_out.y = 100; //e_out.y = 100;
e_out.t1 = {1}; //e_out.t1 = {1};
e_out.t2 = {2}; //e_out.t2 = {2};
e_out.t3 = {3}; //e_out.t3 = {3};
e_out.t4 = {4}; //e_out.t4 = {4};
e_out.s = "Hello, World!"; //e_out.s = "Hello, World!";
{ //{
std::ofstream os("out.txt"); // std::ofstream os("out.txt");
cereal::BinaryOutputArchive archive(os); // cereal::BinaryOutputArchive archive(os);
archive & CEREAL_NVP(e_out); // archive & CEREAL_NVP(e_out);
} //}
Everything e_in; //Everything e_in;
{ //{
std::ifstream is("out.txt"); // std::ifstream is("out.txt");
cereal::BinaryInputArchive archive(is); // cereal::BinaryInputArchive archive(is);
archive & CEREAL_NVP(e_in); // archive & CEREAL_NVP(e_in);
} //}
assert(e_in == e_out); //assert(e_in == e_out);
{ //{
std::ofstream os("ptr.txt"); // std::ofstream os("ptr.txt");
cereal::BinaryOutputArchive archive(os); // cereal::BinaryOutputArchive archive(os);
std::shared_ptr<std::shared_ptr<int>> xptr1 = std::make_shared<std::shared_ptr<int>>(std::make_shared<int>(5)); // std::shared_ptr<std::shared_ptr<int>> xptr1 = std::make_shared<std::shared_ptr<int>>(std::make_shared<int>(5));
std::shared_ptr<int> xptr2 = *xptr1; // std::shared_ptr<int> xptr2 = *xptr1;
std::weak_ptr<int> wptr2 = xptr2; // std::weak_ptr<int> wptr2 = xptr2;
std::unique_ptr<Test1> uptr(new Test1); // std::unique_ptr<Test1> uptr(new Test1);
uptr->a = 99; // uptr->a = 99;
archive & xptr1; // archive & xptr1;
archive & xptr2; // archive & xptr2;
archive & wptr2; // archive & wptr2;
archive & uptr; // archive & uptr;
} //}
{ //{
std::ifstream is("ptr.txt"); // std::ifstream is("ptr.txt");
cereal::BinaryInputArchive archive(is); // cereal::BinaryInputArchive archive(is);
std::shared_ptr<std::shared_ptr<int>> xptr1; // std::shared_ptr<std::shared_ptr<int>> xptr1;
std::shared_ptr<int> xptr2; // std::shared_ptr<int> xptr2;
std::weak_ptr<int> wptr2; // std::weak_ptr<int> wptr2;
std::unique_ptr<Test1> uptr; // std::unique_ptr<Test1> uptr;
archive & xptr1; // archive & xptr1;
archive & xptr2; // archive & xptr2;
archive & wptr2; // archive & wptr2;
archive & uptr; // archive & uptr;
std::cout << **xptr1 << std::endl; // std::cout << **xptr1 << std::endl;
std::cout << *xptr2 << std::endl; // std::cout << *xptr2 << std::endl;
std::cout << (*xptr1).get() << " == " << xptr2.get() << " ? " << ((*xptr1).get() == xptr2.get()) << std::endl; // std::cout << (*xptr1).get() << " == " << xptr2.get() << " ? " << ((*xptr1).get() == xptr2.get()) << std::endl;
std::cout << *(wptr2.lock()) << std::endl; // std::cout << *(wptr2.lock()) << std::endl;
std::cout << (wptr2.lock().get() == xptr2.get()) << std::endl; // std::cout << (wptr2.lock().get() == xptr2.get()) << std::endl;
std::cout << uptr->a << std::endl; // std::cout << uptr->a << std::endl;
} //}
{ //{
std::ofstream os("arr.txt"); // std::ofstream os("arr.txt");
cereal::BinaryOutputArchive archive(os); // cereal::BinaryOutputArchive archive(os);
int a1[] = {1, 2, 3}; // int a1[] = {1, 2, 3};
int a2[][2] = {{4, 5}, {6, 7}}; // int a2[][2] = {{4, 5}, {6, 7}};
archive & a1; // archive & a1;
archive & a2; // archive & a2;
EmptyStruct empty; // EmptyStruct empty;
archive & empty; // archive & empty;
archive & std::complex<float>(); // archive & std::complex<float>();
} //}
{ //{
std::ifstream is("arr.txt"); // std::ifstream is("arr.txt");
cereal::BinaryInputArchive archive(is); // cereal::BinaryInputArchive archive(is);
int a1[3]; // int a1[3];
int a2[2][2]; // int a2[2][2];
archive & a1; // archive & a1;
archive & a2; // archive & a2;
for(auto i : a1) // for(auto i : a1)
std::cout << i << " "; // std::cout << i << " ";
std::cout << std::endl; // std::cout << std::endl;
for( auto const & i : a2 ) // for( auto const & i : a2 )
{ // {
for( auto j : i ) // for( auto j : i )
std::cout << j << " "; // std::cout << j << " ";
std::cout << std::endl; // std::cout << std::endl;
} // }
std::cout << std::endl; // std::cout << std::endl;
} //}
Private p;
NonEmptyStruct nes;
int q;
cereal::BinaryOutputArchive archive(std::cout);
archive & p;
//cereal::access::member_serialize(archive, p);
//cereal::access::member_serialize(archive, q);
//archive & p;
//archive & q;
//decltype(cereal::access::member_serialize(archive, q)) sss;
std::cout << cereal::traits::has_member_serialize<Private, cereal::BinaryOutputArchive>() << std::endl;
std::cout << cereal::traits::is_output_serializable<Private, cereal::BinaryOutputArchive>() << std::endl;
std::cout << cereal::traits::has_member_serialize<int, cereal::BinaryOutputArchive>() << std::endl;
return 0; return 0;
} }