From 3d7ac026c6401d05533c3bc9ef7b3c90173a47a8 Mon Sep 17 00:00:00 2001 From: Robert Ramey Date: Sun, 28 Apr 2013 20:23:10 +0000 Subject: [PATCH] sync with release branch [SVN r84077] --- src/basic_iarchive.cpp | 88 +++++++++++++++++++++++++----------------- test/test_check.cpp | 3 ++ 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/basic_iarchive.cpp b/src/basic_iarchive.cpp index e9badddb..8266de46 100644 --- a/src/basic_iarchive.cpp +++ b/src/basic_iarchive.cpp @@ -81,9 +81,18 @@ class basic_iarchive_impl { ////////////////////////////////////////////////////////////////////// // used to implement the reset_object_address operation. - object_id_type moveable_objects_start; - object_id_type moveable_objects_end; - object_id_type moveable_objects_recent; + struct moveable_objects { + object_id_type start; + object_id_type end; + object_id_type recent; + bool is_pointer; + moveable_objects() : + start(0), + end(0), + recent(0), + is_pointer(false) + {} + } m_moveable_objects; void reset_object_address( const void * new_address, @@ -159,19 +168,20 @@ class basic_iarchive_impl { ////////////////////////////////////////////////////////////////////// // address of the most recent object serialized as a poiner // whose data itself is now pending serialization - void * pending_object; - const basic_iserializer * pending_bis; - version_type pending_version; + struct pending { + void * object; + const basic_iserializer * bis; + version_type version; + pending() : + object(NULL), + bis(NULL), + version(0) + {} + } m_pending; basic_iarchive_impl(unsigned int flags) : m_archive_library_version(BOOST_ARCHIVE_VERSION()), - m_flags(flags), - moveable_objects_start(0), - moveable_objects_end(0), - moveable_objects_recent(0), - pending_object(NULL), - pending_bis(NULL), - pending_version(0) + m_flags(flags) {} ~basic_iarchive_impl(){} void set_library_version(library_version_type archive_library_version){ @@ -200,7 +210,7 @@ class basic_iarchive_impl { //public: void next_object_pointer(void * t){ - pending_object = t; + m_pending.object = t; } void delete_created_pointers(); class_id_type register_type( @@ -224,9 +234,12 @@ class basic_iarchive_impl { inline void basic_iarchive_impl::reset_object_address( - const void * new_address, - const void *old_address + void const * const new_address, + void const * const old_address ){ + if(m_moveable_objects.is_pointer) + return; + // this code handles a couple of situations. // a) where reset_object_address is applied to an untracked object. // In such a case the call is really superfluous and its really an @@ -240,18 +253,18 @@ basic_iarchive_impl::reset_object_address( // of the programmer but we can't detect it - as above. So maybe we // can save a few more people from themselves as above. object_id_type i; - for(i = moveable_objects_recent; i < moveable_objects_end; ++i){ + for(i = m_moveable_objects.recent; i < m_moveable_objects.end; ++i){ if(old_address == object_id_vector[i].address) break; } - for(; i < moveable_objects_end; ++i){ - + for(; i < m_moveable_objects.end; ++i){ + void const * const this_address = object_id_vector[i].address; // calculate displacement from this level // warning - pointer arithmetic on void * is in herently non-portable // but expected to work on all platforms in current usage - if(object_id_vector[i].address > old_address){ + if(this_address > old_address){ std::size_t member_displacement - = reinterpret_cast(object_id_vector[i].address) + = reinterpret_cast(this_address) - reinterpret_cast(old_address); object_id_vector[i].address = reinterpret_cast( reinterpret_cast(new_address) + member_displacement @@ -260,7 +273,7 @@ basic_iarchive_impl::reset_object_address( else{ std::size_t member_displacement = reinterpret_cast(old_address) - - reinterpret_cast(object_id_vector[i].address); + - reinterpret_cast(this_address); object_id_vector[i].address = reinterpret_cast( reinterpret_cast(new_address) - member_displacement ); @@ -356,10 +369,12 @@ basic_iarchive_impl::load_object( void * t, const basic_iserializer & bis ){ + m_moveable_objects.is_pointer = false; + serialization::state_saver ss_is_pointer(m_moveable_objects.is_pointer); // if its been serialized through a pointer and the preamble's been done - if(t == pending_object && & bis == pending_bis){ + if(t == m_pending.object && & bis == m_pending.bis){ // read data - (bis.load_object_data)(ar, t, pending_version); + (bis.load_object_data)(ar, t, m_pending.version); return; } @@ -370,13 +385,13 @@ basic_iarchive_impl::load_object( load_preamble(ar, co); // save the current move stack position in case we want to truncate it - boost::serialization::state_saver w(moveable_objects_start); + boost::serialization::state_saver ss_start(m_moveable_objects.start); // note: extra line used to evade borland issue const bool tracking = co.tracking_level; object_id_type this_id; - moveable_objects_start = + m_moveable_objects.start = this_id = object_id_type(object_id_vector.size()); // if we tracked this object when the archive was saved @@ -388,11 +403,11 @@ basic_iarchive_impl::load_object( // add a new enty into the tracking list object_id_vector.push_back(aobject(t, cid)); // and add an entry for this object - moveable_objects_end = object_id_type(object_id_vector.size()); + m_moveable_objects.end = object_id_type(object_id_vector.size()); } // read data (bis.load_object_data)(ar, t, co.file_version); - moveable_objects_recent = this_id; + m_moveable_objects.recent = this_id; } inline const basic_pointer_iserializer * @@ -405,6 +420,9 @@ basic_iarchive_impl::load_pointer( ) ){ + m_moveable_objects.is_pointer = true; + serialization::state_saver w(m_moveable_objects.is_pointer); + class_id_type cid; load(ar, cid); @@ -453,23 +471,23 @@ basic_iarchive_impl::load_pointer( return bpis_ptr; // save state - serialization::state_saver w_start(moveable_objects_start); + serialization::state_saver w_start(m_moveable_objects.start); if(! tracking){ bpis_ptr->load_object_ptr(ar, t, co.file_version); } else{ - serialization::state_saver x(pending_object); - serialization::state_saver y(pending_bis); - serialization::state_saver z(pending_version); + serialization::state_saver x(m_pending.object); + serialization::state_saver y(m_pending.bis); + serialization::state_saver z(m_pending.version); - pending_bis = & bpis_ptr->get_basic_serializer(); - pending_version = co.file_version; + m_pending.bis = & bpis_ptr->get_basic_serializer(); + m_pending.version = co.file_version; // predict next object id to be created const unsigned int ui = object_id_vector.size(); - serialization::state_saver w_end(moveable_objects_end); + serialization::state_saver w_end(m_moveable_objects.end); // because the following operation could move the items // don't use co after this diff --git a/test/test_check.cpp b/test/test_check.cpp index 5da30ced..2a6967c1 100644 --- a/test/test_check.cpp +++ b/test/test_check.cpp @@ -23,6 +23,7 @@ struct check1 { template void serialize(Archive & ar, const unsigned int version); + check1(){} }; BOOST_CLASS_IMPLEMENTATION(check1, boost::serialization::object_serializable) @@ -33,6 +34,7 @@ BOOST_CLASS_TRACKING(check1, boost::serialization::track_selectively) struct check2 { template void serialize(Archive & ar, const unsigned int version); + check2(){} }; BOOST_CLASS_IMPLEMENTATION(check2, boost::serialization::object_serializable) @@ -45,6 +47,7 @@ BOOST_CLASS_TRACKING(check2, boost::serialization::track_always) struct check3 { template void serialize(Archive & ar, const unsigned int version); + check3(){} }; BOOST_CLASS_TRACKING(check3, boost::serialization::track_never)