diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 8fd92e6480..bc4774b179 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -71,6 +71,8 @@ SOURCES = extended_type_info_no_rtti polymorphic_iarchive polymorphic_oarchive + portable_iarchive + portable_oarchive stl_port text_iarchive text_oarchive diff --git a/include/boost/archive/portable_archive.hpp b/include/boost/archive/portable_archive.hpp deleted file mode 100755 index ec8149cc3b..0000000000 --- a/include/boost/archive/portable_archive.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/*****************************************************************************/ -/** - * \file portable_archive.hpp - * \brief Needed for unit tests on portable archives. - * \author christian.pfligersdorffer@gmx.at - * - * Header for testing portable archives with all of the serialization tests. - * Before use copy all hpp files from this directory to your boost folder - * boost_.../libs/serialization/test and run from there a visual studio - * prompt with b2 oder bjam -sBOOST_ARCHIVE_LIST=portable_archive.hpp - * - * \note Since portable archives version 5.0 we depend on program_options! - * Edit libs/serialization/test/Jamfile.v2 and change the requirements to - * : requirements /boost/filesystem /boost/program_options - */ -/****************************************************************************/ - -#pragma warning( disable:4217 4127 4310 4244 4800 4267 ) - -// portable_archive test header -// include output archive header -#include "portable_oarchive.hpp" -// set name of test output archive -typedef eos::portable_oarchive test_oarchive; -// set name of test output stream -typedef std::ofstream test_ostream; - -// repeat the above for input archive -#include "portable_iarchive.hpp" -typedef eos::portable_iarchive test_iarchive; -typedef std::ifstream test_istream; - -// define open mode for streams -// binary archives should use std::ios_base::binary -#define TEST_STREAM_FLAGS std::ios_base::binary diff --git a/include/boost/archive/portable_archive_exception.hpp b/include/boost/archive/portable_archive_exception.hpp index 719fc00440..1e269c119f 100755 --- a/include/boost/archive/portable_archive_exception.hpp +++ b/include/boost/archive/portable_archive_exception.hpp @@ -18,76 +18,74 @@ #include #include -namespace eos { +// hint from Johan Rade: on VMS there is still support for +// the VAX floating point format and this macro detects it +#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT +#error "VAX floating point format is not supported!" +#endif - // this value is written to the top of the stream - const signed char magic_byte = 'e' | 'o' | 's'; +namespace boost { + namespace archive { - // flag for fp serialization - const unsigned no_infnan = 64; + // this value is written to the top of the stream + const signed char magic_byte = 127; - // integral type for the archive version - #if BOOST_VERSION < 104400 - typedef boost::archive::version_type archive_version_type; - #else - typedef boost::archive::library_version_type archive_version_type; - #endif + // flag for fp serialization + const unsigned no_infnan = 64; - // version of the linked boost archive library - const archive_version_type archive_version( - #if BOOST_VERSION < 103700 - boost::archive::ARCHIVE_VERSION() - #else - boost::archive::BOOST_ARCHIVE_VERSION() - #endif - ); + // integral type for the archive version + typedef library_version_type archive_version_type; - /** - * \brief Exception being thrown when serialization cannot proceed. - * - * There are several situations in which the portable archives may fail and - * hence throw an exception: - * -# deserialization of an integer value that exceeds the range of the type - * -# (de)serialization of inf/nan through an archive with no_infnan flag set - * -# deserialization of a denormalized value without the floating point type - * supporting denormalized numbers - * - * Note that this exception will also be thrown if you mixed up your stream - * position and accidentially interpret some value for size data (in this case - * the reported size will be totally amiss most of the time). - */ - class portable_archive_exception : public boost::archive::archive_exception - { - std::string msg; + // version of the linked boost archive library + const archive_version_type archive_version(BOOST_ARCHIVE_VERSION()); - public: - //! type size is not large enough for deserialized number - portable_archive_exception(signed char invalid_size) - : boost::archive::archive_exception(other_exception) - , msg("requested integer size exceeds type size: ") + /** + * \brief Exception being thrown when serialization cannot proceed. + * + * There are several situations in which the portable archives may fail and + * hence throw an exception: + * -# deserialization of an integer value that exceeds the range of the type + * -# (de)serialization of inf/nan through an archive with no_infnan flag set + * -# deserialization of a denormalized value without the floating point type + * supporting denormalized numbers + * + * Note that this exception will also be thrown if you mixed up your stream + * position and accidentially interpret some value for size data (in this case + * the reported size will be totally amiss most of the time). + */ + class portable_archive_exception : public archive_exception { - msg += boost::lexical_cast(invalid_size); - } + std::string msg; - //! negative number in unsigned type - portable_archive_exception() - : boost::archive::archive_exception(other_exception) - , msg("cannot read a negative number into an unsigned type") - { - } + public: + //! type size is not large enough for deserialized number + portable_archive_exception(signed char invalid_size) + : archive_exception(other_exception) + , msg("requested integer size exceeds type size: ") + { + msg += lexical_cast(invalid_size); + } - //! serialization of inf, nan and denormals - template - portable_archive_exception(const T& abnormal) - : boost::archive::archive_exception(other_exception) - , msg("serialization of illegal floating point value: ") - { - msg += boost::lexical_cast(abnormal); - } + //! negative number in unsigned type + portable_archive_exception() + : archive_exception(other_exception) + , msg("cannot read a negative number into an unsigned type") + { + } + + //! serialization of inf, nan and denormals + template + portable_archive_exception(const T& abnormal) + : archive_exception(other_exception) + , msg("serialization of illegal floating point value: ") + { + msg += lexical_cast(abnormal); + } - //! override the base class function with our message - const char* what() const throw() { return msg.c_str(); } - ~portable_archive_exception() throw() {} - }; + //! override the base class function with our message + const char* what() const throw() { return msg.c_str(); } + ~portable_archive_exception() throw() {} + }; -} // namespace eos + } // namespace archive +} // namespace boost diff --git a/include/boost/archive/portable_iarchive.hpp b/include/boost/archive/portable_iarchive.hpp index 67763f222c..2fc289fe0d 100755 --- a/include/boost/archive/portable_iarchive.hpp +++ b/include/boost/archive/portable_iarchive.hpp @@ -3,7 +3,7 @@ * \file portable_iarchive.hpp * \brief Provides an archive to read from portable binary files. * \author christian.pfligersdorffer@gmx.at - * \version 5.1 + * \version 6.0 * * This pair of archives brings the advantages of binary streams to the cross * platform boost::serialization user. While being almost as fast as the native @@ -23,6 +23,10 @@ * chance it will instantly work for your specific setup. If you encounter * problems or have suggestions please contact the author. * + * \note Version 6.0 is prepared for submission to boost serialization library. + * Full backwards compatibility is maintained for all your archived data! + * Namespaces changed and some refactoring was necessary, that's all. + * * \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to * ecotax for pointing to the issue with shared_ptr_helper. * @@ -92,51 +96,17 @@ #include #include -#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 -#include -#endif - // funny polymorphics -#if BOOST_VERSION < 103500 -#include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_iarchive_impl - -#elif BOOST_VERSION < 103600 -#include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_iarchive_dispatch - -#else #include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_iarchive_route -#endif // endian and fpclassify -#if BOOST_VERSION < 103600 -#include -#include -#elif BOOST_VERSION < 104800 -#include +#include #include -#else -#include -#include -#endif -// namespace alias -#if BOOST_VERSION < 103800 -namespace fp = boost::math; -#else +// namespace alias for fp utilities namespace fp = boost::spirit::math; -#endif -// namespace alias endian -#if BOOST_VERSION < 104800 -namespace endian = boost::detail; -#else -namespace endian = boost::spirit::detail; -#endif - -#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING +#ifndef BOOST_NO_STD_WSTRING // used for wstring to utf8 conversion #include #include @@ -150,25 +120,15 @@ namespace endian = boost::spirit::detail; #include "portable_archive_exception.hpp" -// hint from Johan Rade: on VMS there is still support for -// the VAX floating point format and this macro detects it -#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT -#error "VAX floating point format is not supported!" -#endif - -namespace eos { +namespace boost { namespace archive { // forward declaration class portable_iarchive; - typedef boost::archive::basic_binary_iprimitive< + typedef basic_binary_iprimitive < portable_iarchive - #if BOOST_VERSION < 103400 - , std::istream - #else - , std::istream::char_type + , std::istream::char_type , std::istream::traits_type - #endif > portable_iprimitive; /** @@ -187,34 +147,28 @@ namespace eos { */ class portable_iarchive : public portable_iprimitive - // the example derives from common_oarchive but that lacks the + // Robert's example derives from common_oarchive but that lacks the // load_override functions so we chose to stay one level higher - , public boost::archive::basic_binary_iarchive - - #if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 - // mix-in helper class for serializing shared_ptr - , public boost::archive::detail::shared_ptr_helper - #endif + , public basic_binary_iarchive { // only needed for Robert's hack in basic_binary_iarchive::init - friend class boost::archive::basic_binary_iarchive; + friend class basic_binary_iarchive; // workaround for gcc: use a dummy struct // as additional argument type for overloading - template struct dummy { dummy(int) {}}; + template struct dummy { dummy(int) {} }; // loads directly from stream inline signed char load_signed_char() - { - signed char c; - portable_iprimitive::load(c); - return c; + { + signed char c; + portable_iprimitive::load(c); + return c; } // archive initialization void init(unsigned flags) { - using namespace boost::archive; archive_version_type input_library_version(3); // it is vital to have version information! @@ -222,7 +176,7 @@ namespace eos { if (flags & no_header) set_library_version(input_library_version); - // extract and check the magic eos byte + // extract and check the magic byte header else if (load_signed_char() != magic_byte) throw archive_exception(archive_exception::invalid_signature); @@ -253,32 +207,26 @@ namespace eos { * library version. Due to efficiency we stick with our own. */ portable_iarchive(std::istream& is, unsigned flags = 0) - #if BOOST_VERSION < 103400 - : portable_iprimitive(is, flags & boost::archive::no_codecvt) - #else - : portable_iprimitive(*is.rdbuf(), flags & boost::archive::no_codecvt) - #endif - , boost::archive::basic_binary_iarchive(flags) + : portable_iprimitive(*is.rdbuf(), flags & no_codecvt) + , basic_binary_iarchive(flags) { init(flags); } - #if BOOST_VERSION >= 103400 portable_iarchive(std::streambuf& sb, unsigned flags = 0) - : portable_iprimitive(sb, flags & boost::archive::no_codecvt) - , boost::archive::basic_binary_iarchive(flags) + : portable_iprimitive(sb, flags & no_codecvt) + , basic_binary_iarchive(flags) { init(flags); } - #endif //! Load narrow strings. - void load(std::string& s) + void load(std::string& s) { portable_iprimitive::load(s); } - #ifndef BOOST_NO_STD_WSTRING +#ifndef BOOST_NO_STD_WSTRING /** * \brief Load wide strings. * @@ -297,23 +245,23 @@ namespace eos { load(utf8); s = boost::from_utf8(utf8); } - #endif +#endif - /** - * \brief Loading bool type. - * - * Byte pattern is same as with integer types, so this function - * is somewhat redundant but treating bool as integer generates + /** + * \brief Loading bool type. + * + * Byte pattern is same as with integer types, so this function + * is somewhat redundant but treating bool as integer generates * a lot of compiler warnings. - * - * \note If you cannot compile your application and it says something - * about load(bool) cannot convert your type A& into bool& then you - * should check your BOOST_CLASS_IMPLEMENTATION setting for A, as - * portable_archive is not able to handle custom primitive types in - * a general manner. - */ - void load(bool& b) - { + * + * \note If you cannot compile your application and it says something + * about load(bool) cannot convert your type A& into bool& then you + * should check your BOOST_CLASS_IMPLEMENTATION setting for A, as + * portable_archive is not able to handle custom primitive types in + * a general manner. + */ + void load(bool& b) + { switch (signed char c = load_signed_char()) { case 0: b = false; break; @@ -325,13 +273,13 @@ namespace eos { /** * \brief Load integer types. * - * First we load the size information ie. the number of bytes that + * First we load the size information ie. the number of bytes that * hold the actual data. Then we retrieve the data and transform it * to the original value by using load_little_endian. */ template typename boost::enable_if >::type - load(T & t, dummy<2> = 0) + load(T & t, dummy<2> = 0) { // get the number of bytes in the stream if (signed char size = load_signed_char()) @@ -341,51 +289,50 @@ namespace eos { throw portable_archive_exception(); // check that our type T is large enough - else if ((unsigned) abs(size) > sizeof(T)) + else if ((unsigned)abs(size) > sizeof(T)) throw portable_archive_exception(size); // reconstruct the value T temp = size < 0 ? -1 : 0; load_binary(&temp, abs(size)); - // load the value from little endian - it is then converted // to the target type T and fits it because size <= sizeof(T) - t = endian::load_little_endian(&temp); + t = boost::endian::little_to_native(temp); } else t = 0; // zero optimization } - /** + /** * \brief Load floating point types. - * + * * We simply rely on fp_traits to set the bit pattern from the (unsigned) * integral type that was stored in the stream. Francois Mauger provided * standardized behaviour for special values like inf and NaN, that need to * be serialized in his application. * * \note by Johan Rade (author of the floating point utilities library): - * Be warned that the math::detail::fp_traits::type::get_bits() function + * Be warned that the math::detail::fp_traits::type::get_bits() function * is *not* guaranteed to give you all bits of the floating point number. It * will give you all bits if and only if there is an integer type that has * the same size as the floating point you are copying from. It will not * give you all bits for double if there is no uint64_t. It will not give * you all bits for long double if sizeof(long double) > 8 or there is no - * uint64_t. - * + * uint64_t. + * * The member fp_traits::type::coverage will tell you whether all bits * are copied. This is a typedef for either math::detail::all_bits or - * math::detail::not_all_bits. - * + * math::detail::not_all_bits. + * * If the function does not copy all bits, then it will copy the most * significant bits. So if you serialize and deserialize the way you * describe, and fp_traits::type::coverage is math::detail::not_all_bits, * then your floating point numbers will be truncated. This will introduce - * small rounding off errors. + * small rounding off errors. */ template typename boost::enable_if >::type - load(T & t, dummy<3> = 0) + load(T & t, dummy<3> = 0) { typedef typename fp::detail::fp_traits::type traits; @@ -410,7 +357,7 @@ namespace eos { // denormalized numbers. this might be the case even though // your type conforms to IEC 559 (and thus to IEEE 754) if (std::numeric_limits::has_denorm == std::denorm_absent - && fp::fpclassify(t) == (int) FP_SUBNORMAL) // GCC4 + && fp::fpclassify(t) == (int)FP_SUBNORMAL) // GCC4 throw portable_archive_exception(t); } @@ -418,11 +365,11 @@ namespace eos { // item_version_type, plus a whole bunch of additional strong typedefs. template typename boost::disable_if >::type - load(T& t, dummy<4> = 0) + load(T& t, dummy<4> = 0) { // we provide a generic load routine for all types that feature // conversion operators into an unsigned integer value like those - // created through BOOST_STRONG_TYPEDEF(X, some unsigned int) like + // created through BOOST_STRONG_TYPEDEF(X, some unsigned int) ie. // library_version_type, collection_size_type, item_version_type, // class_id_type, object_id_type, version_type and tracking_type load((typename boost::uint_t::least&)(t)); @@ -430,58 +377,11 @@ namespace eos { }; // polymorphic portable binary iarchive typedef - typedef POLYMORPHIC(portable_iarchive) polymorphic_portable_iarchive; - #undef POLYMORPHIC + typedef detail::polymorphic_iarchive_route polymorphic_portable_iarchive; -} // namespace eos +} } // namespace boost::archive // this is required by export which registers all of your // classes with all the inbuilt archives plus our archive. -#if BOOST_VERSION < 103500 -#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES eos::portable_iarchive -#else -BOOST_SERIALIZATION_REGISTER_ARCHIVE(eos::portable_iarchive) -BOOST_SERIALIZATION_REGISTER_ARCHIVE(eos::polymorphic_portable_iarchive) -#endif - -// if you include this header multiple times and your compiler is picky -// about multiple template instantiations (eg. gcc is) then you need to -// define NO_EXPLICIT_TEMPLATE_INSTANTIATION before every include but one -// or you move the instantiation section into an implementation file -#ifndef NO_EXPLICIT_TEMPLATE_INSTANTIATION - -#include -#include - -#if BOOST_VERSION < 104000 -#include -#elif !defined BOOST_ARCHIVE_SERIALIZER_INCLUDED -#include -#define BOOST_ARCHIVE_SERIALIZER_INCLUDED -#endif - -namespace boost { namespace archive { - - // explicitly instantiate for this type of binary stream - template class basic_binary_iarchive; - - template class basic_binary_iprimitive< - eos::portable_iarchive - #if BOOST_VERSION < 103400 - , std::istream - #else - , std::istream::char_type - , std::istream::traits_type - #endif - >; - -#if BOOST_VERSION < 104000 - template class detail::archive_pointer_iserializer; -#else - template class detail::archive_serializer_map; - //template class detail::archive_serializer_map; -#endif - -} } // namespace boost::archive - -#endif +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::portable_iarchive) +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_portable_iarchive) diff --git a/include/boost/archive/portable_oarchive.hpp b/include/boost/archive/portable_oarchive.hpp index 100176e9e5..f28b267b12 100755 --- a/include/boost/archive/portable_oarchive.hpp +++ b/include/boost/archive/portable_oarchive.hpp @@ -3,7 +3,7 @@ * \file portable_oarchive.hpp * \brief Provides an archive to create portable binary files. * \author christian.pfligersdorffer@gmx.at - * \version 5.1 + * \version 6.0 * * This pair of archives brings the advantages of binary streams to the cross * platform boost::serialization user. While being almost as fast as the native @@ -23,6 +23,10 @@ * chance it will instantly work for your specific setup. If you encounter * problems or have suggestions please contact the author. * + * \note Version 6.0 is prepared for submission to boost serialization library. + * Full backwards compatibility is maintained for all your archived data! + * Namespaces changed and some refactoring was necessary, that's all. + * * \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to * ecotax for pointing to the issue with shared_ptr_helper. * @@ -94,52 +98,16 @@ #include #include #include - -#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 -#include -#endif - -// funny polymorphics -#if BOOST_VERSION < 103500 -#include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_oarchive_impl - -#elif BOOST_VERSION < 103600 -#include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_oarchive_dispatch - -#else #include -#define POLYMORPHIC(T) boost::archive::detail::polymorphic_oarchive_route -#endif // endian and fpclassify -#if BOOST_VERSION < 103600 -#include -#include -#elif BOOST_VERSION < 104800 -#include -#include -#else -#include +#include #include -#endif -// namespace alias fp_classify -#if BOOST_VERSION < 103800 -namespace fp = boost::math; -#else +// namespace alias for fp utilities namespace fp = boost::spirit::math; -#endif - -// namespace alias endian -#if BOOST_VERSION < 104800 -namespace endian = boost::detail; -#else -namespace endian = boost::spirit::detail; -#endif -#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING +#ifndef BOOST_NO_STD_WSTRING // used for wstring to utf8 conversion #include #include @@ -153,25 +121,15 @@ namespace endian = boost::spirit::detail; #include "portable_archive_exception.hpp" -// hint from Johan Rade: on VMS there is still support for -// the VAX floating point format and this macro detects it -#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT -#error "VAX floating point format is not supported!" -#endif - -namespace eos { +namespace boost { namespace archive { // forward declaration class portable_oarchive; - typedef boost::archive::basic_binary_oprimitive< + typedef basic_binary_oprimitive < portable_oarchive - #if BOOST_VERSION < 103400 - , std::ostream - #else - , std::ostream::char_type + , std::ostream::char_type , std::ostream::traits_type - #endif > portable_oprimitive; /** @@ -188,23 +146,18 @@ namespace eos { */ class portable_oarchive : public portable_oprimitive - // the example derives from common_oarchive but that lacks the + // Robert's example derives from common_oarchive but that lacks the // save_override functions so we chose to stay one level higher - , public boost::archive::basic_binary_oarchive - - #if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600 - // mix-in helper class for serializing shared_ptr - , public boost::archive::detail::shared_ptr_helper - #endif + , public basic_binary_oarchive { // workaround for gcc: use a dummy struct // as additional argument type for overloading - template struct dummy { dummy(int) {}}; + template struct dummy { dummy(int) {} }; // stores a signed char directly to stream - inline void save_signed_char(const signed char& c) - { - portable_oprimitive::save(c); + inline void save_signed_char(const signed char& c) + { + portable_oprimitive::save(c); } // archive initialization @@ -213,7 +166,8 @@ namespace eos { // it is vital to have version information if the archive is // to be parsed with a newer version of boost::serialization // therefor we create a header, no header means boost 1.33 - if (flags & boost::archive::no_header) + // for backwards compatibility + if (flags & no_header) BOOST_ASSERT(archive_version == 3); else { @@ -241,24 +195,18 @@ namespace eos { * library version. Due to efficiency we stick with our own. */ portable_oarchive(std::ostream& os, unsigned flags = 0) - #if BOOST_VERSION < 103400 - : portable_oprimitive(os, flags & boost::archive::no_codecvt) - #else - : portable_oprimitive(*os.rdbuf(), flags & boost::archive::no_codecvt) - #endif - , boost::archive::basic_binary_oarchive(flags) + : portable_oprimitive(*os.rdbuf(), flags & no_codecvt) + , basic_binary_oarchive(flags) { init(flags); } - #if BOOST_VERSION >= 103400 portable_oarchive(std::streambuf& sb, unsigned flags = 0) - : portable_oprimitive(sb, flags & boost::archive::no_codecvt) - , boost::archive::basic_binary_oarchive(flags) + : portable_oprimitive(sb, flags & no_codecvt) + , basic_binary_oarchive(flags) { init(flags); } - #endif //! Save narrow strings. void save(const std::string& s) @@ -266,7 +214,7 @@ namespace eos { portable_oprimitive::save(s); } - #ifndef BOOST_NO_STD_WSTRING +#ifndef BOOST_NO_STD_WSTRING /** * \brief Save wide strings. * @@ -283,20 +231,20 @@ namespace eos { { save(boost::to_utf8(s)); } - #endif - - /** - * \brief Saving bool type. - * - * Saving bool directly, not by const reference - * because of tracking_type's operator (bool). - * - * \note If you cannot compile your application and it says something - * about save(bool) cannot convert your type const A& into bool then - * you should check your BOOST_CLASS_IMPLEMENTATION setting for A, as - * portable_archive is not able to handle custom primitive types in - * a general manner. - */ +#endif + + /** + * \brief Saving bool type. + * + * Saving bool directly, not by const reference + * because of tracking_type's operator (bool). + * + * \note If you cannot compile your application and it says something + * about save(bool) cannot convert your type const A& into bool then + * you should check your BOOST_CLASS_IMPLEMENTATION setting for A, as + * portable_archive is not able to handle custom primitive types in + * a general manner. + */ void save(const bool& b) { save_signed_char(b); @@ -312,15 +260,14 @@ namespace eos { */ template typename boost::enable_if >::type - save(const T & t, dummy<2> = 0) + save(const T & t, dummy<2> = 0) { if (T temp = t) { // examine the number of bytes // needed to represent the number signed char size = 0; - do { temp >>= CHAR_BIT; ++size; } - while (temp != 0 && temp != (T) -1); + do { temp >>= CHAR_BIT; ++size; } while (temp != 0 && temp != (T)-1); // encode the sign bit into the size save_signed_char(t > 0 ? size : -size); @@ -328,7 +275,7 @@ namespace eos { // we choose to use little endian because this way we just // save the first size bytes to the stream and skip the rest - endian::store_little_endian(&temp, t); + temp = boost::endian::native_to_little(t); save_binary(&temp, size); } @@ -338,34 +285,34 @@ namespace eos { /** * \brief Save floating point types. - * + * * We simply rely on fp_traits to extract the bit pattern into an (unsigned) * integral type and store that into the stream. Francois Mauger provided * standardized behaviour for special values like inf and NaN, that need to * be serialized in his application. * * \note by Johan Rade (author of the floating point utilities library): - * Be warned that the math::detail::fp_traits::type::get_bits() function + * Be warned that the math::detail::fp_traits::type::get_bits() function * is *not* guaranteed to give you all bits of the floating point number. It * will give you all bits if and only if there is an integer type that has * the same size as the floating point you are copying from. It will not * give you all bits for double if there is no uint64_t. It will not give * you all bits for long double if sizeof(long double) > 8 or there is no - * uint64_t. - * + * uint64_t. + * * The member fp_traits::type::coverage will tell you whether all bits * are copied. This is a typedef for either math::detail::all_bits or - * math::detail::not_all_bits. - * + * math::detail::not_all_bits. + * * If the function does not copy all bits, then it will copy the most * significant bits. So if you serialize and deserialize the way you * describe, and fp_traits::type::coverage is math::detail::not_all_bits, * then your floating point numbers will be truncated. This will introduce - * small rounding off errors. + * small rounding off errors. */ template typename boost::enable_if >::type - save(const T & t, dummy<3> = 0) + save(const T & t, dummy<3> = 0) { typedef typename fp::detail::fp_traits::type traits; @@ -386,9 +333,9 @@ namespace eos { // examine value closely switch (fp::fpclassify(t)) { - //case FP_ZERO: bits = 0; break; + //case FP_ZERO: bits = 0; break; case FP_NAN: bits = traits::exponent | traits::mantissa; break; - case FP_INFINITE: bits = traits::exponent | (t<0) * traits::sign; break; + case FP_INFINITE: bits = traits::exponent | (t < 0) * traits::sign; break; case FP_SUBNORMAL: assert(std::numeric_limits::has_denorm); // pass case FP_ZERO: // note that floats can be ±0.0 case FP_NORMAL: traits::get_bits(t, bits); break; @@ -402,7 +349,7 @@ namespace eos { // item_version_type, plus a whole bunch of additional strong typedefs. template typename boost::disable_if >::type - save(const T& t, dummy<4> = 0) + save(const T& t, dummy<4> = 0) { // we provide a generic save routine for all types that feature // conversion operators into an unsigned integer value like those @@ -414,57 +361,10 @@ namespace eos { }; // polymorphic portable binary oarchive typedef - typedef POLYMORPHIC(portable_oarchive) polymorphic_portable_oarchive; - #undef POLYMORPHIC - -} // namespace eos - -// required by export -#if BOOST_VERSION < 103500 -#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES eos::portable_oarchive -#else -BOOST_SERIALIZATION_REGISTER_ARCHIVE(eos::portable_oarchive) -BOOST_SERIALIZATION_REGISTER_ARCHIVE(eos::polymorphic_portable_oarchive) -#endif - -// if you include this header multiple times and your compiler is picky -// about multiple template instantiations (eg. gcc is) then you need to -// define NO_EXPLICIT_TEMPLATE_INSTANTIATION before every include but one -// or you move the instantiation section into an implementation file -#ifndef NO_EXPLICIT_TEMPLATE_INSTANTIATION - -#include -#include - -#if BOOST_VERSION < 104000 -#include -#elif !defined BOOST_ARCHIVE_SERIALIZER_INCLUDED -#include -#define BOOST_ARCHIVE_SERIALIZER_INCLUDED -#endif - -namespace boost { namespace archive { - - // explicitly instantiate for this type of binary stream - template class basic_binary_oarchive; - - template class basic_binary_oprimitive< - eos::portable_oarchive - #if BOOST_VERSION < 103400 - , std::ostream - #else - , std::ostream::char_type - , std::ostream::traits_type - #endif - >; - -#if BOOST_VERSION < 104000 - template class detail::archive_pointer_oserializer; -#else - template class detail::archive_serializer_map; - //template class detail::archive_serializer_map; -#endif + typedef detail::polymorphic_oarchive_route polymorphic_portable_oarchive; } } // namespace boost::archive -#endif +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::portable_oarchive) +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_portable_oarchive) diff --git a/src/portable_iarchive.cpp b/src/portable_iarchive.cpp new file mode 100644 index 0000000000..0e3f48c5e0 --- /dev/null +++ b/src/portable_iarchive.cpp @@ -0,0 +1,40 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// 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 + +#define BOOST_ARCHIVE_SOURCE +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace archive { + + + // explicitly instantiate for this type of binary stream + template class basic_binary_iarchive; + + template class basic_binary_iprimitive< + portable_iarchive + , std::istream::char_type + , std::istream::traits_type + >; + + // need to instantiate this template also for polymorphic version? + template class detail::archive_serializer_map; + template class detail::archive_serializer_map; + +} // namespace archive +} // namespace boost diff --git a/src/portable_oarchive.cpp b/src/portable_oarchive.cpp new file mode 100644 index 0000000000..29ff0c7408 --- /dev/null +++ b/src/portable_oarchive.cpp @@ -0,0 +1,40 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// 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 + +#define BOOST_ARCHIVE_SOURCE +#include +#include +#include + +// explicitly instantiate for this type of binary stream +#include +#include +#include + +namespace boost { +namespace archive { + + // explicitly instantiate for this type of binary stream + template class basic_binary_oarchive; + + template class basic_binary_oprimitive< + portable_oarchive + , std::ostream::char_type + , std::ostream::traits_type + >; + + // need to instantiate this template also for polymorphic version? + template class detail::archive_serializer_map; + template class detail::archive_serializer_map; + +} // namespace archive +} // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a42bced472..4ab4ba1684 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -8,7 +8,7 @@ project libs/serialization/test : id serialization_test - : requirements /boost/filesystem + : requirements /boost/filesystem /boost/program_options ; # import rules for testing conditional on config file variables diff --git a/test/polymorphic_portable_archive.hpp b/test/polymorphic_portable_archive.hpp index 91d4cc3c0c..d87ce3ea4b 100755 --- a/test/polymorphic_portable_archive.hpp +++ b/test/polymorphic_portable_archive.hpp @@ -21,13 +21,13 @@ // include output archive header #include // set name of test output archive -typedef eos::polymorphic_portable_oarchive test_oarchive; +typedef boost::archive::polymorphic_portable_oarchive test_oarchive; // set name of test output stream typedef std::ofstream test_ostream; // repeat the above for input archive #include -typedef eos::polymorphic_portable_iarchive test_iarchive; +typedef boost::archive::polymorphic_portable_iarchive test_iarchive; typedef std::ifstream test_istream; // define open mode for streams diff --git a/test/portable_archive.hpp b/test/portable_archive.hpp index 95b0cda852..db851d3882 100644 --- a/test/portable_archive.hpp +++ b/test/portable_archive.hpp @@ -12,13 +12,13 @@ // #include output archive header #include // define output archive class to be used -typedef eos::portable_oarchive test_oarchive; +typedef boost::archive::portable_oarchive test_oarchive; // and corresponding stream typedef std::ofstream test_ostream; // repeat the above for correspondng input archive #include -typedef eos::portable_iarchive test_iarchive; +typedef boost::archive::portable_iarchive test_iarchive; typedef std::ifstream test_istream; // and stream open flags