Chris@16: // Chris@16: // Boost.Pointer Container Chris@16: // Chris@16: // Copyright Thorsten Ottosen 2003-2005. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/ptr_container/ Chris@16: // Chris@16: Chris@16: Chris@16: #ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP Chris@16: #define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_NO_SFINAE Chris@16: #else Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable:4127) Chris@16: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: namespace ptr_container_detail Chris@16: { Chris@16: template< class CloneAllocator > Chris@16: struct clone_deleter Chris@16: { Chris@16: template< class T > Chris@16: void operator()( const T* p ) const Chris@16: { Chris@16: CloneAllocator::deallocate_clone( p ); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< class T > Chris@16: struct is_pointer_or_integral Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(bool, value = is_pointer::value || is_integral::value ); Chris@16: }; Chris@16: Chris@16: struct is_pointer_or_integral_tag {}; Chris@16: struct is_range_tag {}; Chris@16: struct sequence_tag {}; Chris@16: struct fixed_length_sequence_tag : sequence_tag {}; Chris@16: struct associative_container_tag {}; Chris@16: struct ordered_associative_container_tag : associative_container_tag {}; Chris@16: struct unordered_associative_container_tag : associative_container_tag {}; Chris@16: Chris@16: Chris@16: Chris@16: template Chris@16: < Chris@16: class Config, Chris@16: class CloneAllocator Chris@16: > Chris@16: class reversible_ptr_container Chris@16: { Chris@16: private: Chris@16: BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null ); Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_; Chris@16: Chris@16: template< bool allow_null_values > Chris@16: struct null_clone_allocator Chris@16: { Chris@16: template< class Iter > Chris@16: static Ty_* allocate_clone_from_iterator( Iter i ) Chris@16: { Chris@16: return allocate_clone( Config::get_const_pointer( i ) ); Chris@16: } Chris@16: Chris@16: static Ty_* allocate_clone( const Ty_* x ) Chris@16: { Chris@16: if( allow_null_values ) Chris@16: { Chris@16: if( x == 0 ) Chris@16: return 0; Chris@16: } Chris@16: else Chris@16: { Chris@16: BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" ); Chris@16: } Chris@16: Chris@16: Ty_* res = CloneAllocator::allocate_clone( *x ); Chris@16: BOOST_ASSERT( typeid(*res) == typeid(*x) && Chris@16: "CloneAllocator::allocate_clone() does not clone the " Chris@16: "object properly. Check that new_clone() is implemented" Chris@16: " correctly" ); Chris@16: return res; Chris@16: } Chris@16: Chris@16: static void deallocate_clone( const Ty_* x ) Chris@16: { Chris@16: if( allow_null_values ) Chris@16: { Chris@16: if( x == 0 ) Chris@16: return; Chris@16: } Chris@16: Chris@16: CloneAllocator::deallocate_clone( x ); Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::void_container_type Cont; Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: typedef null_clone_allocator Chris@16: null_cloner_type; Chris@16: #else Chris@16: typedef null_clone_allocator null_cloner_type; Chris@16: #endif Chris@16: typedef clone_deleter Deleter; Chris@16: Chris@16: Cont c_; Chris@16: Chris@16: public: Chris@16: Cont& base() { return c_; } Chris@16: protected: // having this public could break encapsulation Chris@16: const Cont& base() const { return c_; } Chris@16: Chris@16: public: // typedefs Chris@16: typedef Ty_* value_type; Chris@16: typedef Ty_* pointer; Chris@16: typedef Ty_& reference; Chris@16: typedef const Ty_& const_reference; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::iterator Chris@16: iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::const_iterator Chris@16: const_iterator; Chris@16: typedef boost::reverse_iterator< iterator > Chris@16: reverse_iterator; Chris@16: typedef boost::reverse_iterator< const_iterator > Chris@16: const_reverse_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Cont::difference_type Chris@16: difference_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME Cont::size_type Chris@16: size_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME Config::allocator_type Chris@16: allocator_type; Chris@16: typedef CloneAllocator clone_allocator_type; Chris@16: typedef ptr_container_detail::static_move_ptr Chris@16: auto_type; Chris@16: Chris@16: protected: Chris@16: Chris@16: typedef ptr_container_detail::scoped_deleter Chris@16: scoped_deleter; Chris@16: typedef BOOST_DEDUCED_TYPENAME Cont::iterator Chris@16: ptr_iterator; Chris@16: typedef BOOST_DEDUCED_TYPENAME Cont::const_iterator Chris@16: ptr_const_iterator; Chris@16: private: Chris@16: Chris@16: template< class InputIterator > Chris@16: void copy( InputIterator first, InputIterator last ) Chris@16: { Chris@16: std::copy( first, last, begin() ); Chris@16: } Chris@16: Chris@16: void copy( const reversible_ptr_container& r ) Chris@16: { Chris@16: copy( r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: void copy_clones_and_release( scoped_deleter& sd ) // nothrow Chris@16: { Chris@16: BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() ); Chris@16: std::copy( sd.begin(), sd.end(), c_.begin() ); Chris@16: sd.release(); Chris@16: } Chris@16: Chris@16: template< class ForwardIterator > Chris@16: void clone_assign( ForwardIterator first, Chris@16: ForwardIterator last ) // strong Chris@16: { Chris@16: BOOST_ASSERT( first != last ); Chris@16: scoped_deleter sd( first, last ); // strong Chris@16: copy_clones_and_release( sd ); // nothrow Chris@16: } Chris@16: Chris@16: template< class ForwardIterator > Chris@16: void clone_back_insert( ForwardIterator first, Chris@16: ForwardIterator last ) Chris@16: { Chris@16: BOOST_ASSERT( first != last ); Chris@16: scoped_deleter sd( first, last ); Chris@16: insert_clones_and_release( sd, end() ); Chris@16: } Chris@16: Chris@16: void remove_all() Chris@16: { Chris@16: remove( begin(), end() ); Chris@16: } Chris@16: Chris@16: protected: Chris@16: Chris@16: void insert_clones_and_release( scoped_deleter& sd, Chris@16: iterator where ) // strong Chris@16: { Chris@16: // Chris@16: // 'c_.insert' always provides the strong guarantee for T* elements Chris@16: // since a copy constructor of a pointer cannot throw Chris@16: // Chris@16: c_.insert( where.base(), Chris@16: sd.begin(), sd.end() ); Chris@16: sd.release(); Chris@16: } Chris@16: Chris@16: void insert_clones_and_release( scoped_deleter& sd ) // strong Chris@16: { Chris@16: c_.insert( sd.begin(), sd.end() ); Chris@16: sd.release(); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: void remove( U* ptr ) Chris@16: { Chris@16: null_policy_deallocate_clone( ptr ); Chris@16: } Chris@16: Chris@16: template< class I > Chris@16: void remove( I i ) Chris@16: { Chris@16: null_policy_deallocate_clone( Config::get_const_pointer(i) ); Chris@16: } Chris@16: Chris@16: template< class I > Chris@16: void remove( I first, I last ) Chris@16: { Chris@16: for( ; first != last; ++first ) Chris@16: remove( first ); Chris@16: } Chris@16: Chris@16: static void enforce_null_policy( const Ty_* x, const char* msg ) Chris@16: { Chris@16: if( !allow_null ) Chris@16: { Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed", Chris@16: bad_pointer, msg ); Chris@16: } Chris@16: } Chris@16: Chris@16: static Ty_* null_policy_allocate_clone( const Ty_* x ) Chris@16: { Chris@16: return null_cloner_type::allocate_clone( x ); Chris@16: } Chris@16: Chris@16: static void null_policy_deallocate_clone( const Ty_* x ) Chris@16: { Chris@16: null_cloner_type::deallocate_clone( x ); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< class ForwardIterator > Chris@16: ForwardIterator advance( ForwardIterator begin, size_type n ) Chris@16: { Chris@16: ForwardIterator iter = begin; Chris@16: std::advance( iter, n ); Chris@16: return iter; Chris@16: } Chris@16: Chris@16: template< class I > Chris@16: void constructor_impl( I first, I last, std::input_iterator_tag ) // basic Chris@16: { Chris@16: while( first != last ) Chris@16: { Chris@16: insert( end(), null_cloner_type::allocate_clone_from_iterator(first) ); Chris@16: ++first; Chris@16: } Chris@16: } Chris@16: Chris@16: template< class I > Chris@16: void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong Chris@16: { Chris@16: if( first == last ) Chris@16: return; Chris@16: clone_back_insert( first, last ); Chris@16: } Chris@16: Chris@16: template< class I > Chris@16: void associative_constructor_impl( I first, I last ) // strong Chris@16: { Chris@16: if( first == last ) Chris@16: return; Chris@16: Chris@16: scoped_deleter sd( first, last ); Chris@16: insert_clones_and_release( sd ); Chris@16: } Chris@16: Chris@16: public: // foundation! should be protected! Chris@16: reversible_ptr_container() Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: reversible_ptr_container( SizeType n, unordered_associative_container_tag ) Chris@16: : c_( n ) Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: reversible_ptr_container( SizeType n, fixed_length_sequence_tag ) Chris@16: : c_( n ) Chris@16: { } Chris@16: Chris@16: template< class SizeType > Chris@16: reversible_ptr_container( SizeType n, const allocator_type& a, Chris@16: fixed_length_sequence_tag ) Chris@16: : c_( n, a ) Chris@16: { } Chris@16: Chris@16: explicit reversible_ptr_container( const allocator_type& a ) Chris@16: : c_( a ) Chris@16: { } Chris@16: Chris@16: template< class PtrContainer > Chris@16: explicit reversible_ptr_container( std::auto_ptr clone ) Chris@16: { Chris@16: swap( *clone ); Chris@16: } Chris@16: Chris@16: reversible_ptr_container( const reversible_ptr_container& r ) Chris@16: { Chris@16: constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() ); Chris@16: } Chris@16: Chris@16: template< class C, class V > Chris@16: reversible_ptr_container( const reversible_ptr_container& r ) Chris@16: { Chris@16: constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() ); Chris@16: } Chris@16: Chris@16: template< class PtrContainer > Chris@16: reversible_ptr_container& operator=( std::auto_ptr clone ) // nothrow Chris@16: { Chris@16: swap( *clone ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: reversible_ptr_container& operator=( reversible_ptr_container r ) // strong Chris@16: { Chris@16: swap( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // overhead: null-initilization of container pointer (very cheap compared to cloning) Chris@16: // overhead: 1 heap allocation (very cheap compared to cloning) Chris@16: template< class InputIterator > Chris@16: reversible_ptr_container( InputIterator first, Chris@16: InputIterator last, Chris@16: const allocator_type& a = allocator_type() ) // basic, strong Chris@16: : c_( a ) Chris@16: { Chris@16: constructor_impl( first, last, Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: #else Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: #endif Chris@16: iterator_category::type() ); Chris@16: } Chris@16: Chris@16: template< class Compare > Chris@16: reversible_ptr_container( const Compare& comp, Chris@16: const allocator_type& a ) Chris@16: : c_( comp, a ) {} Chris@16: Chris@16: template< class ForwardIterator > Chris@16: reversible_ptr_container( ForwardIterator first, Chris@16: ForwardIterator last, Chris@16: fixed_length_sequence_tag ) Chris@16: : c_( std::distance(first,last) ) Chris@16: { Chris@16: constructor_impl( first, last, Chris@16: std::forward_iterator_tag() ); Chris@16: } Chris@16: Chris@16: template< class SizeType, class InputIterator > Chris@16: reversible_ptr_container( SizeType n, Chris@16: InputIterator first, Chris@16: InputIterator last, Chris@16: fixed_length_sequence_tag ) Chris@16: : c_( n ) Chris@16: { Chris@16: constructor_impl( first, last, Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: #else Chris@16: BOOST_DEDUCED_TYPENAME Chris@16: #endif Chris@16: iterator_category::type() ); Chris@16: } Chris@16: Chris@16: template< class Compare > Chris@16: reversible_ptr_container( const Compare& comp, Chris@16: const allocator_type& a, Chris@16: associative_container_tag ) Chris@16: : c_( comp, a ) Chris@16: { } Chris@16: Chris@16: template< class InputIterator > Chris@16: reversible_ptr_container( InputIterator first, Chris@16: InputIterator last, Chris@16: associative_container_tag ) Chris@16: { Chris@16: associative_constructor_impl( first, last ); Chris@16: } Chris@16: Chris@16: template< class InputIterator, class Compare > Chris@16: reversible_ptr_container( InputIterator first, Chris@16: InputIterator last, Chris@16: const Compare& comp, Chris@16: const allocator_type& a, Chris@16: associative_container_tag ) Chris@16: : c_( comp, a ) Chris@16: { Chris@16: associative_constructor_impl( first, last ); Chris@16: } Chris@16: Chris@16: explicit reversible_ptr_container( size_type n ) Chris@16: : c_( n ) {} Chris@16: Chris@16: template< class Hash, class Pred > Chris@16: reversible_ptr_container( const Hash& h, Chris@16: const Pred& pred, Chris@16: const allocator_type& a ) Chris@16: : c_( h, pred, a ) {} Chris@16: Chris@16: template< class InputIterator, class Hash, class Pred > Chris@16: reversible_ptr_container( InputIterator first, Chris@16: InputIterator last, Chris@16: const Hash& h, Chris@16: const Pred& pred, Chris@16: const allocator_type& a ) Chris@16: : c_( h, pred, a ) Chris@16: { Chris@16: associative_constructor_impl( first, last ); Chris@16: } Chris@16: Chris@16: public: Chris@16: ~reversible_ptr_container() Chris@16: { Chris@16: remove_all(); Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: allocator_type get_allocator() const Chris@16: { Chris@16: return c_.get_allocator(); Chris@16: } Chris@16: Chris@16: public: // container requirements Chris@16: iterator begin() Chris@16: { return iterator( c_.begin() ); } Chris@16: const_iterator begin() const Chris@16: { return const_iterator( c_.begin() ); } Chris@16: iterator end() Chris@16: { return iterator( c_.end() ); } Chris@16: const_iterator end() const Chris@16: { return const_iterator( c_.end() ); } Chris@16: Chris@16: reverse_iterator rbegin() Chris@16: { return reverse_iterator( this->end() ); } Chris@16: const_reverse_iterator rbegin() const Chris@16: { return const_reverse_iterator( this->end() ); } Chris@16: reverse_iterator rend() Chris@16: { return reverse_iterator( this->begin() ); } Chris@16: const_reverse_iterator rend() const Chris@16: { return const_reverse_iterator( this->begin() ); } Chris@16: Chris@16: const_iterator cbegin() const Chris@16: { return const_iterator( c_.begin() ); } Chris@16: const_iterator cend() const Chris@16: { return const_iterator( c_.end() ); } Chris@16: Chris@16: const_reverse_iterator crbegin() const Chris@16: { return const_reverse_iterator( this->end() ); } Chris@16: const_reverse_iterator crend() const Chris@16: { return const_reverse_iterator( this->begin() ); } Chris@16: Chris@16: void swap( reversible_ptr_container& r ) // nothrow Chris@16: { Chris@16: c_.swap( r.c_ ); Chris@16: } Chris@16: Chris@16: size_type size() const // nothrow Chris@16: { Chris@16: return c_.size(); Chris@16: } Chris@16: Chris@16: size_type max_size() const // nothrow Chris@16: { Chris@16: return c_.max_size(); Chris@16: } Chris@16: Chris@16: bool empty() const // nothrow Chris@16: { Chris@16: return c_.empty(); Chris@16: } Chris@16: Chris@16: public: // optional container requirements Chris@16: Chris@16: bool operator==( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: if( size() != r.size() ) Chris@16: return false; Chris@16: else Chris@16: return std::equal( begin(), end(), r.begin() ); Chris@16: } Chris@16: Chris@16: bool operator!=( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: return !(*this == r); Chris@16: } Chris@16: Chris@16: bool operator<( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: return std::lexicographical_compare( begin(), end(), r.begin(), r.end() ); Chris@16: } Chris@16: Chris@16: bool operator<=( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: return !(r < *this); Chris@16: } Chris@16: Chris@16: bool operator>( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: return r < *this; Chris@16: } Chris@16: Chris@16: bool operator>=( const reversible_ptr_container& r ) const // nothrow Chris@16: { Chris@16: return !(*this < r); Chris@16: } Chris@16: Chris@16: public: // modifiers Chris@16: Chris@16: iterator insert( iterator before, Ty_* x ) Chris@16: { Chris@16: enforce_null_policy( x, "Null pointer in 'insert()'" ); Chris@16: Chris@16: auto_type ptr( x ); // nothrow Chris@16: iterator res( c_.insert( before.base(), x ) ); // strong, commit Chris@16: ptr.release(); // nothrow Chris@16: return res; Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: iterator insert( iterator before, std::auto_ptr x ) Chris@16: { Chris@16: return insert( before, x.release() ); Chris@16: } Chris@16: Chris@16: iterator erase( iterator x ) // nothrow Chris@16: { Chris@16: BOOST_ASSERT( !empty() ); Chris@16: BOOST_ASSERT( x != end() ); Chris@16: Chris@16: remove( x ); Chris@16: return iterator( c_.erase( x.base() ) ); Chris@16: } Chris@16: Chris@16: iterator erase( iterator first, iterator last ) // nothrow Chris@16: { Chris@16: remove( first, last ); Chris@16: return iterator( c_.erase( first.base(), Chris@16: last.base() ) ); Chris@16: } Chris@16: Chris@16: template< class Range > Chris@16: iterator erase( const Range& r ) Chris@16: { Chris@16: return erase( boost::begin(r), boost::end(r) ); Chris@16: } Chris@16: Chris@16: void clear() Chris@16: { Chris@16: remove_all(); Chris@16: c_.clear(); Chris@16: } Chris@16: Chris@16: public: // access interface Chris@16: Chris@16: auto_type release( iterator where ) Chris@16: { Chris@16: BOOST_ASSERT( where != end() ); Chris@16: Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation, Chris@16: "'release()' on empty container" ); Chris@16: Chris@16: auto_type ptr( Config::get_pointer( where ) ); // nothrow Chris@16: c_.erase( where.base() ); // nothrow Chris@16: return boost::ptr_container_detail::move( ptr ); Chris@16: } Chris@16: Chris@16: auto_type replace( iterator where, Ty_* x ) // strong Chris@16: { Chris@16: BOOST_ASSERT( where != end() ); Chris@16: Chris@16: enforce_null_policy( x, "Null pointer in 'replace()'" ); Chris@16: Chris@16: auto_type ptr( x ); Chris@16: Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation, Chris@16: "'replace()' on empty container" ); Chris@16: Chris@16: auto_type old( Config::get_pointer( where ) ); // nothrow Chris@16: const_cast(*where.base()) = ptr.release(); Chris@16: return boost::ptr_container_detail::move( old ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: auto_type replace( iterator where, std::auto_ptr x ) Chris@16: { Chris@16: return replace( where, x.release() ); Chris@16: } Chris@16: Chris@16: auto_type replace( size_type idx, Ty_* x ) // strong Chris@16: { Chris@16: enforce_null_policy( x, "Null pointer in 'replace()'" ); Chris@16: Chris@16: auto_type ptr( x ); Chris@16: Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= size(), bad_index, Chris@16: "'replace()' out of bounds" ); Chris@16: Chris@16: auto_type old( static_cast( c_[idx] ) ); // nothrow Chris@16: c_[idx] = ptr.release(); // nothrow, commit Chris@16: return boost::ptr_container_detail::move( old ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: auto_type replace( size_type idx, std::auto_ptr x ) Chris@16: { Chris@16: return replace( idx, x.release() ); Chris@16: } Chris@16: Chris@16: }; // 'reversible_ptr_container' Chris@16: Chris@16: Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \ Chris@16: typename base_type::auto_type \ Chris@16: release( typename base_type::iterator i ) \ Chris@16: { \ Chris@16: return boost::ptr_container_detail::move(base_type::release(i)); \ Chris@16: } Chris@16: #else Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \ Chris@16: using base_type::release; Chris@16: #endif Chris@16: Chris@16: // Chris@16: // two-phase lookup of template functions Chris@16: // is buggy on most compilers, so we use a macro instead Chris@16: // Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) \ Chris@16: explicit PC( std::auto_ptr r ) \ Chris@16: : base_type ( r ) { } \ Chris@16: \ Chris@16: PC& operator=( std::auto_ptr r ) \ Chris@16: { \ Chris@16: base_type::operator=( r ); \ Chris@16: return *this; \ Chris@16: } \ Chris@16: \ Chris@16: std::auto_ptr release() \ Chris@16: { \ Chris@16: std::auto_ptr ptr( new this_type );\ Chris@16: this->swap( *ptr ); \ Chris@16: return ptr; \ Chris@16: } \ Chris@16: BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \ Chris@16: \ Chris@16: std::auto_ptr clone() const \ Chris@16: { \ Chris@16: return std::auto_ptr( new this_type( this->begin(), this->end() ) ); \ Chris@16: } Chris@16: Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type ) \ Chris@16: \ Chris@16: template< class U > \ Chris@16: PC( const PC& r ) : base_type( r ) { } \ Chris@16: \ Chris@16: PC& operator=( PC r ) \ Chris@16: { \ Chris@16: this->swap( r ); \ Chris@16: return *this; \ Chris@16: } \ Chris@16: Chris@16: Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \ Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::iterator iterator; \ Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; \ Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::const_reference const_reference; \ Chris@16: typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type allocator_type; \ Chris@16: PC() {} \ Chris@16: explicit PC( const allocator_type& a ) : base_type(a) {} \ Chris@16: template< class InputIterator > \ Chris@16: PC( InputIterator first, InputIterator last ) : base_type( first, last ) {} \ Chris@16: template< class InputIterator > \ Chris@16: PC( InputIterator first, InputIterator last, \ Chris@16: const allocator_type& a ) : base_type( first, last, a ) {} Chris@16: Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \ Chris@16: BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \ Chris@16: BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) Chris@16: Chris@16: #define BOOST_PTR_CONTAINER_DEFINE_SEQEUENCE_MEMBERS( PC, base_type, this_type ) \ Chris@16: BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \ Chris@16: BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type ) Chris@16: Chris@16: } // namespace 'ptr_container_detail' Chris@16: Chris@16: // Chris@16: // @remark: expose movability of internal move-pointer Chris@16: // Chris@16: namespace ptr_container Chris@16: { Chris@16: using ptr_container_detail::move; Chris@16: } Chris@16: Chris@16: } // namespace 'boost' Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif