Adding chrono. Some docs/cleanup. NVP now works with R-values and l-values

This commit is contained in:
Shane Grant
2013-06-19 14:19:48 -07:00
parent a09841ad4d
commit d5afb78fcc
7 changed files with 151 additions and 25 deletions

View File

@@ -7,8 +7,8 @@ sandbox: sandbox.cpp
${CC} sandbox.cpp -o sandbox ${CPPFLAGS}
unittests: unittests.cpp
${CC} unittests.cpp -o unittests -lboost_unit_test_framework ${CPPFLAGS}
./unittests --show_progress
time ${CC} unittests.cpp -o unittests -lboost_unit_test_framework ${CPPFLAGS}
time ./unittests --show_progress
performance: performance.cpp
${CC} performance.cpp -o performance -lboost_serialization ${CPPFLAGS} -O3

View File

@@ -35,19 +35,19 @@ namespace cereal
{
namespace binary_detail
{
struct variant_save_visitor : boost::static_visitor<>
struct variant_save_visitor : boost::static_visitor<>
{
variant_save_visitor(BinaryOutputArchive & ar) : ar(ar) {}
template<class T>
void operator()(T const & value) const
{
ar & CEREAL_NVP(value);
ar( value );
}
BinaryOutputArchive & ar;
};
template<int N, class Variant, class ... Args>
typename std::enable_if<N == boost::mpl::size<typename Variant::types>::value, void>::type
load_variant(BinaryInputArchive & ar, int target, Variant & variant)
@@ -62,7 +62,7 @@ namespace cereal
if(N == target)
{
H value;
ar & CEREAL_NVP(value);
ar( value );
variant = value;
}
else
@@ -75,8 +75,8 @@ namespace cereal
template <typename... VariantTypes> inline
void save( BinaryOutputArchive & ar, boost::variant<VariantTypes...> const & variant )
{
int which = variant.which();
ar & CEREAL_NVP(which);
int32_t which = variant.which();
ar( which );
binary_detail::variant_save_visitor visitor(ar);
variant.apply_visitor(visitor);
}
@@ -87,9 +87,9 @@ namespace cereal
{
typedef typename boost::variant<VariantTypes...>::types types;
int which;
ar & cereal::make_nvp("which", which);
if(which >= boost::mpl::size<types>::value)
int32_t which;
ar( which );
if(which >= boost::mpl::size<types>::value)
throw Exception("Invalid 'which' selector when deserializing boost::variant");
binary_detail::load_variant<0, boost::variant<VariantTypes...>, VariantTypes...>(ar, which, variant);

View File

@@ -0,0 +1,71 @@
/*
Copyright (c) 2013, Randolph Voorhies, Shane Grant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of cereal nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CEREAL_BINARY_ARCHIVE_CHRONO_HPP_
#define CEREAL_BINARY_ARCHIVE_CHRONO_HPP_
#include <cereal/binary_archive/binary_archive.hpp>
#include <chrono>
namespace cereal
{
//! Saving duration
template <class R, class P> inline
void save( BinaryOutputArchive & ar, std::chrono::duration<R, P> const & dur )
{
ar( dur.count() );
}
//! Loading duration
template <class R, class P> inline
void load( BinaryInputArchive & ar, std::chrono::duration<R, P> & dur )
{
R count;
ar( count );
dur = std::chrono::duration<R, P>{count};
}
//! Saving duration
template <class C, class D> inline
void save( BinaryOutputArchive & ar, std::chrono::time_point<C, D> const & dur )
{
ar( dur.time_since_epoch() );
}
//! Loading duration
template <class C, class D> inline
void load( BinaryInputArchive & ar, std::chrono::time_point<C, D> & dur )
{
D elapsed;
ar( elapsed );
dur = std::chrono::time_point<C, D>{elapsed};
}
} // namespace cereal
#endif // CEREAL_BINARY_ARCHIVE_CHRONO_HPP_

View File

@@ -27,7 +27,6 @@
#ifndef CEREAL_BINARY_ARCHIVE_TUPLE_HPP_
#define CEREAL_BINARY_ARCHIVE_TUPLE_HPP_
#include <cereal/details/traits.hpp>
#include <cereal/binary_archive/binary_archive.hpp>
#include <tuple>

View File

@@ -40,34 +40,54 @@ namespace cereal
{
static const int32_t msb_32bit = 0x80000000;
// ######################################################################
//! An exception class thrown when things go wrong at runtime
struct Exception : public std::runtime_error
{
using std::runtime_error::runtime_error;
};
// ######################################################################
//! For holding name value pairs
/*! This pairs a name (some string) with some value such that an archive
can potentially take advantage of the pairing. */
template <class T>
struct NameValuePair
class NameValuePair
{
NameValuePair( std::string const & n, T & v ) : name(n), value(v) {}
private:
// If we get passed an RValue, we'll just make a local copy if it here
// otherwise, we store a reference
using DT = typename std::decay<T>::type;
using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
DT,
typename std::add_lvalue_reference<DT>::type>::type;
public:
//! Constructs a new NameValuePair
/*! @param n The name of the pair
@param v The value to pair. Ideally this should be an l-value reference so that
the value can be both loaded and saved to. If you pass an r-value reference,
the NameValuePair will store a copy of it instead of a reference. Thus you should
only pass r-values in cases where this makes sense, such as the result of some
size() call. In either case, any constness will be stripped away */
NameValuePair( std::string const & n, T && v ) : name(n), value(const_cast<Type>(v)) {}
std::string name;
T & value;
std::string name;
Type value;
};
//! Creates a name value pair
template <class T> inline
NameValuePair<T> make_nvp( std::string const & name, T & value )
NameValuePair<T> make_nvp( std::string const & name, T && value )
{
return {name, value};
return {name, std::forward<T>(value)};
}
//! Creates a name value pair for the variable T, using the same name
#define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
enum Flags { AllowEmptyClassElision = 1 };
// ######################################################################
//! Casts a derived class to its base class in a way that allows
//! cereal to track inheritance
template<class Base>
struct base_class
{
@@ -79,6 +99,10 @@ namespace cereal
Base * base_ptr;
};
// ######################################################################
//! Special flags for archives
enum Flags { AllowEmptyClassElision = 1 };
// ######################################################################
//! The base output archive class
template<class ArchiveType, uint32_t Flags = 0>

View File

@@ -85,7 +85,7 @@ struct cerealBinary
static void save( std::ostringstream & os, T const & data )
{
cereal::BinaryOutputArchive oar(os);
oar & data;
oar(data);
}
//! Loads data to a cereal binary archive
@@ -93,7 +93,7 @@ struct cerealBinary
static void load( std::istringstream & is, T & data )
{
cereal::BinaryInputArchive iar(is);
iar & data;
iar(data);
}
};
@@ -260,7 +260,7 @@ struct PoDStruct
template <class Archive>
void serialize( Archive & ar )
{
ar & a & b & c & d;
ar(a, b, c, d);
};
template <class Archive>
@@ -280,8 +280,7 @@ struct PoDChild : PoDStruct
template <class Archive>
void serialize( Archive & ar )
{
ar & static_cast<PoDStruct>(*this);
ar & v;
ar( cereal::base_class<PoDStruct>(this), v );
};
template <class Archive>

View File

@@ -42,6 +42,7 @@
#include <cereal/binary_archive/tuple.hpp>
#include <cereal/binary_archive/bitset.hpp>
#include <cereal/binary_archive/complex.hpp>
#include <cereal/binary_archive/chrono.hpp>
#include <limits>
#include <random>
@@ -1784,3 +1785,35 @@ BOOST_AUTO_TEST_CASE( binary_bitset )
BOOST_CHECK_EQUAL( o_bit256, i_bit256 );
}
}
// ######################################################################
BOOST_AUTO_TEST_CASE( binary_chrono )
{
for(int i=0; i<100; ++i)
{
std::ostringstream os;
cereal::BinaryOutputArchive oar(os);
auto o_timePoint1 = std::chrono::system_clock::now();
auto o_timePoint2 = std::chrono::steady_clock::now();
auto o_timePoint3 = std::chrono::high_resolution_clock::now();
oar(o_timePoint1);
oar(o_timePoint2);
oar(o_timePoint3);
std::istringstream is(os.str());
cereal::BinaryInputArchive iar(is);
decltype(o_timePoint1) i_timePoint1;
decltype(o_timePoint2) i_timePoint2;
decltype(o_timePoint3) i_timePoint3;
iar(i_timePoint1);
iar(i_timePoint2);
iar(i_timePoint3);
BOOST_CHECK_EQUAL( o_timePoint1 == i_timePoint1, true );
}
}