epoc32/include/stdapis/boost/ptr_container/ptr_map_adapter.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@2
     1
//
williamr@2
     2
// Boost.Pointer Container
williamr@2
     3
//
williamr@2
     4
//  Copyright Thorsten Ottosen 2003-2005. Use, modification and
williamr@2
     5
//  distribution is subject to the Boost Software License, Version
williamr@2
     6
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     7
//  http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     8
//
williamr@2
     9
// For more information, see http://www.boost.org/libs/ptr_container/
williamr@2
    10
//
williamr@2
    11
williamr@2
    12
#ifndef BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
williamr@2
    13
#define BOOST_PTR_CONTAINER_DETAIL_PTR_MAP_ADAPTER_HPP
williamr@2
    14
williamr@2
    15
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
williamr@2
    16
# pragma once
williamr@2
    17
#endif
williamr@2
    18
williamr@2
    19
#include <boost/ptr_container/detail/map_iterator.hpp>
williamr@2
    20
#include <boost/ptr_container/detail/associative_ptr_container.hpp>
williamr@2
    21
#include <boost/static_assert.hpp>
williamr@2
    22
#include <boost/range/iterator_range.hpp>
williamr@2
    23
williamr@2
    24
namespace boost
williamr@2
    25
{
williamr@2
    26
namespace ptr_container_detail
williamr@2
    27
{
williamr@2
    28
williamr@2
    29
    template
williamr@2
    30
    < 
williamr@2
    31
        class T,
williamr@2
    32
        class VoidPtrMap
williamr@2
    33
    >
williamr@2
    34
    struct map_config
williamr@2
    35
    {
williamr@2
    36
        typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
williamr@2
    37
                     U;
williamr@2
    38
        typedef VoidPtrMap 
williamr@2
    39
                     void_container_type;
williamr@2
    40
        
williamr@2
    41
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
williamr@2
    42
                     allocator_type;
williamr@2
    43
        
williamr@2
    44
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_compare
williamr@2
    45
                     key_compare;
williamr@2
    46
        
williamr@2
    47
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::value_compare
williamr@2
    48
                     value_compare;
williamr@2
    49
        
williamr@2
    50
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type
williamr@2
    51
                     key_type;
williamr@2
    52
        
williamr@2
    53
        typedef U    value_type;
williamr@2
    54
williamr@2
    55
        typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const >
williamr@2
    56
                     iterator;
williamr@2
    57
        
williamr@2
    58
        typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const>
williamr@2
    59
                     const_iterator;
williamr@2
    60
  
williamr@2
    61
        template< class Iter >
williamr@2
    62
        static U* get_pointer( Iter i )
williamr@2
    63
        {
williamr@2
    64
            return i->second;
williamr@2
    65
        }
williamr@2
    66
williamr@2
    67
        template< class Iter >
williamr@2
    68
        static const U* get_const_pointer( Iter i )
williamr@2
    69
        {
williamr@2
    70
            return i->second;
williamr@2
    71
        }
williamr@2
    72
williamr@2
    73
        BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value );
williamr@2
    74
    };
williamr@2
    75
    
williamr@2
    76
    
williamr@2
    77
williamr@2
    78
    template
williamr@2
    79
    < 
williamr@2
    80
        class T,
williamr@2
    81
        class VoidPtrMap, 
williamr@2
    82
        class CloneAllocator
williamr@2
    83
    >
williamr@2
    84
    class ptr_map_adapter_base : 
williamr@2
    85
        public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap>,
williamr@2
    86
                                                    CloneAllocator >
williamr@2
    87
    {
williamr@2
    88
        typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap>,
williamr@2
    89
                                                     CloneAllocator > 
williamr@2
    90
            base_type;
williamr@2
    91
williamr@2
    92
        typedef map_config<T,VoidPtrMap>                           config;
williamr@2
    93
williamr@2
    94
        typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator>  this_type;
williamr@2
    95
        
williamr@2
    96
    public:
williamr@2
    97
williamr@2
    98
        typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
williamr@2
    99
                    allocator_type;
williamr@2
   100
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator
williamr@2
   101
                    iterator;
williamr@2
   102
        typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
williamr@2
   103
                    const_iterator;
williamr@2
   104
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
williamr@2
   105
                    size_type;
williamr@2
   106
        typedef BOOST_DEDUCED_TYPENAME base_type::key_type
williamr@2
   107
                    key_type;
williamr@2
   108
        typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
williamr@2
   109
                    auto_type;
williamr@2
   110
        typedef BOOST_DEDUCED_TYPENAME base_type::value_type 
williamr@2
   111
                    mapped_type;
williamr@2
   112
        typedef BOOST_DEDUCED_TYPENAME base_type::reference
williamr@2
   113
                    mapped_reference;
williamr@2
   114
        typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
williamr@2
   115
                    const_mapped_reference;
williamr@2
   116
        typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type
williamr@2
   117
                    value_type;
williamr@2
   118
        typedef value_type
williamr@2
   119
                    reference;
williamr@2
   120
        typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type
williamr@2
   121
                    const_reference;
williamr@2
   122
        typedef value_type 
williamr@2
   123
                    pointer;
williamr@2
   124
        typedef const_reference 
williamr@2
   125
                    const_pointer;
williamr@2
   126
williamr@2
   127
    private:
williamr@2
   128
        const_mapped_reference lookup( const key_type& key ) const
williamr@2
   129
        {
williamr@2
   130
           const_iterator i = this->find( key );
williamr@2
   131
           if( i != this->end() )
williamr@2
   132
               return *i->second;
williamr@2
   133
           else                                           
williamr@2
   134
               BOOST_PTR_CONTAINER_THROW_EXCEPTION( true, bad_ptr_container_operation,
williamr@2
   135
                                                    "'ptr_map/multimap::at()' could"
williamr@2
   136
                                                    " not find key" );
williamr@2
   137
        }
williamr@2
   138
williamr@2
   139
        struct eraser // scope guard
williamr@2
   140
        {
williamr@2
   141
            bool            released_;
williamr@2
   142
            VoidPtrMap*     m_;
williamr@2
   143
            const key_type& key_;
williamr@2
   144
williamr@2
   145
            eraser( VoidPtrMap* m, const key_type& key ) 
williamr@2
   146
              : released_(false), m_(m), key_(key)
williamr@2
   147
            {}
williamr@2
   148
williamr@2
   149
            ~eraser() 
williamr@2
   150
            {
williamr@2
   151
                if( !released_ )
williamr@2
   152
                    m_->erase(key_);
williamr@2
   153
            }
williamr@2
   154
williamr@2
   155
            void release() { released_ = true; }
williamr@2
   156
        };
williamr@2
   157
williamr@2
   158
        mapped_reference insert_lookup( const key_type& key )
williamr@2
   159
        {
williamr@2
   160
            void*& ref = this->c_private()[key];
williamr@2
   161
            if( ref )
williamr@2
   162
            {
williamr@2
   163
                return *static_cast<mapped_type>(ref);
williamr@2
   164
            }
williamr@2
   165
            else
williamr@2
   166
            {
williamr@2
   167
                eraser e(&this->c_private(),key); // nothrow
williamr@2
   168
                mapped_type res = new T();        // strong 
williamr@2
   169
                ref = res;                        // nothrow
williamr@2
   170
                e.release();                      // nothrow
williamr@2
   171
                return *res;
williamr@2
   172
            }
williamr@2
   173
          }
williamr@2
   174
        
williamr@2
   175
    public:
williamr@2
   176
williamr@2
   177
        ptr_map_adapter_base( const allocator_type& a = allocator_type() )
williamr@2
   178
        : base_type(a)
williamr@2
   179
        { }
williamr@2
   180
williamr@2
   181
        template< class InputIterator >
williamr@2
   182
        ptr_map_adapter_base( InputIterator first, InputIterator last,
williamr@2
   183
                              const allocator_type& a = allocator_type() )
williamr@2
   184
        : base_type( first, last, a )
williamr@2
   185
        { }
williamr@2
   186
 
williamr@2
   187
        template< class Compare, class Allocator >
williamr@2
   188
        explicit ptr_map_adapter_base( const Compare& comp,
williamr@2
   189
                                       const Allocator& a ) 
williamr@2
   190
        : base_type( comp, a ) 
williamr@2
   191
        { }
williamr@2
   192
williamr@2
   193
        template< class PtrContainer >
williamr@2
   194
        ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone ) 
williamr@2
   195
        : base_type( clone )
williamr@2
   196
        { }
williamr@2
   197
        
williamr@2
   198
        template< typename PtrContainer >
williamr@2
   199
        void operator=( std::auto_ptr<PtrContainer> clone )    
williamr@2
   200
        {
williamr@2
   201
            base_type::operator=( clone );
williamr@2
   202
        }        
williamr@2
   203
williamr@2
   204
        iterator find( const key_type& x )                                                
williamr@2
   205
        {                                                                            
williamr@2
   206
            return iterator( this->c_private().find( x ) );                                
williamr@2
   207
        }                                                                            
williamr@2
   208
williamr@2
   209
        const_iterator find( const key_type& x ) const                                    
williamr@2
   210
        {                                                                            
williamr@2
   211
            return const_iterator( this->c_private().find( x ) );                          
williamr@2
   212
        }                                                                            
williamr@2
   213
williamr@2
   214
        size_type count( const key_type& x ) const                                        
williamr@2
   215
        {                                                                            
williamr@2
   216
            return this->c_private().count( x );                                           
williamr@2
   217
        }                                                                            
williamr@2
   218
                                                                                     
williamr@2
   219
        iterator lower_bound( const key_type& x )                                         
williamr@2
   220
        {                                                                            
williamr@2
   221
            return iterator( this->c_private().lower_bound( x ) );                         
williamr@2
   222
        }                                                                            
williamr@2
   223
                                                                                     
williamr@2
   224
        const_iterator lower_bound( const key_type& x ) const                             
williamr@2
   225
        {                                                                            
williamr@2
   226
            return const_iterator( this->c_private().lower_bound( x ) );                   
williamr@2
   227
        }                                                                            
williamr@2
   228
                                                                                     
williamr@2
   229
        iterator upper_bound( const key_type& x )                                         
williamr@2
   230
        {                                                                            
williamr@2
   231
            return iterator( this->c_private().upper_bound( x ) );                         
williamr@2
   232
        }                                                                            
williamr@2
   233
                                                                                     
williamr@2
   234
        const_iterator upper_bound( const key_type& x ) const                             
williamr@2
   235
        {                                                                            
williamr@2
   236
            return const_iterator( this->c_private().upper_bound( x ) );                   
williamr@2
   237
        }                                                                            
williamr@2
   238
                                                                                     
williamr@2
   239
        iterator_range<iterator> equal_range( const key_type& x )                    
williamr@2
   240
        {                                                                            
williamr@2
   241
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
williamr@2
   242
                      BOOST_DEDUCED_TYPENAME base_type::ptr_iterator>
williamr@2
   243
                 p = this->c_private().equal_range( x );   
williamr@2
   244
            return make_iterator_range( iterator( p.first ), iterator( p.second ) );      
williamr@2
   245
        }                                                                            
williamr@2
   246
                                                                                     
williamr@2
   247
        iterator_range<const_iterator> equal_range( const key_type& x ) const  
williamr@2
   248
        {                                                                            
williamr@2
   249
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
williamr@2
   250
                      BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator> 
williamr@2
   251
                p = this->c_private().equal_range( x ); 
williamr@2
   252
            return make_iterator_range( const_iterator( p.first ), 
williamr@2
   253
                                        const_iterator( p.second ) );    
williamr@2
   254
        }                                                                            
williamr@2
   255
                                                                                     
williamr@2
   256
        mapped_reference at( const key_type& key )  
williamr@2
   257
        {   
williamr@2
   258
            return const_cast<mapped_reference>( lookup( key ) ); 
williamr@2
   259
        }
williamr@2
   260
                                                                                     
williamr@2
   261
        const_mapped_reference at( const key_type& key ) const
williamr@2
   262
        {                                                                            
williamr@2
   263
            return lookup( key );
williamr@2
   264
        }
williamr@2
   265
williamr@2
   266
        mapped_reference operator[]( const key_type& key )
williamr@2
   267
        {
williamr@2
   268
            return insert_lookup( key );
williamr@2
   269
        }              
williamr@2
   270
williamr@2
   271
        auto_type replace( iterator where, mapped_type x ) // strong  
williamr@2
   272
        { 
williamr@2
   273
            BOOST_ASSERT( where != this->end() );
williamr@2
   274
williamr@2
   275
            this->enforce_null_policy( x, "Null pointer in 'replace()'" );
williamr@2
   276
williamr@2
   277
            auto_type ptr( x );
williamr@2
   278
williamr@2
   279
            BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(),
williamr@2
   280
                                                 bad_ptr_container_operation,
williamr@2
   281
                                                 "'replace()' on empty container" );
williamr@2
   282
williamr@2
   283
            auto_type old( where->second );       // nothrow
williamr@2
   284
            where.base()->second = ptr.release(); // nothrow, commit
williamr@2
   285
            return move( old );
williamr@2
   286
        }
williamr@2
   287
williamr@2
   288
        template< class U >
williamr@2
   289
        auto_type replace( iterator where, std::auto_ptr<U> x )
williamr@2
   290
        {
williamr@2
   291
            return replace( where, x.release() );
williamr@2
   292
        }
williamr@2
   293
williamr@2
   294
    public: // serialization
williamr@2
   295
williamr@2
   296
        template< class Archive >
williamr@2
   297
        void save( Archive& ar, const unsigned ) const
williamr@2
   298
        {
williamr@2
   299
            ar & ptr_container_detail::serialize_as_const( this->size() );
williamr@2
   300
williamr@2
   301
            const_iterator i = this->begin(), e = this->end();
williamr@2
   302
            for( ; i != e; ++i )
williamr@2
   303
            {
williamr@2
   304
                ar & i->first;
williamr@2
   305
                ar & ptr_container_detail::serialize_as_const( i->second );
williamr@2
   306
            }
williamr@2
   307
        }
williamr@2
   308
    };
williamr@2
   309
    
williamr@2
   310
} // ptr_container_detail
williamr@2
   311
williamr@2
   312
    /////////////////////////////////////////////////////////////////////////
williamr@2
   313
    // ptr_map_adapter
williamr@2
   314
    /////////////////////////////////////////////////////////////////////////
williamr@2
   315
    
williamr@2
   316
    template
williamr@2
   317
    < 
williamr@2
   318
        class T,
williamr@2
   319
        class VoidPtrMap, 
williamr@2
   320
        class CloneAllocator = heap_clone_allocator
williamr@2
   321
    >
williamr@2
   322
    class ptr_map_adapter : 
williamr@2
   323
        public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator>
williamr@2
   324
    {
williamr@2
   325
        typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator> 
williamr@2
   326
            base_type;
williamr@2
   327
    
williamr@2
   328
    public:    
williamr@2
   329
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator 
williamr@2
   330
                     iterator;       
williamr@2
   331
        typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
williamr@2
   332
                     const_iterator;
williamr@2
   333
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
williamr@2
   334
                    size_type;
williamr@2
   335
        typedef BOOST_DEDUCED_TYPENAME base_type::key_type
williamr@2
   336
                    key_type;
williamr@2
   337
        typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
williamr@2
   338
                    const_reference;
williamr@2
   339
        typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
williamr@2
   340
                    auto_type;
williamr@2
   341
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_compare 
williamr@2
   342
                    key_compare;
williamr@2
   343
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type 
williamr@2
   344
                    allocator_type;
williamr@2
   345
        typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
williamr@2
   346
                    mapped_type;
williamr@2
   347
    private:
williamr@2
   348
williamr@2
   349
        void safe_insert( const key_type& key, auto_type ptr ) // strong
williamr@2
   350
        {
williamr@2
   351
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
williamr@2
   352
                res = 
williamr@2
   353
                this->c_private().insert( std::make_pair( key, ptr.get() ) ); // strong, commit      
williamr@2
   354
            if( res.second )                                                  // nothrow     
williamr@2
   355
                ptr.release();                                                // nothrow
williamr@2
   356
        }
williamr@2
   357
    
williamr@2
   358
        template< class II >                                               
williamr@2
   359
        void map_basic_clone_and_insert( II first, II last )                  
williamr@2
   360
        {       
williamr@2
   361
            while( first != last )                                            
williamr@2
   362
            {                                            
williamr@2
   363
                if( this->find( first->first ) == this->end() )
williamr@2
   364
                {
williamr@2
   365
                    const_reference p = *first.base();     // nothrow                    
williamr@2
   366
                    auto_type ptr( this->null_policy_allocate_clone( p.second ) ); 
williamr@2
   367
                                                              // strong 
williamr@2
   368
                    this->safe_insert( p.first, ptr_container_detail::
williamr@2
   369
                                                move( ptr ) );// strong, commit
williamr@2
   370
                }
williamr@2
   371
                ++first;                                                      
williamr@2
   372
            }                                                                 
williamr@2
   373
        }
williamr@2
   374
    
williamr@2
   375
    public:
williamr@2
   376
williamr@2
   377
        explicit ptr_map_adapter( const key_compare& comp = key_compare(),
williamr@2
   378
                                  const allocator_type& a = allocator_type()  ) 
williamr@2
   379
          : base_type( comp, a ) { }
williamr@2
   380
    
williamr@2
   381
        template< class InputIterator >
williamr@2
   382
        ptr_map_adapter( InputIterator first, InputIterator last, 
williamr@2
   383
                         const key_compare& comp = key_compare(),
williamr@2
   384
                         const allocator_type& a = allocator_type() )
williamr@2
   385
          : base_type( comp, a ) 
williamr@2
   386
        {
williamr@2
   387
            map_basic_clone_and_insert( first, last );
williamr@2
   388
        }
williamr@2
   389
williamr@2
   390
        template< class U >
williamr@2
   391
        ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r )
williamr@2
   392
        { }
williamr@2
   393
williamr@2
   394
        template< class U >
williamr@2
   395
        void operator=( std::auto_ptr<U> r )
williamr@2
   396
        {  
williamr@2
   397
            base_type::operator=( r );
williamr@2
   398
        }
williamr@2
   399
williamr@2
   400
        using base_type::release;
williamr@2
   401
williamr@2
   402
        template< typename InputIterator >
williamr@2
   403
        void insert( InputIterator first, InputIterator last ) // basic
williamr@2
   404
        {
williamr@2
   405
            map_basic_clone_and_insert( first, last );
williamr@2
   406
        }
williamr@2
   407
williamr@2
   408
        template< class Range >
williamr@2
   409
        void insert( const Range& r )
williamr@2
   410
        {
williamr@2
   411
            insert( boost::begin(r), boost::end(r) );
williamr@2
   412
        }
williamr@2
   413
williamr@2
   414
    private:
williamr@2
   415
        std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong
williamr@2
   416
        {
williamr@2
   417
            this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" );
williamr@2
   418
            auto_type ptr( x );                                              // nothrow
williamr@2
   419
williamr@2
   420
            std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
williamr@2
   421
                 res = this->c_private().insert( std::make_pair( key, x ) ); // strong, commit      
williamr@2
   422
            if( res.second )                                             // nothrow     
williamr@2
   423
                ptr.release();                                           // nothrow
williamr@2
   424
            return std::make_pair( iterator( res.first ), res.second );  // nothrow        
williamr@2
   425
        }
williamr@2
   426
        
williamr@2
   427
    public:
williamr@2
   428
        
williamr@2
   429
        std::pair<iterator,bool> insert( key_type& key, mapped_type x )
williamr@2
   430
        {
williamr@2
   431
            return insert_impl( key, x );
williamr@2
   432
        }
williamr@2
   433
williamr@2
   434
        template< class U >
williamr@2
   435
        std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x )
williamr@2
   436
        {
williamr@2
   437
            return insert_impl( key, x.release() );
williamr@2
   438
        }
williamr@2
   439
williamr@2
   440
        template< class PtrMapAdapter >
williamr@2
   441
        bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, 
williamr@2
   442
                       PtrMapAdapter& from ) // strong
williamr@2
   443
        {
williamr@2
   444
            return this->single_transfer( object, from );
williamr@2
   445
        }
williamr@2
   446
williamr@2
   447
        template< class PtrMapAdapter >
williamr@2
   448
        size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, 
williamr@2
   449
                            BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, 
williamr@2
   450
                            PtrMapAdapter& from ) // basic
williamr@2
   451
        {
williamr@2
   452
            return this->single_transfer( first, last, from );
williamr@2
   453
        }
williamr@2
   454
williamr@2
   455
#if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
williamr@2
   456
#else    
williamr@2
   457
williamr@2
   458
        template< class PtrMapAdapter, class Range >
williamr@2
   459
        BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
williamr@2
   460
                            BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
williamr@2
   461
                                                            size_type >::type
williamr@2
   462
        transfer( const Range& r, PtrMapAdapter& from ) // basic
williamr@2
   463
        {
williamr@2
   464
            return transfer( boost::begin(r), boost::end(r), from );
williamr@2
   465
        }
williamr@2
   466
        
williamr@2
   467
#endif
williamr@2
   468
williamr@2
   469
        template< class PtrMapAdapter >
williamr@2
   470
        size_type transfer( PtrMapAdapter& from ) // basic
williamr@2
   471
        {
williamr@2
   472
            return transfer( from.begin(), from.end(), from );
williamr@2
   473
        }
williamr@2
   474
williamr@2
   475
    public: // serialization
williamr@2
   476
williamr@2
   477
        template< class Archive >
williamr@2
   478
        void load( Archive& ar, const unsigned ) // strong
williamr@2
   479
        {
williamr@2
   480
            this->clear();
williamr@2
   481
            size_type n;
williamr@2
   482
            ar & n;
williamr@2
   483
williamr@2
   484
            for( size_type i = 0u; i != n; ++i )
williamr@2
   485
            {
williamr@2
   486
                key_type  key;
williamr@2
   487
                T*        value;
williamr@2
   488
                ar & key;
williamr@2
   489
                ar & value;
williamr@2
   490
                std::pair<iterator,bool> p = this->insert( key, value );
williamr@2
   491
                ar.reset_object_address( &p.first->first, &key ); 
williamr@2
   492
            }
williamr@2
   493
        }
williamr@2
   494
williamr@2
   495
        BOOST_SERIALIZATION_SPLIT_MEMBER()
williamr@2
   496
        
williamr@2
   497
  };
williamr@2
   498
  
williamr@2
   499
  /////////////////////////////////////////////////////////////////////////
williamr@2
   500
  // ptr_multimap_adapter
williamr@2
   501
  /////////////////////////////////////////////////////////////////////////
williamr@2
   502
williamr@2
   503
    template
williamr@2
   504
    < 
williamr@2
   505
        class T,
williamr@2
   506
        class VoidPtrMultiMap, 
williamr@2
   507
        class CloneAllocator = heap_clone_allocator
williamr@2
   508
    >
williamr@2
   509
    class ptr_multimap_adapter : 
williamr@2
   510
        public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator>
williamr@2
   511
    {
williamr@2
   512
        typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator>
williamr@2
   513
             base_type;
williamr@2
   514
williamr@2
   515
    public: // typedefs
williamr@2
   516
        typedef BOOST_DEDUCED_TYPENAME base_type::iterator           
williamr@2
   517
                       iterator;                 
williamr@2
   518
        typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator     
williamr@2
   519
                       const_iterator;           
williamr@2
   520
        typedef BOOST_DEDUCED_TYPENAME base_type::size_type
williamr@2
   521
                       size_type;
williamr@2
   522
        typedef BOOST_DEDUCED_TYPENAME base_type::key_type
williamr@2
   523
                       key_type;
williamr@2
   524
        typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
williamr@2
   525
                       const_reference;
williamr@2
   526
        typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
williamr@2
   527
                    mapped_type;
williamr@2
   528
        typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
williamr@2
   529
                    auto_type;            
williamr@2
   530
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::key_compare 
williamr@2
   531
                    key_compare;
williamr@2
   532
        typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type 
williamr@2
   533
                    allocator_type;
williamr@2
   534
    private:
williamr@2
   535
williamr@2
   536
        void safe_insert( const key_type& key, auto_type ptr ) // strong
williamr@2
   537
        {
williamr@2
   538
            this->c_private().insert( 
williamr@2
   539
                           std::make_pair( key, ptr.get() ) ); // strong, commit      
williamr@2
   540
            ptr.release();                                     // nothrow
williamr@2
   541
        }
williamr@2
   542
        
williamr@2
   543
        template< typename II >                                               
williamr@2
   544
        void map_basic_clone_and_insert( II first, II last )                  
williamr@2
   545
        {                                                         
williamr@2
   546
            while( first != last )                                            
williamr@2
   547
            {                                            
williamr@2
   548
                const_reference pair = *first.base();     // nothrow                     
williamr@2
   549
                auto_type ptr( this->null_policy_allocate_clone( pair.second ) );    
williamr@2
   550
                                                          // strong
williamr@2
   551
                safe_insert( pair.first, ptr_container_detail::
williamr@2
   552
                                         move( ptr ) );   // strong, commit
williamr@2
   553
                ++first;                                                      
williamr@2
   554
            }                                                                 
williamr@2
   555
        }
williamr@2
   556
        
williamr@2
   557
    public:
williamr@2
   558
        
williamr@2
   559
        explicit ptr_multimap_adapter( const key_compare& comp = key_compare(),
williamr@2
   560
                                       const allocator_type& a = allocator_type() )
williamr@2
   561
          : base_type( comp, a ) { }
williamr@2
   562
        
williamr@2
   563
        template< class InputIterator >
williamr@2
   564
        ptr_multimap_adapter( InputIterator first, InputIterator last,
williamr@2
   565
                              const key_compare& comp = key_compare(),
williamr@2
   566
                              const allocator_type& a = allocator_type() )
williamr@2
   567
          : base_type( comp, a )
williamr@2
   568
        {
williamr@2
   569
            map_basic_clone_and_insert( first, last );
williamr@2
   570
        }
williamr@2
   571
williamr@2
   572
        template< class U >
williamr@2
   573
        ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r )
williamr@2
   574
        { }
williamr@2
   575
williamr@2
   576
        template< class U >
williamr@2
   577
        void operator=( std::auto_ptr<U> r )
williamr@2
   578
        {  
williamr@2
   579
            base_type::operator=( r );
williamr@2
   580
        }
williamr@2
   581
williamr@2
   582
        using base_type::release;
williamr@2
   583
        
williamr@2
   584
        template< typename InputIterator >
williamr@2
   585
        void insert( InputIterator first, InputIterator last ) // basic
williamr@2
   586
        {
williamr@2
   587
            map_basic_clone_and_insert( first, last );
williamr@2
   588
        }
williamr@2
   589
williamr@2
   590
        template< class Range >
williamr@2
   591
        void insert( const Range& r )
williamr@2
   592
        {
williamr@2
   593
            insert( boost::begin(r), boost::end(r) );
williamr@2
   594
        }
williamr@2
   595
williamr@2
   596
        iterator insert( key_type& key, mapped_type x ) // strong
williamr@2
   597
        {
williamr@2
   598
            this->enforce_null_policy( x, 
williamr@2
   599
                  "Null pointer in 'ptr_multimap_adapter::insert()'" );
williamr@2
   600
williamr@2
   601
            auto_type ptr( x );         // nothrow
williamr@2
   602
            BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
williamr@2
   603
                res = this->c_private().insert( std::make_pair( key, x ) );
williamr@2
   604
                                        // strong, commit        
williamr@2
   605
            ptr.release();              // notrow
williamr@2
   606
            return iterator( res );           
williamr@2
   607
        }
williamr@2
   608
williamr@2
   609
        template< class U >
williamr@2
   610
        iterator insert( key_type& key, std::auto_ptr<U> x )
williamr@2
   611
        {
williamr@2
   612
            return insert( key, x.release() );
williamr@2
   613
        }
williamr@2
   614
williamr@2
   615
        template< class PtrMapAdapter >
williamr@2
   616
        void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object, 
williamr@2
   617
                       PtrMapAdapter& from ) // strong
williamr@2
   618
        {
williamr@2
   619
            this->multi_transfer( object, from );
williamr@2
   620
        }
williamr@2
   621
williamr@2
   622
        template< class PtrMapAdapter >
williamr@2
   623
        size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first, 
williamr@2
   624
                            BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last, 
williamr@2
   625
                            PtrMapAdapter& from ) // basic
williamr@2
   626
        {
williamr@2
   627
            return this->multi_transfer( first, last, from );
williamr@2
   628
        }
williamr@2
   629
williamr@2
   630
#if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)        
williamr@2
   631
#else    
williamr@2
   632
williamr@2
   633
        template<  class PtrMapAdapter, class Range >
williamr@2
   634
        BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
williamr@2
   635
                            BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
williamr@2
   636
                                                            size_type >::type
williamr@2
   637
        transfer( const Range& r, PtrMapAdapter& from ) // basic
williamr@2
   638
        {
williamr@2
   639
            return transfer( boost::begin(r), boost::end(r), from );
williamr@2
   640
        }
williamr@2
   641
williamr@2
   642
#endif        
williamr@2
   643
        template< class PtrMapAdapter >
williamr@2
   644
        void transfer( PtrMapAdapter& from ) // basic
williamr@2
   645
        {
williamr@2
   646
            transfer( from.begin(), from.end(), from );
williamr@2
   647
            BOOST_ASSERT( from.empty() );
williamr@2
   648
        }
williamr@2
   649
williamr@2
   650
    public: // serialization
williamr@2
   651
williamr@2
   652
        template< class Archive >
williamr@2
   653
        void load( Archive& ar, const unsigned ) // basic
williamr@2
   654
        {
williamr@2
   655
            this->clear();
williamr@2
   656
            size_type n;
williamr@2
   657
            ar & n;
williamr@2
   658
williamr@2
   659
            for( size_type i = 0u; i != n; ++i )
williamr@2
   660
            {
williamr@2
   661
                key_type  key;
williamr@2
   662
                T*        value;
williamr@2
   663
                ar & key;
williamr@2
   664
                ar & value;
williamr@2
   665
                iterator p = this->insert( key, value );
williamr@2
   666
                ar.reset_object_address( &p->first, &key );
williamr@2
   667
            }
williamr@2
   668
        }
williamr@2
   669
williamr@2
   670
        BOOST_SERIALIZATION_SPLIT_MEMBER()
williamr@2
   671
williamr@2
   672
    };
williamr@2
   673
williamr@2
   674
    template< class I, class F, class S >
williamr@2
   675
    inline bool is_null( const ptr_map_iterator<I,F,S>& i )
williamr@2
   676
    {
williamr@2
   677
        return i->second == 0;
williamr@2
   678
    }
williamr@2
   679
    
williamr@2
   680
} // namespace 'boost'  
williamr@2
   681
williamr@2
   682
#endif