Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/ptr_container/ptr_map_adapter.hpp @ 44

Last change on this file since 44 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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