mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
Merge branch 'master' of git.r-c-v.com:rand/cereal
Conflicts: binary_archive/array.hpp binary_archive/forward_list.hpp
This commit is contained in:
5
Makefile
5
Makefile
@@ -5,3 +5,8 @@ unittests: unittests.cpp
|
|||||||
g++ -std=c++0x unittests.cpp -o unittests -lboost_unit_test_framework -I./..
|
g++ -std=c++0x unittests.cpp -o unittests -lboost_unit_test_framework -I./..
|
||||||
./unittests --show_progress
|
./unittests --show_progress
|
||||||
|
|
||||||
|
boost_serialize: boost_serialize.cpp
|
||||||
|
g++ -std=c++11 boost_serialize.cpp -o boost_serialize -lboost_serialization -I./..
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test; rm unittests;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace cereal
|
|||||||
ar.load_binary( array.data(), N * sizeof(T) );
|
ar.load_binary( array.data(), N * sizeof(T) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving for const std::array all other types to binary
|
//! Saving for std::array all other types to binary
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
||||||
save( BinaryOutputArchive & ar, std::array<T, N> const & array )
|
save( BinaryOutputArchive & ar, std::array<T, N> const & array )
|
||||||
@@ -31,16 +31,7 @@ namespace cereal
|
|||||||
ar & i;
|
ar & i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving for non-const std::array all other types to binary
|
//! Loading for std::array all other types to binary
|
||||||
template <class T, size_t N>
|
|
||||||
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
|
||||||
save( BinaryOutputArchive & ar, std::array<T, N> & array )
|
|
||||||
{
|
|
||||||
for( auto & i : array )
|
|
||||||
ar & i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Loading for std::array all other types from binary
|
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
|
||||||
load( BinaryInputArchive & ar, std::array<T, N> & array )
|
load( BinaryInputArchive & ar, std::array<T, N> & array )
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define CEREAL_BINARY_ARCHIVE_BINARY_ARCHIVE_HPP_
|
#define CEREAL_BINARY_ARCHIVE_BINARY_ARCHIVE_HPP_
|
||||||
|
|
||||||
#include <cereal/cereal.hpp>
|
#include <cereal/cereal.hpp>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
namespace cereal
|
namespace cereal
|
||||||
{
|
{
|
||||||
@@ -23,8 +24,41 @@ namespace cereal
|
|||||||
throw 1; // TODO: something terrible
|
throw 1; // TODO: something terrible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Pushes a placeholder for data onto the archive and saves its position
|
||||||
|
void pushPosition( size_t size )
|
||||||
|
{
|
||||||
|
itsPositionStack.push( itsStream.tellp() );
|
||||||
|
for(size_t i = 0; i < size; ++i)
|
||||||
|
itsStream.rdbuf()->sputc('\0'); // char doesn't matter, but null-term is zero
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Pops the most recently pushed position onto the archive, going to the end
|
||||||
|
//! of the archive if the stack is empty
|
||||||
|
/*! @return true if the stack is empty and we are at the end of the archive */
|
||||||
|
bool popPosition()
|
||||||
|
{
|
||||||
|
if( itsPositionStack.empty() ) // seek to end of stream
|
||||||
|
{
|
||||||
|
itsStream.seekp( 0, std::ios_base::end );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itsStream.seekp( itsPositionStack.top() );
|
||||||
|
itsPositionStack.pop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Resets the position stack and seeks to the end of the archive
|
||||||
|
void resetPosition()
|
||||||
|
{
|
||||||
|
while( !popPosition() );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostream & itsStream;
|
std::ostream & itsStream;
|
||||||
|
std::stack<std::ostream::pos_type> itsPositionStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ######################################################################
|
// ######################################################################
|
||||||
|
|||||||
@@ -16,16 +16,6 @@ namespace cereal
|
|||||||
ar & i;
|
ar & i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading for std::deque all other types from binary (non-const version)
|
|
||||||
template <class T, class A>
|
|
||||||
void save( BinaryOutputArchive & ar, std::deque<T, A> & deque )
|
|
||||||
{
|
|
||||||
ar & deque.size();
|
|
||||||
|
|
||||||
for( auto & i : deque )
|
|
||||||
ar & i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Loading for std::deque all other types to binary
|
//! Loading for std::deque all other types to binary
|
||||||
template <class T, class A>
|
template <class T, class A>
|
||||||
void load( BinaryInputArchive & ar, std::deque<T, A> & deque )
|
void load( BinaryInputArchive & ar, std::deque<T, A> & deque )
|
||||||
|
|||||||
@@ -10,22 +10,42 @@ namespace cereal
|
|||||||
template <class T, class A>
|
template <class T, class A>
|
||||||
void save( BinaryOutputArchive & ar, std::forward_list<T, A> const & forward_list )
|
void save( BinaryOutputArchive & ar, std::forward_list<T, A> const & forward_list )
|
||||||
{
|
{
|
||||||
// TODO: This is linear time! We may want to do something smarter
|
// save position for size of list
|
||||||
ar & std::distance(forward_list.begin(), forward_list.end());
|
ar.pushPosition(sizeof(size_t));
|
||||||
|
|
||||||
for( auto const & i : forward_list )
|
// write the list
|
||||||
|
size_t size = 0;
|
||||||
|
for( const auto & i : forward_list )
|
||||||
|
{
|
||||||
ar & i;
|
ar & i;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the size
|
||||||
|
ar.popPosition();
|
||||||
|
ar & size;
|
||||||
|
ar.resetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving for std::forward_list all other types to binary (non-const version)
|
//! Saving for std::forward_list all other types to binary (non-const version)
|
||||||
template <class T, class A>
|
template <class T, class A>
|
||||||
void save( BinaryOutputArchive & ar, std::forward_list<T, A> & forward_list )
|
void save( BinaryOutputArchive & ar, std::forward_list<T, A> & forward_list )
|
||||||
{
|
{
|
||||||
// TODO: This is linear time! We may want to do something smarter
|
// save position for size of list
|
||||||
ar & std::distance(forward_list.begin(), forward_list.end());
|
ar.pushPosition(sizeof(size_t));
|
||||||
|
|
||||||
|
// write the list
|
||||||
|
size_t size = 0;
|
||||||
for( auto & i : forward_list )
|
for( auto & i : forward_list )
|
||||||
|
{
|
||||||
ar & i;
|
ar & i;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the size
|
||||||
|
ar.popPosition();
|
||||||
|
ar & size;
|
||||||
|
ar.resetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loading for std::forward_list all other types from binary
|
//! Loading for std::forward_list all other types from binary
|
||||||
|
|||||||
62
binary_archive/set.hpp
Normal file
62
binary_archive/set.hpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef CEREAL_BINARY_ARCHIVE_SET_HPP_
|
||||||
|
#define CEREAL_BINARY_ARCHIVE_SET_HPP_
|
||||||
|
|
||||||
|
#include <cereal/binary_archive/binary_archive.hpp>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace cereal
|
||||||
|
{
|
||||||
|
//! Saving for std::set all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void save( BinaryOutputArchive & ar, std::set<K, H, KE, A> const & set )
|
||||||
|
{
|
||||||
|
ar & set.size();
|
||||||
|
|
||||||
|
for( const auto & i : set )
|
||||||
|
ar & i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Loading for std::set all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void load( BinaryInputArchive & ar, std::set<K, H, KE, A> & set )
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
ar & size;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
K key;
|
||||||
|
|
||||||
|
ar & key;
|
||||||
|
set.insert( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Saving for std::multiset all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void save( BinaryOutputArchive & ar, std::multiset<K, H, KE, A> const & multiset )
|
||||||
|
{
|
||||||
|
ar & multiset.size();
|
||||||
|
|
||||||
|
for( const auto & i : multiset )
|
||||||
|
ar & i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Loading for std::multiset all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void load( BinaryInputArchive & ar, std::multiset<K, H, KE, A> & multiset )
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
ar & size;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
K key;
|
||||||
|
|
||||||
|
ar & key;
|
||||||
|
multiset.insert( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace cereal
|
||||||
|
|
||||||
|
#endif // CEREAL_BINARY_ARCHIVE_SET_HPP_
|
||||||
64
binary_archive/unordered_set.hpp
Normal file
64
binary_archive/unordered_set.hpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef CEREAL_BINARY_ARCHIVE_UNORDERED_SET_HPP_
|
||||||
|
#define CEREAL_BINARY_ARCHIVE_UNORDERED_SET_HPP_
|
||||||
|
|
||||||
|
#include <cereal/binary_archive/binary_archive.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace cereal
|
||||||
|
{
|
||||||
|
//! Saving for std::unordered_set all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void save( BinaryOutputArchive & ar, std::unordered_set<K, H, KE, A> const & unordered_set )
|
||||||
|
{
|
||||||
|
ar & unordered_set.size();
|
||||||
|
|
||||||
|
for( const auto & i : unordered_set )
|
||||||
|
ar & i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Loading for std::unordered_set all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void load( BinaryInputArchive & ar, std::unordered_set<K, H, KE, A> & unordered_set )
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
ar & size;
|
||||||
|
|
||||||
|
unordered_set.reserve( size );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
K key;
|
||||||
|
|
||||||
|
ar & key;
|
||||||
|
unordered_set.insert( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Saving for std::unordered_multiset all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void save( BinaryOutputArchive & ar, std::unordered_multiset<K, H, KE, A> const & unordered_multiset )
|
||||||
|
{
|
||||||
|
ar & multiset.size();
|
||||||
|
|
||||||
|
for( const auto & i : multiset )
|
||||||
|
ar & i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Loading for std::multiset all other types to binary
|
||||||
|
template <class K, class H, class KE, class A>
|
||||||
|
void load( BinaryInputArchive & ar, std::multiset<K, H, KE, A> & multiset )
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
ar & size;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < size; ++i )
|
||||||
|
{
|
||||||
|
K key;
|
||||||
|
|
||||||
|
ar & key;
|
||||||
|
multiset.insert( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace cereal
|
||||||
|
|
||||||
|
#endif // CEREAL_BINARY_ARCHIVE_UNORDERED_SET_HPP_
|
||||||
@@ -43,16 +43,6 @@ namespace cereal
|
|||||||
ar & (*it);
|
ar & (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Serialization for non-arithmetic (and bool) vector types to binary (non-const version)
|
|
||||||
template <class T, class A>
|
|
||||||
typename std::enable_if<!std::is_arithmetic<T>::value || std::is_same<T, bool>::value, void>::type
|
|
||||||
save( BinaryOutputArchive & ar, std::vector<T, A> & vector )
|
|
||||||
{
|
|
||||||
ar & vector.size(); // number of elements
|
|
||||||
for( auto it = vector.begin(), end = vector.end(); it != end; ++it )
|
|
||||||
ar & (*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Serialization for non-arithmetic (and bool) vector types from binary
|
//! Serialization for non-arithmetic (and bool) vector types from binary
|
||||||
template <class T, class A>
|
template <class T, class A>
|
||||||
typename std::enable_if<!std::is_arithmetic<T>::value || std::is_same<T, bool>::value, void>::type
|
typename std::enable_if<!std::is_arithmetic<T>::value || std::is_same<T, bool>::value, void>::type
|
||||||
|
|||||||
34
boost_serialize.cpp
Normal file
34
boost_serialize.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <boost/serialization/serialization.hpp>
|
||||||
|
#include <boost/archive/text_oarchive.hpp>
|
||||||
|
#include <boost/archive/text_iarchive.hpp>
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct myStruct
|
||||||
|
{
|
||||||
|
myStruct() : x(0) {}
|
||||||
|
int x;
|
||||||
|
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int version)
|
||||||
|
{
|
||||||
|
ar & x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::archive::text_oarchive oa(std::cout);
|
||||||
|
|
||||||
|
const myStruct v;
|
||||||
|
|
||||||
|
oa & v;
|
||||||
|
|
||||||
|
std::cout << BOOST_NO_FUNCTION_TEMPLATE_ORDERING << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
10
cereal.hpp
10
cereal.hpp
@@ -45,9 +45,9 @@ namespace cereal
|
|||||||
template <class T>
|
template <class T>
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>(),
|
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>(),
|
||||||
ArchiveType &>::type
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
t.serialize(*self);
|
const_cast<T &>(t).serialize(*self);
|
||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +55,9 @@ namespace cereal
|
|||||||
template <class T>
|
template <class T>
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>(),
|
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>(),
|
||||||
ArchiveType &>::type
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
serialize(*self, std::forward<T>(t));
|
serialize(*self, const_cast<T &>(t));
|
||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ namespace cereal
|
|||||||
ArchiveType &>::type
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T && t)
|
||||||
{
|
{
|
||||||
serialize(*self, t);
|
serialize(*self, std::forward<T>(t));
|
||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,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&>().save( std::declval<A&>() ) )
|
decltype( std::declval<T const &>().save( std::declval<A&>() ) )
|
||||||
>::type
|
>::type
|
||||||
>: std::true_type {};
|
>: std::true_type {};
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ std::ostream& operator<<(std::ostream& os, StructBase const & s)
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct StructInternalSerialize : StructBase
|
struct StructInternalSerialize : StructBase
|
||||||
{
|
{
|
||||||
StructInternalSerialize() : StructBase{0,0} {}
|
StructInternalSerialize() : StructBase{0,0} {}
|
||||||
StructInternalSerialize(int x_, int y_) : StructBase{x_,y_} {}
|
StructInternalSerialize(int x_, int y_) : StructBase{x_,y_} {}
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive & ar)
|
void serialize(Archive & ar)
|
||||||
{
|
{
|
||||||
@@ -43,9 +43,9 @@ struct StructInternalSerialize : StructBase
|
|||||||
struct StructInternalSplit : StructBase
|
struct StructInternalSplit : StructBase
|
||||||
{
|
{
|
||||||
StructInternalSplit() : StructBase{0,0} {}
|
StructInternalSplit() : StructBase{0,0} {}
|
||||||
StructInternalSplit(int x_, int y_) : StructBase{x_,y_} {}
|
StructInternalSplit(int x_, int y_) : StructBase{x_,y_} {}
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void save(Archive & ar)
|
void save(Archive & ar) const
|
||||||
{
|
{
|
||||||
ar & x & y;
|
ar & x & y;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ struct StructInternalSplit : StructBase
|
|||||||
struct StructExternalSerialize : StructBase
|
struct StructExternalSerialize : StructBase
|
||||||
{
|
{
|
||||||
StructExternalSerialize() : StructBase{0,0} {}
|
StructExternalSerialize() : StructBase{0,0} {}
|
||||||
StructExternalSerialize(int x_, int y_) : StructBase{x_,y_} {}
|
StructExternalSerialize(int x_, int y_) : StructBase{x_,y_} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
@@ -72,11 +72,11 @@ void serialize(Archive & ar, StructExternalSerialize & s)
|
|||||||
struct StructExternalSplit : StructBase
|
struct StructExternalSplit : StructBase
|
||||||
{
|
{
|
||||||
StructExternalSplit() : StructBase{0,0} {}
|
StructExternalSplit() : StructBase{0,0} {}
|
||||||
StructExternalSplit(int x_, int y_) : StructBase{x_,y_} {}
|
StructExternalSplit(int x_, int y_) : StructBase{x_,y_} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void save(Archive & ar, StructExternalSplit & s)
|
void save(Archive & ar, StructExternalSplit const & s)
|
||||||
{
|
{
|
||||||
ar & s.x & s.y;
|
ar & s.x & s.y;
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE( structs )
|
|||||||
StructExternalSplit i_espl;
|
StructExternalSplit i_espl;
|
||||||
|
|
||||||
iar & i_iser & i_ispl & i_eser & i_espl;
|
iar & i_iser & i_ispl & i_eser & i_espl;
|
||||||
|
|
||||||
BOOST_CHECK(i_iser == o_iser);
|
BOOST_CHECK(i_iser == o_iser);
|
||||||
BOOST_CHECK(i_ispl == o_ispl);
|
BOOST_CHECK(i_ispl == o_ispl);
|
||||||
BOOST_CHECK(i_eser == o_eser);
|
BOOST_CHECK(i_eser == o_eser);
|
||||||
|
|||||||
Reference in New Issue
Block a user