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