Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:36

0001 //
0002 // Boost.Pointer Container
0003 //
0004 //  Copyright Thorsten Ottosen 2003-2005. Use, modification and
0005 //  distribution is subject to the Boost Software License, Version
0006 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // For more information, see http://www.boost.org/libs/ptr_container/
0010 //
0011 
0012 #ifndef BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
0013 #define BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
0014 
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018 
0019 #include <boost/ptr_container/detail/map_iterator.hpp>
0020 #include <boost/ptr_container/detail/associative_ptr_container.hpp>
0021 #include <boost/ptr_container/detail/meta_functions.hpp>
0022 #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
0023 #include <boost/static_assert.hpp>
0024 #include <boost/range/iterator_range.hpp>
0025 
0026 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0027 #pragma GCC diagnostic push
0028 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0029 #endif
0030 
0031 namespace boost
0032 {
0033 namespace ptr_container_detail
0034 {
0035 
0036     template
0037     <
0038         class T,
0039         class VoidPtrMap,
0040         bool  Ordered
0041     >
0042     struct map_config
0043     {
0044         typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
0045                      U;
0046         typedef VoidPtrMap
0047                      void_container_type;
0048 
0049         typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
0050                      allocator_type;
0051 
0052        typedef BOOST_DEDUCED_TYPENAME
0053            mpl::eval_if_c<Ordered,
0054                           select_value_compare<VoidPtrMap>,
0055                           mpl::identity<void> >::type
0056                     value_compare;
0057 
0058        typedef BOOST_DEDUCED_TYPENAME
0059            mpl::eval_if_c<Ordered,
0060                           select_key_compare<VoidPtrMap>,
0061                           mpl::identity<void> >::type
0062                     key_compare;
0063 
0064        typedef BOOST_DEDUCED_TYPENAME
0065            mpl::eval_if_c<Ordered,
0066                           mpl::identity<void>,
0067                           select_hasher<VoidPtrMap> >::type
0068                     hasher;
0069 
0070        typedef BOOST_DEDUCED_TYPENAME
0071            mpl::eval_if_c<Ordered,
0072                           mpl::identity<void>,
0073                           select_key_equal<VoidPtrMap> >::type
0074                     key_equal;
0075 
0076        typedef BOOST_DEDUCED_TYPENAME
0077            mpl::if_c<Ordered,
0078                      ptr_container_detail::ordered_associative_container_tag,
0079                      ptr_container_detail::unordered_associative_container_tag>::type
0080                     container_type;
0081 
0082         typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type
0083                      key_type;
0084 
0085         typedef U    value_type;
0086 
0087         typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const >
0088                      iterator;
0089 
0090         typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const>
0091                      const_iterator;
0092 
0093         typedef ptr_map_iterator<
0094            BOOST_DEDUCED_TYPENAME
0095              mpl::eval_if_c<Ordered,
0096                             select_iterator<VoidPtrMap>,
0097                             select_local_iterator<VoidPtrMap> >::type,
0098              key_type, U* const >
0099                     local_iterator;
0100 
0101        typedef ptr_map_iterator<
0102            BOOST_DEDUCED_TYPENAME
0103              mpl::eval_if_c<Ordered,
0104                             select_iterator<VoidPtrMap>,
0105                             select_const_local_iterator<VoidPtrMap> >::type,
0106              key_type, const U* const >
0107                     const_local_iterator;
0108 
0109         template< class Iter >
0110         static U* get_pointer( Iter i )
0111         {
0112             return i->second;
0113         }
0114 
0115         template< class Iter >
0116         static const U* get_const_pointer( Iter i )
0117         {
0118             return i->second;
0119         }
0120 
0121         BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value );
0122     };
0123 
0124 
0125 
0126     template
0127     <
0128         class T,
0129         class VoidPtrMap,
0130         class CloneAllocator,
0131         bool  Ordered
0132     >
0133     class ptr_map_adapter_base :
0134         public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
0135                                                     CloneAllocator >
0136     {
0137         typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
0138                                                      CloneAllocator >
0139             base_type;
0140 
0141         typedef map_config<T,VoidPtrMap,Ordered>                           config;
0142         typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>  this_type;
0143 
0144     public:
0145 
0146         typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
0147                     allocator_type;
0148         typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0149                     iterator;
0150         typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0151                     const_iterator;
0152         typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0153                     size_type;
0154         typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0155                     key_type;
0156         typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0157                     auto_type;
0158         typedef BOOST_DEDUCED_TYPENAME base_type::value_type
0159                     mapped_type;
0160         typedef BOOST_DEDUCED_TYPENAME base_type::reference
0161                     mapped_reference;
0162         typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0163                     const_mapped_reference;
0164         typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type
0165                     value_type;
0166         typedef value_type
0167                     reference;
0168         typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type
0169                     const_reference;
0170         typedef value_type
0171                     pointer;
0172         typedef const_reference
0173                     const_pointer;
0174 
0175     private:
0176         const_mapped_reference lookup( const key_type& key ) const
0177         {
0178            const_iterator i = this->find( key );
0179            BOOST_PTR_CONTAINER_THROW_EXCEPTION( i == this->end(), bad_ptr_container_operation,
0180                                                 "'ptr_map/multimap::at()' could"
0181                                                 " not find key" );
0182            return *i->second;
0183         }
0184 
0185         struct eraser // scope guard
0186         {
0187             bool            released_;
0188             VoidPtrMap*     m_;
0189             const key_type& key_;
0190 
0191             eraser( VoidPtrMap* m, const key_type& key )
0192               : released_(false), m_(m), key_(key)
0193             {}
0194 
0195             ~eraser()
0196             {
0197                 if( !released_ )
0198                     m_->erase(key_);
0199             }
0200 
0201             void release() { released_ = true; }
0202 
0203         private:
0204             eraser& operator=(const eraser&);
0205         };
0206 
0207         mapped_reference insert_lookup( const key_type& key )
0208         {
0209             void*& ref = this->base()[key];
0210             if( ref )
0211             {
0212                 return *static_cast<mapped_type>(ref);
0213             }
0214             else
0215             {
0216                 eraser e(&this->base(),key);      // nothrow
0217                 mapped_type res = new T();        // strong
0218                 ref = res;                        // nothrow
0219                 e.release();                      // nothrow
0220                 return *res;
0221             }
0222           }
0223 
0224     public:
0225 
0226         ptr_map_adapter_base()
0227         { }
0228 
0229         template< class SizeType >
0230         explicit ptr_map_adapter_base( SizeType n,
0231                                        ptr_container_detail::unordered_associative_container_tag tag )
0232         : base_type( n, tag )
0233         { }
0234 
0235         template< class Compare, class Allocator >
0236         ptr_map_adapter_base( const Compare& comp,
0237                               const Allocator& a )
0238         : base_type( comp, a )
0239         { }
0240 
0241         template< class Hash, class Pred, class Allocator >
0242         ptr_map_adapter_base( const Hash& hash,
0243                               const Pred& pred,
0244                               const Allocator& a )
0245          : base_type( hash, pred, a )
0246         { }
0247 
0248         template< class InputIterator >
0249         ptr_map_adapter_base( InputIterator first, InputIterator last )
0250          : base_type( first, last )
0251         { }
0252 
0253         template< class InputIterator, class Comp >
0254         ptr_map_adapter_base( InputIterator first, InputIterator last,
0255                               const Comp& comp,
0256                               const allocator_type& a = allocator_type() )
0257         : base_type( first, last, comp, a )
0258         { }
0259 
0260         template< class InputIterator, class Hash, class Pred, class Allocator >
0261         ptr_map_adapter_base( InputIterator first, InputIterator last,
0262                               const Hash& hash,
0263                               const Pred& pred,
0264                               const Allocator& a )
0265          : base_type( first, last, hash, pred, a )
0266         { }
0267 
0268 #ifndef BOOST_NO_AUTO_PTR
0269         template< class PtrContainer >
0270         explicit ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone )
0271         : base_type( clone )
0272         { }
0273 
0274         template< typename PtrContainer >
0275         ptr_map_adapter_base& operator=( std::auto_ptr<PtrContainer> clone )
0276         {
0277             base_type::operator=( clone );
0278             return *this;
0279         }
0280 #endif
0281 #ifndef BOOST_NO_CXX11_SMART_PTR
0282         template< class PtrContainer >
0283         explicit ptr_map_adapter_base( std::unique_ptr<PtrContainer> clone )
0284         : base_type( std::move( clone ) )
0285         { }
0286 
0287         template< typename PtrContainer >
0288         ptr_map_adapter_base& operator=( std::unique_ptr<PtrContainer> clone )
0289         {
0290             base_type::operator=( std::move( clone ) );
0291             return *this;
0292         }
0293 #endif
0294 
0295         iterator find( const key_type& x )
0296         {
0297             return iterator( this->base().find( x ) );
0298         }
0299 
0300         const_iterator find( const key_type& x ) const
0301         {
0302             return const_iterator( this->base().find( x ) );
0303         }
0304 
0305         size_type count( const key_type& x ) const
0306         {
0307             return this->base().count( x );
0308         }
0309 
0310         iterator lower_bound( const key_type& x )
0311         {
0312             return iterator( this->base().lower_bound( x ) );
0313         }
0314 
0315         const_iterator lower_bound( const key_type& x ) const
0316         {
0317             return const_iterator( this->base().lower_bound( x ) );
0318         }
0319 
0320         iterator upper_bound( const key_type& x )
0321         {
0322             return iterator( this->base().upper_bound( x ) );
0323         }
0324 
0325         const_iterator upper_bound( const key_type& x ) const
0326         {
0327             return const_iterator( this->base().upper_bound( x ) );
0328         }
0329 
0330         iterator_range<iterator> equal_range( const key_type& x )
0331         {
0332             std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
0333                       BOOST_DEDUCED_TYPENAME base_type::ptr_iterator>
0334                  p = this->base().equal_range( x );
0335             return make_iterator_range( iterator( p.first ), iterator( p.second ) );
0336         }
0337 
0338         iterator_range<const_iterator> equal_range( const key_type& x ) const
0339         {
0340             std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
0341                       BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator>
0342                 p = this->base().equal_range( x );
0343             return make_iterator_range( const_iterator( p.first ),
0344                                         const_iterator( p.second ) );
0345         }
0346 
0347         mapped_reference at( const key_type& key )
0348         {
0349             return const_cast<mapped_reference>( lookup( key ) );
0350         }
0351 
0352         const_mapped_reference at( const key_type& key ) const
0353         {
0354             return lookup( key );
0355         }
0356 
0357         mapped_reference operator[]( const key_type& key )
0358         {
0359             return insert_lookup( key );
0360         }
0361 
0362         auto_type replace( iterator where, mapped_type x ) // strong
0363         {
0364             BOOST_ASSERT( where != this->end() );
0365             this->enforce_null_policy( x, "Null pointer in 'replace()'" );
0366 
0367             auto_type ptr( x, *this );
0368             BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(),
0369                                                  bad_ptr_container_operation,
0370                                                  "'replace()' on empty container" );
0371 
0372             auto_type old( where->second, *this ); // nothrow
0373             where.base()->second = ptr.release();  // nothrow, commit
0374             return boost::ptr_container::move( old );
0375         }
0376 
0377 #ifndef BOOST_NO_AUTO_PTR
0378         template< class U >
0379         auto_type replace( iterator where, std::auto_ptr<U> x )
0380         {
0381             return replace( where, x.release() );
0382         }
0383 #endif
0384 #ifndef BOOST_NO_CXX11_SMART_PTR
0385         template< class U >
0386         auto_type replace( iterator where, std::unique_ptr<U> x )
0387         {
0388             return replace( where, x.release() );
0389         }
0390 #endif
0391 
0392     protected:
0393         size_type bucket( const key_type& key ) const
0394         {
0395             return this->base().bucket( key );
0396         }
0397     };
0398 
0399 } // ptr_container_detail
0400 
0401     /////////////////////////////////////////////////////////////////////////
0402     // ptr_map_adapter
0403     /////////////////////////////////////////////////////////////////////////
0404 
0405     template
0406     <
0407         class T,
0408         class VoidPtrMap,
0409         class CloneAllocator = heap_clone_allocator,
0410         bool  Ordered        = true
0411     >
0412     class ptr_map_adapter :
0413         public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
0414     {
0415         typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
0416             base_type;
0417 
0418     public:
0419         typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0420                      iterator;
0421         typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0422                      const_iterator;
0423         typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0424                     size_type;
0425         typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0426                     key_type;
0427         typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0428                     const_reference;
0429         typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0430                     auto_type;
0431         typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
0432                     allocator_type;
0433         typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
0434                     mapped_type;
0435     private:
0436 
0437         void safe_insert( const key_type& key, auto_type ptr ) // strong
0438         {
0439             std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
0440                 res =
0441                 this->base().insert( std::make_pair( key, ptr.get() ) ); // strong, commit
0442             if( res.second )                                             // nothrow
0443                 ptr.release();                                           // nothrow
0444         }
0445 
0446         template< class II >
0447         void map_basic_clone_and_insert( II first, II last )
0448         {
0449             while( first != last )
0450             {
0451                 if( this->find( first->first ) == this->end() )
0452                 {
0453                     const_reference p = *first.base();     // nothrow
0454                     auto_type ptr( this->null_policy_allocate_clone(p.second), *this );
0455                                                            // strong
0456                     this->safe_insert( p.first,
0457                                        boost::ptr_container::move( ptr ) );
0458                                                            // strong, commit
0459                 }
0460                 ++first;
0461             }
0462         }
0463 
0464     public:
0465         ptr_map_adapter( )
0466         { }
0467 
0468         template< class Comp >
0469         explicit ptr_map_adapter( const Comp& comp,
0470                                   const allocator_type& a )
0471           : base_type( comp, a ) { }
0472 
0473         template< class SizeType >
0474         explicit ptr_map_adapter( SizeType n,
0475             ptr_container_detail::unordered_associative_container_tag tag )
0476           : base_type( n, tag ) { }
0477 
0478         template< class Hash, class Pred, class Allocator >
0479         ptr_map_adapter( const Hash& hash,
0480                          const Pred& pred,
0481                          const Allocator& a )
0482          : base_type( hash, pred, a )
0483         { }
0484 
0485         template< class InputIterator >
0486         ptr_map_adapter( InputIterator first, InputIterator last )
0487         {
0488             map_basic_clone_and_insert( first, last );
0489         }
0490 
0491         template< class InputIterator, class Comp >
0492         ptr_map_adapter( InputIterator first, InputIterator last,
0493                          const Comp& comp,
0494                          const allocator_type& a = allocator_type() )
0495           : base_type( comp, a )
0496         {
0497             map_basic_clone_and_insert( first, last );
0498         }
0499 
0500         template< class InputIterator, class Hash, class Pred, class Allocator >
0501         ptr_map_adapter( InputIterator first, InputIterator last,
0502                          const Hash& hash,
0503                          const Pred& pred,
0504                          const Allocator& a )
0505           : base_type( hash, pred, a )
0506         {
0507             map_basic_clone_and_insert( first, last );
0508         }
0509 
0510         ptr_map_adapter( const ptr_map_adapter& r )
0511         {
0512             map_basic_clone_and_insert( r.begin(), r.end() );
0513         }
0514 
0515         template< class Key, class U, class CA, bool b >
0516         ptr_map_adapter( const ptr_map_adapter<Key,U,CA,b>& r )
0517         {
0518             map_basic_clone_and_insert( r.begin(), r.end() );
0519         }
0520 
0521 #ifndef BOOST_NO_AUTO_PTR
0522         template< class U >
0523         ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r )
0524         { }
0525 #endif
0526 #ifndef BOOST_NO_CXX11_SMART_PTR
0527         template< class U >
0528         ptr_map_adapter( std::unique_ptr<U> r ) : base_type( std::move( r ) )
0529         { }
0530 #endif
0531 
0532         ptr_map_adapter& operator=( ptr_map_adapter r )
0533         {
0534             this->swap( r );
0535             return *this;
0536         }
0537 
0538 #ifndef BOOST_NO_AUTO_PTR
0539         template< class U >
0540         ptr_map_adapter& operator=( std::auto_ptr<U> r )
0541         {
0542             base_type::operator=( r );
0543             return *this;
0544         }
0545 #endif
0546 #ifndef BOOST_NO_CXX11_SMART_PTR
0547         template< class U >
0548         ptr_map_adapter& operator=( std::unique_ptr<U> r )
0549         {
0550             base_type::operator=( std::move( r ) );
0551             return *this;
0552         }
0553 #endif
0554 
0555         using base_type::release;
0556 
0557         template< typename InputIterator >
0558         void insert( InputIterator first, InputIterator last ) // basic
0559         {
0560             map_basic_clone_and_insert( first, last );
0561         }
0562 
0563         template< class Range >
0564         void insert( const Range& r )
0565         {
0566             insert( boost::begin(r), boost::end(r) );
0567         }
0568 
0569     private:
0570         std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong
0571         {
0572             this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" );
0573 
0574             auto_type ptr( x, *this );                                  // nothrow
0575             std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
0576                  res = this->base().insert( std::make_pair( key, x ) ); // strong, commit
0577             if( res.second )                                            // nothrow
0578                 ptr.release();                                          // nothrow
0579             return std::make_pair( iterator( res.first ), res.second ); // nothrow
0580         }
0581 
0582         iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong
0583         {
0584             this->enforce_null_policy( x,
0585                   "Null pointer in 'ptr_map_adapter::insert()'" );
0586 
0587             auto_type ptr( x, *this );  // nothrow
0588             BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0589                 res = this->base().insert( before.base(), std::make_pair( key, x ) );
0590                                         // strong, commit
0591             ptr.release();              // notrow
0592             return iterator( res );
0593         }
0594 
0595     public:
0596 
0597         std::pair<iterator,bool> insert( key_type& key, mapped_type x )
0598         {
0599             return insert_impl( key, x );
0600         }
0601 
0602 #ifndef BOOST_NO_AUTO_PTR
0603         template< class U >
0604         std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x )
0605         {
0606             return insert_impl( key, x.release() );
0607         }
0608 #endif
0609 #ifndef BOOST_NO_CXX11_SMART_PTR
0610         template< class U >
0611         std::pair<iterator,bool> insert( const key_type& key, std::unique_ptr<U> x )
0612         {
0613             return insert_impl( key, x.release() );
0614         }
0615 #endif
0616 
0617         template< class F, class S >
0618         iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong
0619         {
0620             this->enforce_null_policy( p.second,
0621                   "Null pointer in 'ptr_map_adapter::insert()'" );
0622 
0623             auto_type ptr( this->null_policy_allocate_clone(p.second), *this );
0624             BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0625                 result = this->base().insert( before.base(),
0626                                      std::make_pair(p.first,ptr.get()) ); // strong
0627             if( ptr.get() == result->second )
0628                 ptr.release();
0629 
0630             return iterator( result );
0631         }
0632 
0633         iterator insert( iterator before, key_type& key, mapped_type x ) // strong
0634         {
0635             return insert_impl( before, key, x );
0636         }
0637 
0638 #ifndef BOOST_NO_AUTO_PTR
0639         template< class U >
0640         iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong
0641         {
0642             return insert_impl( before, key, x.release() );
0643         }
0644 #endif
0645 #ifndef BOOST_NO_CXX11_SMART_PTR
0646         template< class U >
0647         iterator insert( iterator before, const key_type& key, std::unique_ptr<U> x ) // strong
0648         {
0649             return insert_impl( before, key, x.release() );
0650         }
0651 #endif
0652 
0653         template< class PtrMapAdapter >
0654         bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
0655                        PtrMapAdapter& from ) // strong
0656         {
0657             return this->single_transfer( object, from );
0658         }
0659 
0660         template< class PtrMapAdapter >
0661         size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
0662                             BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
0663                             PtrMapAdapter& from ) // basic
0664         {
0665             return this->single_transfer( first, last, from );
0666         }
0667 
0668 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0669 #else
0670 
0671         template< class PtrMapAdapter, class Range >
0672         BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0673                             BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
0674                                                             size_type >::type
0675         transfer( const Range& r, PtrMapAdapter& from ) // basic
0676         {
0677             return transfer( boost::begin(r), boost::end(r), from );
0678         }
0679 
0680 #endif
0681 
0682         template< class PtrMapAdapter >
0683         size_type transfer( PtrMapAdapter& from ) // basic
0684         {
0685             return transfer( from.begin(), from.end(), from );
0686         }
0687   };
0688 
0689   /////////////////////////////////////////////////////////////////////////
0690   // ptr_multimap_adapter
0691   /////////////////////////////////////////////////////////////////////////
0692 
0693     template
0694     <
0695         class T,
0696         class VoidPtrMultiMap,
0697         class CloneAllocator = heap_clone_allocator,
0698         bool  Ordered        = true
0699     >
0700     class ptr_multimap_adapter :
0701         public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
0702     {
0703         typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
0704              base_type;
0705 
0706     public: // typedefs
0707         typedef BOOST_DEDUCED_TYPENAME base_type::iterator
0708                        iterator;
0709         typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
0710                        const_iterator;
0711         typedef BOOST_DEDUCED_TYPENAME base_type::size_type
0712                        size_type;
0713         typedef BOOST_DEDUCED_TYPENAME base_type::key_type
0714                        key_type;
0715         typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
0716                        const_reference;
0717         typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
0718                     mapped_type;
0719         typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
0720                     auto_type;
0721         typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type
0722                     allocator_type;
0723     private:
0724 
0725         void safe_insert( const key_type& key, auto_type ptr ) // strong
0726         {
0727             this->base().insert(
0728                            std::make_pair( key, ptr.get() ) ); // strong, commit
0729             ptr.release();                                     // nothrow
0730         }
0731 
0732         template< typename II >
0733         void map_basic_clone_and_insert( II first, II last )
0734         {
0735             while( first != last )
0736             {
0737                 const_reference pair = *first.base();     // nothrow
0738                 auto_type ptr( this->null_policy_allocate_clone(pair.second), *this );
0739                                                           // strong
0740                 safe_insert( pair.first,
0741                              boost::ptr_container::move( ptr ) );
0742                                                           // strong, commit
0743                 ++first;
0744             }
0745         }
0746 
0747     public:
0748 
0749         ptr_multimap_adapter()
0750         { }
0751 
0752         template< class SizeType >
0753         ptr_multimap_adapter( SizeType n,
0754                               ptr_container_detail::unordered_associative_container_tag tag )
0755           : base_type( n, tag )
0756         { }
0757 
0758         template< class Comp >
0759         explicit ptr_multimap_adapter( const Comp& comp,
0760                                        const allocator_type& a )
0761           : base_type( comp, a ) { }
0762 
0763         template< class Hash, class Pred, class Allocator >
0764         ptr_multimap_adapter( const Hash& hash,
0765                               const Pred& pred,
0766                               const Allocator& a )
0767          : base_type( hash, pred, a )
0768         { }
0769 
0770         template< class InputIterator >
0771         ptr_multimap_adapter( InputIterator first, InputIterator last )
0772         {
0773             map_basic_clone_and_insert( first, last );
0774         }
0775 
0776         template< class InputIterator, class Comp >
0777         ptr_multimap_adapter( InputIterator first, InputIterator last,
0778                               const Comp& comp,
0779                               const allocator_type& a )
0780           : base_type( comp, a )
0781         {
0782             map_basic_clone_and_insert( first, last );
0783         }
0784 
0785         template< class InputIterator, class Hash, class Pred, class Allocator >
0786         ptr_multimap_adapter( InputIterator first, InputIterator last,
0787                               const Hash& hash,
0788                               const Pred& pred,
0789                               const Allocator& a )
0790          : base_type( hash, pred, a )
0791         {
0792             map_basic_clone_and_insert( first, last );
0793         }
0794 
0795         ptr_multimap_adapter( const ptr_multimap_adapter& r )
0796         {
0797             map_basic_clone_and_insert( r.begin(), r.end() );
0798         }
0799 
0800         template< class Key, class U, class CA, bool b >
0801         ptr_multimap_adapter( const ptr_multimap_adapter<Key,U,CA,b>& r )
0802         {
0803             map_basic_clone_and_insert( r.begin(), r.end() );
0804         }
0805 
0806 #ifndef BOOST_NO_AUTO_PTR
0807         template< class U >
0808         explicit ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r )
0809         { }
0810 #endif
0811 #ifndef BOOST_NO_CXX11_SMART_PTR
0812         template< class U >
0813         explicit ptr_multimap_adapter( std::unique_ptr<U> r ) : base_type( std::move( r ) )
0814         { }
0815 #endif
0816 
0817         ptr_multimap_adapter& operator=( ptr_multimap_adapter r )
0818         {
0819             this->swap( r );
0820             return *this;
0821         }
0822 
0823 #ifndef BOOST_NO_AUTO_PTR
0824         template< class U >
0825         ptr_multimap_adapter& operator=( std::auto_ptr<U> r )
0826         {
0827             base_type::operator=( r );
0828             return *this;
0829         }
0830 #endif
0831 #ifndef BOOST_NO_CXX11_SMART_PTR
0832         template< class U >
0833         ptr_multimap_adapter& operator=( std::unique_ptr<U> r )
0834         {
0835             base_type::operator=( std::move( r ) );
0836             return *this;
0837         }
0838 #endif
0839 
0840         using base_type::release;
0841 
0842     private:
0843         iterator insert_impl( const key_type& key, mapped_type x ) // strong
0844         {
0845             this->enforce_null_policy( x,
0846                   "Null pointer in 'ptr_multimap_adapter::insert()'" );
0847 
0848             auto_type ptr( x, *this );  // nothrow
0849             BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0850                 res = this->base().insert( std::make_pair( key, x ) );
0851                                         // strong, commit
0852             ptr.release();              // notrow
0853             return iterator( res );
0854         }
0855 
0856         iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong
0857         {
0858             this->enforce_null_policy( x,
0859                   "Null pointer in 'ptr_multimap_adapter::insert()'" );
0860 
0861             auto_type ptr( x, *this );  // nothrow
0862             BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
0863                 res = this->base().insert( before.base(),
0864                                            std::make_pair( key, x ) );
0865                                         // strong, commit
0866             ptr.release();              // notrow
0867             return iterator( res );
0868         }
0869 
0870     public:
0871         template< typename InputIterator >
0872         void insert( InputIterator first, InputIterator last ) // basic
0873         {
0874             map_basic_clone_and_insert( first, last );
0875         }
0876 
0877         template< class Range >
0878         void insert( const Range& r )
0879         {
0880             insert( boost::begin(r), boost::end(r) );
0881         }
0882 
0883         iterator insert( key_type& key, mapped_type x ) // strong
0884         {
0885             return insert_impl( key, x );
0886         }
0887 
0888 #ifndef BOOST_NO_AUTO_PTR
0889         template< class U >
0890         iterator insert( const key_type& key, std::auto_ptr<U> x )
0891         {
0892             return insert_impl( key, x.release() );
0893         }
0894 #endif
0895 #ifndef BOOST_NO_CXX11_SMART_PTR
0896         template< class U >
0897         iterator insert( const key_type& key, std::unique_ptr<U> x )
0898         {
0899             return insert_impl( key, x.release() );
0900         }
0901 #endif
0902 
0903         template< class F, class S >
0904         iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong
0905         {
0906             this->enforce_null_policy( p.second,
0907                   "Null pointer in 'ptr_multimap_adapter::insert()'" );
0908             iterator res = insert_impl( before, p.first,
0909                                         this->null_policy_allocate_clone( p.second ) );
0910             return res;
0911         }
0912 
0913         iterator insert( iterator before, key_type& key, mapped_type x ) // strong
0914         {
0915             return insert_impl( before, key, x );
0916         }
0917 
0918 #ifndef BOOST_NO_AUTO_PTR
0919         template< class U >
0920         iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong
0921         {
0922             return insert_impl( before, key, x.release() );
0923         }
0924 #endif
0925 #ifndef BOOST_NO_CXX11_SMART_PTR
0926         template< class U >
0927         iterator insert( iterator before, const key_type& key, std::unique_ptr<U> x ) // strong
0928         {
0929             return insert_impl( before, key, x.release() );
0930         }
0931 #endif
0932 
0933         template< class PtrMapAdapter >
0934         void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
0935                        PtrMapAdapter& from ) // strong
0936         {
0937             this->multi_transfer( object, from );
0938         }
0939 
0940         template< class PtrMapAdapter >
0941         size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
0942                             BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
0943                             PtrMapAdapter& from ) // basic
0944         {
0945             return this->multi_transfer( first, last, from );
0946         }
0947 
0948 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0949 #else
0950 
0951         template<  class PtrMapAdapter, class Range >
0952         BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0953                             BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
0954                                                             size_type >::type
0955         transfer( const Range& r, PtrMapAdapter& from ) // basic
0956         {
0957             return transfer( boost::begin(r), boost::end(r), from );
0958         }
0959 
0960 #endif
0961         template< class PtrMapAdapter >
0962         void transfer( PtrMapAdapter& from ) // basic
0963         {
0964             transfer( from.begin(), from.end(), from );
0965             BOOST_ASSERT( from.empty() );
0966         }
0967 
0968     };
0969 
0970     template< class I, class F, class S >
0971     inline bool is_null( const ptr_map_iterator<I,F,S>& i )
0972     {
0973         return i->second == 0;
0974     }
0975 
0976 } // namespace 'boost'
0977 
0978 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0979 #pragma GCC diagnostic pop
0980 #endif
0981 
0982 #endif