diff --git a/doc/traits.html b/doc/traits.html index 5db668e3..cb127e41 100644 --- a/doc/traits.html +++ b/doc/traits.html @@ -471,6 +471,32 @@ and template parameters should be assigned according to the following table: IsWrapperis the type a wrapper?mpl::false_
mpl::true_
mpl::false_ + +

Bitwise serialization

+Some simple classes could be serialized just by directly copying all bits +of the class. This is, in particular, the case for POD data types containing +no pointer members, and which are neither versioned nor tracked. Some archives, +such as non-portable binary archives can make us of this information to +substantially speed up Serialization. + +To indicate the possibility of bitwise serialization the type trait defined +in the header +file is_bitwise_serializable.hpp +is used: +

+namespace boost { namespace serialization {
+    template
+    struct is_bitwise_serializable
+     : public is_arithmetic
+    {};
+} }
+
+is used, and can be specialized for other classes. The specialization +is made easy by the corresponding macro: +

+BOOST_IS_BITWISE_SERIALIZABLE(my_class)
+
+

© Copyright Robert Ramey 2002-2004 and Matthias Troyer 2006. Distributed under the Boost Software License, Version 1.0. (See diff --git a/include/boost/archive/basic_binary_iprimitive.hpp b/include/boost/archive/basic_binary_iprimitive.hpp index 373cfa2a..dede7123 100644 --- a/include/boost/archive/basic_binary_iprimitive.hpp +++ b/include/boost/archive/basic_binary_iprimitive.hpp @@ -49,7 +49,7 @@ namespace std{ #include #include #include -#include +#include #include #include // must be the last header @@ -113,7 +113,12 @@ public: ~basic_binary_iprimitive(); public: // we provide an optimized load for all fundamental types - typedef is_fundamental use_array_optimization; + //typedef serialization::is_bitwise_serializable + // use_array_optimization; + struct use_array_optimization { + template + struct apply : public serialization::is_bitwise_serializable {}; + }; // the optimized load_array dispatches to load_binary template @@ -160,7 +165,7 @@ basic_binary_iprimitive::load_binary( static_cast(address), s ); - if(scount != static_cast(s)) + if(scount != static_cast(s)) boost::throw_exception( archive_exception(archive_exception::stream_error) ); diff --git a/include/boost/archive/basic_binary_oprimitive.hpp b/include/boost/archive/basic_binary_oprimitive.hpp index c961230b..43710e6f 100644 --- a/include/boost/archive/basic_binary_oprimitive.hpp +++ b/include/boost/archive/basic_binary_oprimitive.hpp @@ -46,7 +46,7 @@ namespace std{ #include #include #include -#include +#include #include #include #include // must be the last header @@ -113,8 +113,16 @@ public: BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) ~basic_binary_oprimitive(); public: + // we provide an optimized save for all fundamental types - typedef is_fundamental use_array_optimization; + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + // workaround without using mpl lambdas + struct use_array_optimization { + template + struct apply : public serialization::is_bitwise_serializable {}; + }; + // the optimized save_array dispatches to save_binary template diff --git a/include/boost/serialization/complex.hpp b/include/boost/serialization/complex.hpp new file mode 100644 index 00000000..bead218a --- /dev/null +++ b/include/boost/serialization/complex.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_SERIALIZATION_COMPLEX_HPP +#define BOOST_SERIALIZATION_COMPLEX_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/utility.hpp: +// serialization for stl utility templates + +// (C) Copyright 2007 Matthias Troyer . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include + +namespace boost { +namespace serialization { + +template +inline void serialize( + Archive & ar, + std::complex & x, + const unsigned int /* file_version */ +){ + ar & boost::serialization::make_nvp("real", x.real()); + ar & boost::serialization::make_nvp("imag", x.imag()); +} + +/// specialization of serialization traits for complex +template +struct is_bitwise_serializable > + : public is_bitwise_serializable {}; + +template +struct implementation_level > + : mpl::int_ {} ; + +// treat complex just like builtin arithmetic types for tracking +template +struct tracking_level > + : mpl::int_ {} ; + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_COMPLEX_HPP diff --git a/include/boost/serialization/is_bitwise_serializable.hpp b/include/boost/serialization/is_bitwise_serializable.hpp new file mode 100644 index 00000000..97d80b9a --- /dev/null +++ b/include/boost/serialization/is_bitwise_serializable.hpp @@ -0,0 +1,46 @@ +// (C) Copyright 2007 Matthias Troyer + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Matthias Troyer + +/** @file is_bitwise_serializable.hpp + * + * This header provides a traits class for determining whether a class + * can be serialized (in a non-portable way) just by copying the bits. + */ + + +#ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP +#define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace serialization { + template + struct is_bitwise_serializable + : public is_arithmetic + {}; +} // namespace serialization +} // namespace boost + + +// define a macro to make explicit designation of this more transparent +#define BOOST_IS_BITWISE_SERIALIZABLE(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_bitwise_serializable< T > : mpl::true_ {}; \ +}} \ +/**/ + +#endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP diff --git a/include/boost/serialization/utility.hpp b/include/boost/serialization/utility.hpp index ea53d04d..56773932 100644 --- a/include/boost/serialization/utility.hpp +++ b/include/boost/serialization/utility.hpp @@ -22,6 +22,7 @@ #include #include +#include namespace boost { namespace serialization { @@ -41,6 +42,17 @@ inline void serialize( ar & boost::serialization::make_nvp("second", p.second); } +/// specialization of is_bitwise_serializable for pairs +template +struct is_bitwise_serializable > + : public mpl::and_,is_bitwise_serializable > +{ +}; + +template +struct implementation_level > + : mpl::int_ {} ; + } // serialization } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 0e671355..f211e045 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -206,6 +206,7 @@ rule test-bsl-run_polymorphic_archive ( test-name : sources * ) { test-suite "serialization" : [ test-bsl-run_files test_array ] [ test-bsl-run_files test_binary ] + [ test-bsl-run_files test_complex ] [ test-bsl-run_files test_contained_class ] [ test-bsl-run_files test_cyclic_ptrs ] [ test-bsl-run_files test_delete_pointer ] diff --git a/test/test_complex.cpp b/test/test_complex.cpp new file mode 100644 index 00000000..a01867bd --- /dev/null +++ b/test/test_complex.cpp @@ -0,0 +1,57 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// test_complex.cpp + +// (C) Copyright 2005 Matthias Troyer . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// should pass compilation and execution + +#include + +#include // remove +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::remove; +} +#endif + +#include "test_tools.hpp" +#include +#include BOOST_PP_STRINGIZE(BOOST_ARCHIVE_TEST) + +#include + +int test_main( int /* argc */, char* /* argv */[] ) +{ + const char * testfile = boost::archive::tmpnam(NULL); + BOOST_REQUIRE(NULL != testfile); + + // test array of objects + std::complex a(std::rand(),std::rand()); + std::complex b(std::rand(),std::rand()); + { + test_ostream os(testfile, TEST_STREAM_FLAGS); + test_oarchive oa(os); + oa << boost::serialization::make_nvp("afloatcomplex", a); + oa << boost::serialization::make_nvp("adoublecomplex", b); + } + std::complex a1; + std::complex b1; + { + test_istream is(testfile, TEST_STREAM_FLAGS); + test_iarchive ia(is); + ia >> boost::serialization::make_nvp("afloatcomplex", a1); + ia >> boost::serialization::make_nvp("adoublecomplex", b1); + } + bool equal = (std::abs(a-a1) <= 2.*std::numeric_limits::round_error() + && std::abs(b-b1) <= 2.*std::numeric_limits::round_error() ); + + BOOST_CHECK(equal); + std::remove(testfile); + return EXIT_SUCCESS; +} + +// EOF