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:
Randolph Voorhies
2013-06-14 13:46:20 -07:00
12 changed files with 240 additions and 50 deletions

View File

@@ -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;

View File

@@ -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 )

View File

@@ -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;
}; };
// ###################################################################### // ######################################################################

View File

@@ -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 )

View File

@@ -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
View 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_

View 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_

View File

@@ -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
View 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;
}

View File

@@ -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;
} }

View File

@@ -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 {};

View File

@@ -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);