1 //
2 // Boost.Pointer Container
3 //
4 //  Copyright Thorsten Ottosen 2003-2005. Use, modification and
5 //  distribution is subject to the Boost Software License, Version
6 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 //  http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see http://www.boost.org/libs/ptr_container/
10 //
11 
12 
13 #ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
14 #define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
15 
16 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
17 # pragma once
18 #endif
19 
20 #include <boost/ptr_container/detail/throw_exception.hpp>
21 #include <boost/ptr_container/detail/scoped_deleter.hpp>
22 #include <boost/ptr_container/detail/static_move_ptr.hpp>
23 #include <boost/ptr_container/exception.hpp>
24 #include <boost/ptr_container/clone_allocator.hpp>
25 #include <boost/ptr_container/nullable.hpp>
26 
27 #ifdef BOOST_NO_SFINAE
28 #else
29 #include <boost/range/functions.hpp>
30 #endif
31 
32 #include <boost/config.hpp>
33 #include <boost/iterator/reverse_iterator.hpp>
34 #include <boost/range/iterator.hpp>
35 #include <boost/utility/enable_if.hpp>
36 #include <boost/type_traits/is_pointer.hpp>
37 #include <boost/type_traits/is_integral.hpp>
38 #include <typeinfo>
39 #include <memory>
40 
41 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
42 #pragma warning(push)
43 #pragma warning(disable:4127)
44 #endif
45 
46 namespace boost
47 {
48 
49 namespace ptr_container_detail
50 {
51     template< class CloneAllocator >
52     struct clone_deleter
53     {
54         template< class T >
operator ()boost::ptr_container_detail::clone_deleter55         void operator()( const T* p ) const
56         {
57             CloneAllocator::deallocate_clone( p );
58         }
59     };
60 
61     template< class T >
62     struct is_pointer_or_integral
63     {
64         BOOST_STATIC_CONSTANT(bool, value = is_pointer<T>::value || is_integral<T>::value );
65     };
66 
67     struct is_pointer_or_integral_tag {};
68     struct is_range_tag {};
69     struct sequence_tag {};
70     struct fixed_length_sequence_tag : sequence_tag {};
71     struct associative_container_tag {};
72     struct ordered_associative_container_tag : associative_container_tag {};
73     struct unordered_associative_container_tag : associative_container_tag {};
74 
75 
76 
77     template
78     <
79         class Config,
80         class CloneAllocator
81     >
82     class reversible_ptr_container
83     {
84     private:
85         BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null );
86 
87         typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_;
88 
89         template< bool allow_null_values >
90         struct null_clone_allocator
91         {
92             template< class Iter >
allocate_clone_from_iteratorboost::ptr_container_detail::reversible_ptr_container::null_clone_allocator93             static Ty_* allocate_clone_from_iterator( Iter i )
94             {
95                 return allocate_clone( Config::get_const_pointer( i ) );
96             }
97 
allocate_cloneboost::ptr_container_detail::reversible_ptr_container::null_clone_allocator98             static Ty_* allocate_clone( const Ty_* x )
99             {
100                 if( allow_null_values )
101                 {
102                     if( x == 0 )
103                         return 0;
104                 }
105                 else
106                 {
107                     BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" );
108                 }
109 
110                 Ty_* res = CloneAllocator::allocate_clone( *x );
111                 BOOST_ASSERT( typeid(*res) == typeid(*x) &&
112                               "CloneAllocator::allocate_clone() does not clone the "
113                               "object properly. Check that new_clone() is implemented"
114                               " correctly" );
115                 return res;
116             }
117 
deallocate_cloneboost::ptr_container_detail::reversible_ptr_container::null_clone_allocator118             static void deallocate_clone( const Ty_* x )
119             {
120                 if( allow_null_values )
121                 {
122                     if( x == 0 )
123                         return;
124                 }
125 
126                 CloneAllocator::deallocate_clone( x );
127             }
128         };
129 
130         typedef BOOST_DEDUCED_TYPENAME Config::void_container_type  Cont;
131 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
132         typedef  null_clone_allocator<reversible_ptr_container::allow_null>
133                                                                     null_cloner_type;
134 #else
135         typedef null_clone_allocator<allow_null>                    null_cloner_type;
136 #endif
137         typedef clone_deleter<null_cloner_type>                     Deleter;
138 
139         Cont      c_;
140 
141     public:
base()142         Cont&       base()               { return c_; }
143     protected: // having this public could break encapsulation
base() const144         const Cont& base() const         { return c_; }
145 
146     public: // typedefs
147         typedef  Ty_*          value_type;
148         typedef  Ty_*          pointer;
149         typedef  Ty_&          reference;
150         typedef  const Ty_&    const_reference;
151 
152         typedef  BOOST_DEDUCED_TYPENAME Config::iterator
153                                    iterator;
154         typedef  BOOST_DEDUCED_TYPENAME Config::const_iterator
155                                    const_iterator;
156         typedef  boost::reverse_iterator< iterator >
157                                    reverse_iterator;
158         typedef  boost::reverse_iterator< const_iterator >
159                                    const_reverse_iterator;
160         typedef  BOOST_DEDUCED_TYPENAME Cont::difference_type
161                                    difference_type;
162         typedef  BOOST_DEDUCED_TYPENAME Cont::size_type
163                                    size_type;
164         typedef  BOOST_DEDUCED_TYPENAME Config::allocator_type
165                                    allocator_type;
166         typedef CloneAllocator     clone_allocator_type;
167         typedef ptr_container_detail::static_move_ptr<Ty_,Deleter>
168                                    auto_type;
169 
170     protected:
171 
172         typedef ptr_container_detail::scoped_deleter<Ty_,null_cloner_type>
173                                    scoped_deleter;
174         typedef BOOST_DEDUCED_TYPENAME Cont::iterator
175                                    ptr_iterator;
176         typedef BOOST_DEDUCED_TYPENAME Cont::const_iterator
177                                    ptr_const_iterator;
178     private:
179 
180         template< class InputIterator >
copy(InputIterator first,InputIterator last)181         void copy( InputIterator first, InputIterator last )
182         {
183             std::copy( first, last, begin() );
184         }
185 
copy(const reversible_ptr_container & r)186         void copy( const reversible_ptr_container& r )
187         {
188             copy( r.begin(), r.end() );
189         }
190 
copy_clones_and_release(scoped_deleter & sd)191         void copy_clones_and_release( scoped_deleter& sd ) // nothrow
192         {
193             BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() );
194             std::copy( sd.begin(), sd.end(), c_.begin() );
195             sd.release();
196         }
197 
198         template< class ForwardIterator >
clone_assign(ForwardIterator first,ForwardIterator last)199         void clone_assign( ForwardIterator first,
200                            ForwardIterator last ) // strong
201         {
202             BOOST_ASSERT( first != last );
203             scoped_deleter sd( first, last );      // strong
204             copy_clones_and_release( sd );         // nothrow
205         }
206 
207         template< class ForwardIterator >
clone_back_insert(ForwardIterator first,ForwardIterator last)208         void clone_back_insert( ForwardIterator first,
209                                 ForwardIterator last )
210         {
211             BOOST_ASSERT( first != last );
212             scoped_deleter sd( first, last );
213             insert_clones_and_release( sd, end() );
214         }
215 
remove_all()216         void remove_all()
217         {
218             remove( begin(), end() );
219         }
220 
221     protected:
222 
insert_clones_and_release(scoped_deleter & sd,iterator where)223         void insert_clones_and_release( scoped_deleter& sd,
224                                         iterator where ) // strong
225         {
226             //
227             // 'c_.insert' always provides the strong guarantee for T* elements
228             // since a copy constructor of a pointer cannot throw
229             //
230             c_.insert( where.base(),
231                        sd.begin(), sd.end() );
232             sd.release();
233         }
234 
insert_clones_and_release(scoped_deleter & sd)235         void insert_clones_and_release( scoped_deleter& sd ) // strong
236         {
237             c_.insert( sd.begin(), sd.end() );
238             sd.release();
239         }
240 
241         template< class U >
remove(U * ptr)242         void remove( U* ptr )
243         {
244             null_policy_deallocate_clone( ptr );
245         }
246 
247         template< class I >
remove(I i)248         void remove( I i )
249         {
250             null_policy_deallocate_clone( Config::get_const_pointer(i) );
251         }
252 
253         template< class I >
remove(I first,I last)254         void remove( I first, I last )
255         {
256             for( ; first != last; ++first )
257                 remove( first );
258         }
259 
enforce_null_policy(const Ty_ * x,const char * msg)260         static void enforce_null_policy( const Ty_* x, const char* msg )
261         {
262             if( !allow_null )
263             {
264                 BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed",
265                                                      bad_pointer, msg );
266             }
267         }
268 
null_policy_allocate_clone(const Ty_ * x)269         static Ty_* null_policy_allocate_clone( const Ty_* x )
270         {
271             return null_cloner_type::allocate_clone( x );
272         }
273 
null_policy_deallocate_clone(const Ty_ * x)274         static void null_policy_deallocate_clone( const Ty_* x )
275         {
276             null_cloner_type::deallocate_clone( x );
277         }
278 
279     private:
280         template< class ForwardIterator >
advance(ForwardIterator begin,size_type n)281         ForwardIterator advance( ForwardIterator begin, size_type n )
282         {
283             ForwardIterator iter = begin;
284             std::advance( iter, n );
285             return iter;
286         }
287 
288         template< class I >
constructor_impl(I first,I last,std::input_iterator_tag)289         void constructor_impl( I first, I last, std::input_iterator_tag ) // basic
290         {
291             while( first != last )
292             {
293                 insert( end(), null_cloner_type::allocate_clone_from_iterator(first) );
294                 ++first;
295             }
296         }
297 
298         template< class I >
constructor_impl(I first,I last,std::forward_iterator_tag)299         void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong
300         {
301             if( first == last )
302                 return;
303             clone_back_insert( first, last );
304         }
305 
306         template< class I >
associative_constructor_impl(I first,I last)307         void associative_constructor_impl( I first, I last ) // strong
308         {
309             if( first == last )
310                 return;
311 
312             scoped_deleter sd( first, last );
313             insert_clones_and_release( sd );
314         }
315 
316     public: // foundation! should be protected!
reversible_ptr_container()317         reversible_ptr_container()
318         { }
319 
320         template< class SizeType >
reversible_ptr_container(SizeType n,unordered_associative_container_tag)321         reversible_ptr_container( SizeType n, unordered_associative_container_tag )
322           : c_( n )
323         { }
324 
325         template< class SizeType >
reversible_ptr_container(SizeType n,fixed_length_sequence_tag)326         reversible_ptr_container( SizeType n, fixed_length_sequence_tag )
327           : c_( n )
328         { }
329 
330         template< class SizeType >
reversible_ptr_container(SizeType n,const allocator_type & a,fixed_length_sequence_tag)331         reversible_ptr_container( SizeType n, const allocator_type& a,
332                                   fixed_length_sequence_tag )
333           : c_( n, a )
334         { }
335 
reversible_ptr_container(const allocator_type & a)336         explicit reversible_ptr_container( const allocator_type& a )
337          : c_( a )
338         { }
339 
340         template< class PtrContainer >
reversible_ptr_container(std::auto_ptr<PtrContainer> clone)341         explicit reversible_ptr_container( std::auto_ptr<PtrContainer> clone )
342         {
343             swap( *clone );
344         }
345 
reversible_ptr_container(const reversible_ptr_container & r)346         reversible_ptr_container( const reversible_ptr_container& r )
347         {
348             constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
349         }
350 
351         template< class C, class V >
reversible_ptr_container(const reversible_ptr_container<C,V> & r)352         reversible_ptr_container( const reversible_ptr_container<C,V>& r )
353         {
354             constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() );
355         }
356 
357         template< class PtrContainer >
operator =(std::auto_ptr<PtrContainer> clone)358         reversible_ptr_container& operator=( std::auto_ptr<PtrContainer> clone ) // nothrow
359         {
360             swap( *clone );
361             return *this;
362         }
363 
operator =(reversible_ptr_container r)364         reversible_ptr_container& operator=( reversible_ptr_container r ) // strong
365         {
366             swap( r );
367             return *this;
368         }
369 
370         // overhead: null-initilization of container pointer (very cheap compared to cloning)
371         // overhead: 1 heap allocation (very cheap compared to cloning)
372         template< class InputIterator >
reversible_ptr_container(InputIterator first,InputIterator last,const allocator_type & a=allocator_type ())373         reversible_ptr_container( InputIterator first,
374                                   InputIterator last,
375                                   const allocator_type& a = allocator_type() ) // basic, strong
376           : c_( a )
377         {
378             constructor_impl( first, last,
379 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
380 #else
381                               BOOST_DEDUCED_TYPENAME
382 #endif
383                               iterator_category<InputIterator>::type() );
384         }
385 
386         template< class Compare >
reversible_ptr_container(const Compare & comp,const allocator_type & a)387         reversible_ptr_container( const Compare& comp,
388                                   const allocator_type& a )
389           : c_( comp, a ) {}
390 
391         template< class ForwardIterator >
reversible_ptr_container(ForwardIterator first,ForwardIterator last,fixed_length_sequence_tag)392         reversible_ptr_container( ForwardIterator first,
393                                   ForwardIterator last,
394                                   fixed_length_sequence_tag )
395           : c_( std::distance(first,last) )
396         {
397             constructor_impl( first, last,
398                               std::forward_iterator_tag() );
399         }
400 
401         template< class SizeType, class InputIterator >
reversible_ptr_container(SizeType n,InputIterator first,InputIterator last,fixed_length_sequence_tag)402         reversible_ptr_container( SizeType n,
403                                   InputIterator first,
404                                   InputIterator last,
405                                   fixed_length_sequence_tag )
406           : c_( n )
407         {
408             constructor_impl( first, last,
409 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
410 #else
411                               BOOST_DEDUCED_TYPENAME
412 #endif
413                               iterator_category<InputIterator>::type() );
414         }
415 
416         template< class Compare >
reversible_ptr_container(const Compare & comp,const allocator_type & a,associative_container_tag)417         reversible_ptr_container( const Compare& comp,
418                                   const allocator_type& a,
419                                   associative_container_tag )
420           : c_( comp, a )
421         { }
422 
423         template< class InputIterator >
reversible_ptr_container(InputIterator first,InputIterator last,associative_container_tag)424         reversible_ptr_container( InputIterator first,
425                                   InputIterator last,
426                                   associative_container_tag )
427         {
428             associative_constructor_impl( first, last );
429         }
430 
431         template< class InputIterator, class Compare >
reversible_ptr_container(InputIterator first,InputIterator last,const Compare & comp,const allocator_type & a,associative_container_tag)432         reversible_ptr_container( InputIterator first,
433                                   InputIterator last,
434                                   const Compare& comp,
435                                   const allocator_type& a,
436                                   associative_container_tag )
437           : c_( comp, a )
438         {
439             associative_constructor_impl( first, last );
440         }
441 
reversible_ptr_container(size_type n)442         explicit reversible_ptr_container( size_type n )
443           : c_( n ) {}
444 
445         template< class Hash, class Pred >
reversible_ptr_container(const Hash & h,const Pred & pred,const allocator_type & a)446         reversible_ptr_container( const Hash& h,
447                                   const Pred& pred,
448                                   const allocator_type& a )
449           : c_( h, pred, a ) {}
450 
451         template< class InputIterator, class Hash, class Pred >
reversible_ptr_container(InputIterator first,InputIterator last,const Hash & h,const Pred & pred,const allocator_type & a)452         reversible_ptr_container( InputIterator first,
453                                   InputIterator last,
454                                   const Hash& h,
455                                   const Pred& pred,
456                                   const allocator_type& a )
457           : c_( h, pred, a )
458         {
459             associative_constructor_impl( first, last );
460         }
461 
462     public:
~reversible_ptr_container()463         ~reversible_ptr_container()
464         {
465             remove_all();
466         }
467 
468     public:
469 
get_allocator() const470         allocator_type get_allocator() const
471         {
472             return c_.get_allocator();
473         }
474 
475     public: // container requirements
begin()476         iterator begin()
477             { return iterator( c_.begin() ); }
begin() const478         const_iterator begin() const
479             { return const_iterator( c_.begin() ); }
end()480         iterator end()
481             { return iterator( c_.end() ); }
end() const482         const_iterator end() const
483             { return const_iterator( c_.end() ); }
484 
rbegin()485         reverse_iterator rbegin()
486             { return reverse_iterator( this->end() ); }
rbegin() const487         const_reverse_iterator rbegin() const
488             { return const_reverse_iterator( this->end() ); }
rend()489         reverse_iterator rend()
490             { return reverse_iterator( this->begin() ); }
rend() const491         const_reverse_iterator rend() const
492             { return const_reverse_iterator( this->begin() ); }
493 
cbegin() const494         const_iterator cbegin() const
495             { return const_iterator( c_.begin() ); }
cend() const496         const_iterator cend() const
497             { return const_iterator( c_.end() ); }
498 
crbegin() const499         const_reverse_iterator crbegin() const
500             { return const_reverse_iterator( this->end() ); }
crend() const501         const_reverse_iterator crend() const
502             { return const_reverse_iterator( this->begin() ); }
503 
swap(reversible_ptr_container & r)504         void swap( reversible_ptr_container& r ) // nothrow
505         {
506             c_.swap( r.c_ );
507         }
508 
size() const509         size_type size() const // nothrow
510         {
511             return c_.size();
512         }
513 
max_size() const514         size_type max_size() const // nothrow
515         {
516             return c_.max_size();
517         }
518 
empty() const519         bool empty() const // nothrow
520         {
521             return c_.empty();
522         }
523 
524     public: // optional container requirements
525 
operator ==(const reversible_ptr_container & r) const526         bool operator==( const reversible_ptr_container& r ) const // nothrow
527         {
528             if( size() != r.size() )
529                 return false;
530             else
531                 return std::equal( begin(), end(), r.begin() );
532         }
533 
operator !=(const reversible_ptr_container & r) const534         bool operator!=( const reversible_ptr_container& r ) const // nothrow
535         {
536             return !(*this == r);
537         }
538 
operator <(const reversible_ptr_container & r) const539         bool operator<( const reversible_ptr_container& r ) const // nothrow
540         {
541              return std::lexicographical_compare( begin(), end(), r.begin(), r.end() );
542         }
543 
operator <=(const reversible_ptr_container & r) const544         bool operator<=( const reversible_ptr_container& r ) const // nothrow
545         {
546             return !(r < *this);
547         }
548 
operator >(const reversible_ptr_container & r) const549         bool operator>( const reversible_ptr_container& r ) const // nothrow
550         {
551             return r < *this;
552         }
553 
operator >=(const reversible_ptr_container & r) const554         bool operator>=( const reversible_ptr_container& r ) const // nothrow
555         {
556             return !(*this < r);
557         }
558 
559     public: // modifiers
560 
insert(iterator before,Ty_ * x)561         iterator insert( iterator before, Ty_* x )
562         {
563             enforce_null_policy( x, "Null pointer in 'insert()'" );
564 
565             auto_type ptr( x );                            // nothrow
566             iterator res( c_.insert( before.base(), x ) ); // strong, commit
567             ptr.release();                                 // nothrow
568             return res;
569         }
570 
571         template< class U >
insert(iterator before,std::auto_ptr<U> x)572         iterator insert( iterator before, std::auto_ptr<U> x )
573         {
574             return insert( before, x.release() );
575         }
576 
erase(iterator x)577         iterator erase( iterator x ) // nothrow
578         {
579             BOOST_ASSERT( !empty() );
580             BOOST_ASSERT( x != end() );
581 
582             remove( x );
583             return iterator( c_.erase( x.base() ) );
584         }
585 
erase(iterator first,iterator last)586         iterator erase( iterator first, iterator last ) // nothrow
587         {
588             remove( first, last );
589             return iterator( c_.erase( first.base(),
590                                        last.base() ) );
591         }
592 
593         template< class Range >
erase(const Range & r)594         iterator erase( const Range& r )
595         {
596             return erase( boost::begin(r), boost::end(r) );
597         }
598 
clear()599         void clear()
600         {
601             remove_all();
602             c_.clear();
603         }
604 
605     public: // access interface
606 
release(iterator where)607         auto_type release( iterator where )
608         {
609             BOOST_ASSERT( where != end() );
610 
611             BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
612                                                  "'release()' on empty container" );
613 
614             auto_type ptr( Config::get_pointer( where ) );  // nothrow
615             c_.erase( where.base() );                       // nothrow
616             return boost::ptr_container_detail::move( ptr );
617         }
618 
replace(iterator where,Ty_ * x)619         auto_type replace( iterator where, Ty_* x ) // strong
620         {
621             BOOST_ASSERT( where != end() );
622 
623             enforce_null_policy( x, "Null pointer in 'replace()'" );
624 
625             auto_type ptr( x );
626 
627             BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
628                                                  "'replace()' on empty container" );
629 
630             auto_type old( Config::get_pointer( where ) );  // nothrow
631             const_cast<void*&>(*where.base()) = ptr.release();
632             return boost::ptr_container_detail::move( old );
633         }
634 
635         template< class U >
replace(iterator where,std::auto_ptr<U> x)636         auto_type replace( iterator where, std::auto_ptr<U> x )
637         {
638             return replace( where, x.release() );
639         }
640 
replace(size_type idx,Ty_ * x)641         auto_type replace( size_type idx, Ty_* x ) // strong
642         {
643             enforce_null_policy( x, "Null pointer in 'replace()'" );
644 
645             auto_type ptr( x );
646 
647             BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= size(), bad_index,
648                                                  "'replace()' out of bounds" );
649 
650             auto_type old( static_cast<Ty_*>( c_[idx] ) ); // nothrow
651             c_[idx] = ptr.release();                       // nothrow, commit
652             return boost::ptr_container_detail::move( old );
653         }
654 
655         template< class U >
replace(size_type idx,std::auto_ptr<U> x)656         auto_type replace( size_type idx, std::auto_ptr<U> x )
657         {
658             return replace( idx, x.release() );
659         }
660 
661     }; // 'reversible_ptr_container'
662 
663 
664 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
665 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
666     typename base_type::auto_type                   \
667     release( typename base_type::iterator i )       \
668     {                                               \
669         return boost::ptr_container_detail::move(base_type::release(i)); \
670     }
671 #else
672 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
673     using base_type::release;
674 #endif
675 
676     //
677     // two-phase lookup of template functions
678     // is buggy on most compilers, so we use a macro instead
679     //
680 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) \
681     explicit PC( std::auto_ptr<this_type> r )       \
682     : base_type ( r ) { }                           \
683                                                     \
684     PC& operator=( std::auto_ptr<this_type> r )     \
685     {                                               \
686         base_type::operator=( r );                  \
687         return *this;                               \
688     }                                               \
689                                                     \
690     std::auto_ptr<this_type> release()              \
691     {                                               \
692       std::auto_ptr<this_type> ptr( new this_type );\
693       this->swap( *ptr );                           \
694       return ptr;                                   \
695     }                                               \
696     BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
697                                                     \
698     std::auto_ptr<this_type> clone() const          \
699     {                                               \
700        return std::auto_ptr<this_type>( new this_type( this->begin(), this->end() ) ); \
701     }
702 
703 #define BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type ) \
704                                                                       \
705     template< class U >                                               \
706     PC( const PC<U>& r ) : base_type( r ) { }                         \
707                                                                       \
708     PC& operator=( PC r )                                             \
709     {                                                                 \
710         this->swap( r );                                              \
711         return *this;                                                 \
712     }                                                                 \
713 
714 
715 #define BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type )                       \
716     typedef BOOST_DEDUCED_TYPENAME base_type::iterator        iterator;                \
717     typedef BOOST_DEDUCED_TYPENAME base_type::size_type       size_type;               \
718     typedef BOOST_DEDUCED_TYPENAME base_type::const_reference const_reference;         \
719     typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type  allocator_type;          \
720     PC() {}                                                                            \
721     explicit PC( const allocator_type& a ) : base_type(a) {}                           \
722     template< class InputIterator >                                                    \
723     PC( InputIterator first, InputIterator last ) : base_type( first, last ) {}        \
724     template< class InputIterator >                                                    \
725     PC( InputIterator first, InputIterator last,                                       \
726         const allocator_type& a ) : base_type( first, last, a ) {}
727 
728 #define BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type )           \
729    BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type )                                    \
730    BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type )
731 
732 #define BOOST_PTR_CONTAINER_DEFINE_SEQEUENCE_MEMBERS( PC, base_type, this_type )  \
733     BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type )  \
734     BOOST_PTR_CONTAINER_DEFINE_COPY_CONSTRUCTORS( PC, base_type )
735 
736 } // namespace 'ptr_container_detail'
737 
738     //
739     // @remark: expose movability of internal move-pointer
740     //
741     namespace ptr_container
742     {
743         using ptr_container_detail::move;
744     }
745 
746 } // namespace 'boost'
747 
748 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
749 #pragma warning(pop)
750 #endif
751 
752 #endif
753