ptr_sequence and transfer functions.
I have a problem with the current ptr_sequence interface, according to the documentation point #7 at this location: http://www.boost.org/libs/ptr_container/doc/examples.html#transferring-owner... it should be possible to write something such as this ptr_list<X> list; ptr_vector<X> vec; list.transfer( list.begin(), vec.begin(), vec ); vec.transfer( vec.end(), list.begin(), list.end(), list ); i.e. given a U<T> and a V<T> I should be able to perform transfer operations in either direction. However given a suitable X this code fails to compile on VC++ 8 as well as GCC 3.4. Indeed any attempt to transfer between different ptr_sequence types (e.g. ptr_deque<X> to ptr_vector<X>) fails to compile. Looking at the implementation of ptr_sequence it appears easy to see why this is the case. However my question is is the documentation incorrect or is the current code incorrect? Right now if I wish to create containers of objects and then transfer ownership to others I'm forced to use the same container type throughout (i.e. the transfer functions provide no benefit at all if I have to choose the wrong container for the job), either that or write awkward transferal code when it appears the simple transfer function should do the job. Could someone please explain the situation regarding the transfer functions and documentation at this time? Thanks, Mat.
Matthew Bray skrev:
I have a problem with the current ptr_sequence interface, according to the documentation point #7 at this location: http://www.boost.org/libs/ptr_container/doc/examples.html#transferring-owner...
it should be possible to write something such as this
ptr_list<X> list; ptr_vector<X> vec;
list.transfer( list.begin(), vec.begin(), vec ); vec.transfer( vec.end(), list.begin(), list.end(), list );
i.e. given a U<T> and a V<T> I should be able to perform transfer operations in either direction.
However given a suitable X this code fails to compile on VC++ 8 as well as GCC 3.4. Indeed any attempt to transfer between different ptr_sequence types (e.g. ptr_deque<X> to ptr_vector<X>) fails to compile. Looking at the implementation of ptr_sequence it appears easy to see why this is the case.
I think the documentation is incorrect. Could you check if this has been fixed in 1.34? -Thorsten Here's the code for 1.34: template< class PtrSeqAdapter > void transfer( iterator before, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), first.base(), last.base() ); // strong from.c_private().erase( first.base(), last.base() ); // nothrow } template< class PtrSeqAdapter > void transfer( iterator before, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), *object.base() ); // strong from.c_private().erase( object.base() ); // nothrow } template< class PtrSeqAdapter > void transfer( iterator before, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), from.begin().base(), from.end().base() ); // strong from.c_private().clear(); // nothrow }
Thorsten Ottosen wrote:
Matthew Bray skrev:
<snip>
I think the documentation is incorrect.
Could you check if this has been fixed in 1.34?
-Thorsten
The code below almost allows the transfer functions to work as shown in the current documentation, unfortunately 'reversible_ptr_container::c_private()' is protected and stopping the lines 'from.c_private(). ...' from compiling. If c_private is made public then the transfer functions work correctly, possibly there's a further work-around? Mat.
Here's the code for 1.34:
template< class PtrSeqAdapter > void transfer( iterator before, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), first.base(), last.base() ); // strong from.c_private().erase( first.base(), last.base() ); // nothrow }
template< class PtrSeqAdapter > void transfer( iterator before, BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), *object.base() ); // strong from.c_private().erase( object.base() ); // nothrow }
template< class PtrSeqAdapter > void transfer( iterator before, PtrSeqAdapter& from ) // strong { BOOST_ASSERT( (void*)&from != (void*)this ); if( from.empty() ) return; this->c_private(). insert( before.base(), from.begin().base(), from.end().base() ); // strong from.c_private().clear(); // nothrow }
Matthew Bray skrev:
Thorsten Ottosen wrote:
Matthew Bray skrev:
<snip> I think the documentation is incorrect.
Could you check if this has been fixed in 1.34?
-Thorsten
The code below almost allows the transfer functions to work as shown in the current documentation, unfortunately 'reversible_ptr_container::c_private()' is protected and stopping the lines 'from.c_private(). ...' from compiling.
Doh! Aren't templates just great sometimes.
If c_private is made public then the transfer functions work correctly, possibly there's a further work-around?
Hm. I dunno. Compilers are starting to support templated friends, so maybe that is the way to go for 1.35. Thanks for reporting this. -Thorsten
Matthew Bray skrev:
The code below almost allows the transfer functions to work as shown in the current documentation, unfortunately 'reversible_ptr_container::c_private()' is protected and stopping the lines 'from.c_private(). ...' from compiling. If c_private is made public then the transfer functions work correctly, possibly there's a further work-around?
The code is definitely intended to work between different sequence containers. Therefore you would not get into problems if you modified your local copy and made c_private() public (just don't use c_private() directly). I can't think of any better solution. Sorry. -Thorsten
participants (2)
-
Matthew Bray
-
Thorsten Ottosen