Opened 14 years ago

Closed 13 years ago

Last modified 13 years ago

#2271 closed Patches (fixed)

Cannot load version 1.35.0 xml archives that contain vectors of primitive types

Reported by: Ryan Mulder <rjmyst3@…> Owned by: Matthias Troyer
Milestone: Boost 1.37.0 Component: serialization
Version: Boost 1.36.0 Severity: Problem
Keywords: Cc:

Description

Version 1.35.0 xml archives are missing the <item_version> element in vectors of primitive types.

This is obviously a known issue, because version 1.36.0 includes the compatibility header vector_135.hpp.

The problem is, that even when vector_135.hpp is included, it makes no difference because the appropriate load method is not called.

The load method in vector.hpp that is aware of the 1.35.0 bug is this:

template<class Archive, class U, class Allocator>
inline void load(
    Archive & ar,
    std::vector<U, Allocator> &t,
    const unsigned int /* file_version */,
    mpl::true_
){
    collection_size_type count(t.size());
    ar >> BOOST_SERIALIZATION_NVP(count);
    t.resize(count);
    unsigned int item_version=0;
    if(BOOST_SERIALIZATION_VECTOR_VERSION < ar.get_library_version())
        ar >> BOOST_SERIALIZATION_NVP(item_version);
    if (!t.empty())
      ar >> make_array(detail::get_data(t),t.size());
  }

It works correctly, when called. The problem is that the load method which dispatches to either the default or the optimized version chooses the wrong version for vectors of primitive types.

template<class Archive, class U, class Allocator>
inline void load(
    Archive & ar,
    std::vector<U, Allocator> &t,
    const unsigned int file_version
){
	load(ar,t,file_version, BOOST_DEDUCED_TYPENAME use_array_optimization<Archive>::template apply<U>::type() );
}

For some reason, use_array_optimization does not work with primitive types.

Version 1.35.0 used boost::detail::has_default_constructor<U>() to dispatch.

My patch changes the dispatching load method to this:

template<class Archive, class U, class Allocator>
inline void load(
    Archive & ar,
    std::vector<U, Allocator> &t,
    const unsigned int file_version
){
	if(BOOST_SERIALIZATION_VECTOR_VERSION < ar.get_library_version())
	{
		load(ar,t,file_version, BOOST_DEDUCED_TYPENAME use_array_optimization<Archive>::template apply<U>::type() );
	}
	else
	{
		load(ar,t,file_version, boost::detail::has_default_constructor<U>() );		
	}
}

It works well, but I do not fully why use_array_optimization did not work alone.

I used a vector< unsigned char > as a test case.

Attachments (1)

load_1.35_vector.patch (974 bytes ) - added by Ryan Mulder <rjmyst3@…> 14 years ago.

Download all attachments as: .zip

Change History (4)

by Ryan Mulder <rjmyst3@…>, 14 years ago

Attachment: load_1.35_vector.patch added

comment:1 by Robert Ramey, 14 years ago

Owner: changed from Robert Ramey to Matthias Troyer

comment:2 by anonymous, 13 years ago

Resolution: fixed
Status: newclosed

comment:3 by Matthias Troyer, 13 years ago

(In [55415]) Fixed ticket 2271

Note: See TracTickets for help on using tickets.