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/ptr_container/detail/meta_functions.hpp>
22#include <boost/static_assert.hpp>
23#include <boost/range/iterator_range.hpp>
24
25namespace boost
26{
27namespace ptr_container_detail
28{
29
30 template
31 <
32 class T,
33 class VoidPtrMap,
34 bool Ordered
35 >
36 struct map_config
37 {
38 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type
39 U;
40 typedef VoidPtrMap
41 void_container_type;
42
43 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
44 allocator_type;
45
46 typedef BOOST_DEDUCED_TYPENAME
47 mpl::eval_if_c<Ordered,
48 select_value_compare<VoidPtrMap>,
49 mpl::identity<void> >::type
50 value_compare;
51
52 typedef BOOST_DEDUCED_TYPENAME
53 mpl::eval_if_c<Ordered,
54 select_key_compare<VoidPtrMap>,
55 mpl::identity<void> >::type
56 key_compare;
57
58 typedef BOOST_DEDUCED_TYPENAME
59 mpl::eval_if_c<Ordered,
60 mpl::identity<void>,
61 select_hasher<VoidPtrMap> >::type
62 hasher;
63
64 typedef BOOST_DEDUCED_TYPENAME
65 mpl::eval_if_c<Ordered,
66 mpl::identity<void>,
67 select_key_equal<VoidPtrMap> >::type
68 key_equal;
69
70 typedef BOOST_DEDUCED_TYPENAME
71 mpl::if_c<Ordered,
72 ptr_container_detail::ordered_associative_container_tag,
73 ptr_container_detail::unordered_associative_container_tag>::type
74 container_type;
75
76 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::key_type
77 key_type;
78
79 typedef U value_type;
80
81 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::iterator, key_type, U* const >
82 iterator;
83
84 typedef ptr_map_iterator< BOOST_DEDUCED_TYPENAME VoidPtrMap::const_iterator, key_type, const U* const>
85 const_iterator;
86
87 typedef ptr_map_iterator<
88 BOOST_DEDUCED_TYPENAME
89 mpl::eval_if_c<Ordered,
90 select_iterator<VoidPtrMap>,
91 select_local_iterator<VoidPtrMap> >::type,
92 key_type, U* const >
93 local_iterator;
94
95 typedef ptr_map_iterator<
96 BOOST_DEDUCED_TYPENAME
97 mpl::eval_if_c<Ordered,
98 select_iterator<VoidPtrMap>,
99 select_const_local_iterator<VoidPtrMap> >::type,
100 key_type, const U* const >
101 const_local_iterator;
102
103 template< class Iter >
104 static U* get_pointer( Iter i )
105 {
106 return i->second;
107 }
108
109 template< class Iter >
110 static const U* get_const_pointer( Iter i )
111 {
112 return i->second;
113 }
114
115 BOOST_STATIC_CONSTANT( bool, allow_null = boost::is_nullable<T>::value );
116 };
117
118
119
120 template
121 <
122 class T,
123 class VoidPtrMap,
124 class CloneAllocator,
125 bool Ordered
126 >
127 class ptr_map_adapter_base :
128 public ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
129 CloneAllocator >
130 {
131 typedef ptr_container_detail::associative_ptr_container< map_config<T,VoidPtrMap,Ordered>,
132 CloneAllocator >
133 base_type;
134
135 typedef map_config<T,VoidPtrMap,Ordered> config;
136 typedef ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered> this_type;
137
138 public:
139
140 typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type
141 allocator_type;
142 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
143 iterator;
144 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
145 const_iterator;
146 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
147 size_type;
148 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
149 key_type;
150 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
151 auto_type;
152 typedef BOOST_DEDUCED_TYPENAME base_type::value_type
153 mapped_type;
154 typedef BOOST_DEDUCED_TYPENAME base_type::reference
155 mapped_reference;
156 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
157 const_mapped_reference;
158 typedef BOOST_DEDUCED_TYPENAME iterator_value<iterator>::type
159 value_type;
160 typedef value_type
161 reference;
162 typedef BOOST_DEDUCED_TYPENAME iterator_value<const_iterator>::type
163 const_reference;
164 typedef value_type
165 pointer;
166 typedef const_reference
167 const_pointer;
168
169 private:
170 const_mapped_reference lookup( const key_type& key ) const
171 {
172 const_iterator i = this->find( key );
173 if( i != this->end() )
174 return *i->second;
175 else
176 BOOST_PTR_CONTAINER_THROW_EXCEPTION( true, bad_ptr_container_operation,
177 "'ptr_map/multimap::at()' could"
178 " not find key" );
179 }
180
181 struct eraser // scope guard
182 {
183 bool released_;
184 VoidPtrMap* m_;
185 const key_type& key_;
186
187 eraser( VoidPtrMap* m, const key_type& key )
188 : released_(false), m_(m), key_(key)
189 {}
190
191 ~eraser()
192 {
193 if( !released_ )
194 m_->erase(key_);
195 }
196
197 void release() { released_ = true; }
198
199 private:
200 eraser& operator=(const eraser&);
201 };
202
203 mapped_reference insert_lookup( const key_type& key )
204 {
205 void*& ref = this->base()[key];
206 if( ref )
207 {
208 return *static_cast<mapped_type>(ref);
209 }
210 else
211 {
212 eraser e(&this->base(),key); // nothrow
213 mapped_type res = new T(); // strong
214 ref = res; // nothrow
215 e.release(); // nothrow
216 return *res;
217 }
218 }
219
220 public:
221
222 ptr_map_adapter_base()
223 { }
224
225 template< class SizeType >
226 explicit ptr_map_adapter_base( SizeType n,
227 ptr_container_detail::unordered_associative_container_tag tag )
228 : base_type( n, tag )
229 { }
230
231 template< class Compare, class Allocator >
232 ptr_map_adapter_base( const Compare& comp,
233 const Allocator& a )
234 : base_type( comp, a )
235 { }
236
237 template< class Hash, class Pred, class Allocator >
238 ptr_map_adapter_base( const Hash& hash,
239 const Pred& pred,
240 const Allocator& a )
241 : base_type( hash, pred, a )
242 { }
243
244 template< class InputIterator >
245 ptr_map_adapter_base( InputIterator first, InputIterator last )
246 : base_type( first, last )
247 { }
248
249 template< class InputIterator, class Comp >
250 ptr_map_adapter_base( InputIterator first, InputIterator last,
251 const Comp& comp,
252 const allocator_type& a = allocator_type() )
253 : base_type( first, last, comp, a )
254 { }
255
256 template< class InputIterator, class Hash, class Pred, class Allocator >
257 ptr_map_adapter_base( InputIterator first, InputIterator last,
258 const Hash& hash,
259 const Pred& pred,
260 const Allocator& a )
261 : base_type( first, last, hash, pred, a )
262 { }
263
264 template< class PtrContainer >
265 explicit ptr_map_adapter_base( std::auto_ptr<PtrContainer> clone )
266 : base_type( clone )
267 { }
268
269 template< typename PtrContainer >
270 ptr_map_adapter_base& operator=( std::auto_ptr<PtrContainer> clone )
271 {
272 base_type::operator=( clone );
273 return *this;
274 }
275
276 iterator find( const key_type& x )
277 {
278 return iterator( this->base().find( x ) );
279 }
280
281 const_iterator find( const key_type& x ) const
282 {
283 return const_iterator( this->base().find( x ) );
284 }
285
286 size_type count( const key_type& x ) const
287 {
288 return this->base().count( x );
289 }
290
291 iterator lower_bound( const key_type& x )
292 {
293 return iterator( this->base().lower_bound( x ) );
294 }
295
296 const_iterator lower_bound( const key_type& x ) const
297 {
298 return const_iterator( this->base().lower_bound( x ) );
299 }
300
301 iterator upper_bound( const key_type& x )
302 {
303 return iterator( this->base().upper_bound( x ) );
304 }
305
306 const_iterator upper_bound( const key_type& x ) const
307 {
308 return const_iterator( this->base().upper_bound( x ) );
309 }
310
311 iterator_range<iterator> equal_range( const key_type& x )
312 {
313 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,
314 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator>
315 p = this->base().equal_range( x );
316 return make_iterator_range( iterator( p.first ), iterator( p.second ) );
317 }
318
319 iterator_range<const_iterator> equal_range( const key_type& x ) const
320 {
321 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator,
322 BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator>
323 p = this->base().equal_range( x );
324 return make_iterator_range( const_iterator( p.first ),
325 const_iterator( p.second ) );
326 }
327
328 mapped_reference at( const key_type& key )
329 {
330 return const_cast<mapped_reference>( lookup( key ) );
331 }
332
333 const_mapped_reference at( const key_type& key ) const
334 {
335 return lookup( key );
336 }
337
338 mapped_reference operator[]( const key_type& key )
339 {
340 return insert_lookup( key );
341 }
342
343 auto_type replace( iterator where, mapped_type x ) // strong
344 {
345 BOOST_ASSERT( where != this->end() );
346
347 this->enforce_null_policy( x, "Null pointer in 'replace()'" );
348
349 auto_type ptr( x );
350
351 BOOST_PTR_CONTAINER_THROW_EXCEPTION( this->empty(),
352 bad_ptr_container_operation,
353 "'replace()' on empty container" );
354
355 auto_type old( where->second ); // nothrow
356 where.base()->second = ptr.release(); // nothrow, commit
357 return boost::ptr_container::move( old );
358 }
359
360 template< class U >
361 auto_type replace( iterator where, std::auto_ptr<U> x )
362 {
363 return replace( where, x.release() );
364 }
365
366 protected:
367 size_type bucket( const key_type& key ) const
368 {
369 return this->base().bucket( key );
370 }
371 };
372
373} // ptr_container_detail
374
375 /////////////////////////////////////////////////////////////////////////
376 // ptr_map_adapter
377 /////////////////////////////////////////////////////////////////////////
378
379 template
380 <
381 class T,
382 class VoidPtrMap,
383 class CloneAllocator = heap_clone_allocator,
384 bool Ordered = true
385 >
386 class ptr_map_adapter :
387 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
388 {
389 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMap,CloneAllocator,Ordered>
390 base_type;
391
392 public:
393 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
394 iterator;
395 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
396 const_iterator;
397 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
398 size_type;
399 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
400 key_type;
401 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
402 const_reference;
403 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
404 auto_type;
405 typedef BOOST_DEDUCED_TYPENAME VoidPtrMap::allocator_type
406 allocator_type;
407 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
408 mapped_type;
409 private:
410
411 void safe_insert( const key_type& key, auto_type ptr ) // strong
412 {
413 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
414 res =
415 this->base().insert( std::make_pair( key, ptr.get() ) ); // strong, commit
416 if( res.second ) // nothrow
417 ptr.release(); // nothrow
418 }
419
420 template< class II >
421 void map_basic_clone_and_insert( II first, II last )
422 {
423 while( first != last )
424 {
425 if( this->find( first->first ) == this->end() )
426 {
427 const_reference p = *first.base(); // nothrow
428 auto_type ptr( this->null_policy_allocate_clone( p.second ) );
429 // strong
430 this->safe_insert( p.first,
431 boost::ptr_container::move( ptr ) );
432 // strong, commit
433 }
434 ++first;
435 }
436 }
437
438 public:
439 ptr_map_adapter( )
440 { }
441
442 template< class Comp >
443 explicit ptr_map_adapter( const Comp& comp,
444 const allocator_type& a )
445 : base_type( comp, a ) { }
446
447 template< class Hash, class Pred, class Allocator >
448 ptr_map_adapter( const Hash& hash,
449 const Pred& pred,
450 const Allocator& a )
451 : base_type( hash, pred, a )
452 { }
453
454 template< class InputIterator >
455 ptr_map_adapter( InputIterator first, InputIterator last )
456 {
457 map_basic_clone_and_insert( first, last );
458 }
459
460 template< class InputIterator, class Comp >
461 ptr_map_adapter( InputIterator first, InputIterator last,
462 const Comp& comp,
463 const allocator_type& a = allocator_type() )
464 : base_type( comp, a )
465 {
466 map_basic_clone_and_insert( first, last );
467 }
468
469 template< class InputIterator, class Hash, class Pred, class Allocator >
470 ptr_map_adapter( InputIterator first, InputIterator last,
471 const Hash& hash,
472 const Pred& pred,
473 const Allocator& a )
474 : base_type( hash, pred, a )
475 {
476 map_basic_clone_and_insert( first, last );
477 }
478
479 ptr_map_adapter( const ptr_map_adapter& r )
480 {
481 map_basic_clone_and_insert( r.begin(), r.end() );
482 }
483
484 template< class Key, class U, class CA, bool b >
485 ptr_map_adapter( const ptr_map_adapter<Key,U,CA,b>& r )
486 {
487 map_basic_clone_and_insert( r.begin(), r.end() );
488 }
489
490 template< class U >
491 ptr_map_adapter( std::auto_ptr<U> r ) : base_type( r )
492 { }
493
494 ptr_map_adapter& operator=( ptr_map_adapter r )
495 {
496 this->swap( r );
497 return *this;
498 }
499
500 template< class U >
501 ptr_map_adapter& operator=( std::auto_ptr<U> r )
502 {
503 base_type::operator=( r );
504 return *this;
505 }
506
507 using base_type::release;
508
509 template< typename InputIterator >
510 void insert( InputIterator first, InputIterator last ) // basic
511 {
512 map_basic_clone_and_insert( first, last );
513 }
514
515 template< class Range >
516 void insert( const Range& r )
517 {
518 insert( boost::begin(r), boost::end(r) );
519 }
520
521 private:
522 std::pair<iterator,bool> insert_impl( const key_type& key, mapped_type x ) // strong
523 {
524 this->enforce_null_policy( x, "Null pointer in ptr_map_adapter::insert()" );
525 auto_type ptr( x ); // nothrow
526
527 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool>
528 res = this->base().insert( std::make_pair( key, x ) ); // strong, commit
529 if( res.second ) // nothrow
530 ptr.release(); // nothrow
531 return std::make_pair( iterator( res.first ), res.second ); // nothrow
532 }
533
534 iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong
535 {
536 this->enforce_null_policy( x,
537 "Null pointer in 'ptr_map_adapter::insert()'" );
538 auto_type ptr( x ); // nothrow
539 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
540 res = this->base().insert( before.base(), std::make_pair( key, x ) );
541 // strong, commit
542 ptr.release(); // notrow
543 return iterator( res );
544 }
545
546 public:
547
548 std::pair<iterator,bool> insert( key_type& key, mapped_type x )
549 {
550 return insert_impl( key, x );
551 }
552
553 template< class U >
554 std::pair<iterator,bool> insert( const key_type& key, std::auto_ptr<U> x )
555 {
556 return insert_impl( key, x.release() );
557 }
558
559 template< class F, class S >
560 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong
561 {
562 this->enforce_null_policy( p.second,
563 "Null pointer in 'ptr_map_adapter::insert()'" );
564
565 auto_type ptr( this->null_policy_allocate_clone( p.second ) );
566 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
567 result = this->base().insert( before.base(),
568 std::make_pair(p.first,ptr.get()) ); // strong
569 if( ptr.get() == result->second )
570 ptr.release();
571
572 return iterator( result );
573 }
574
575 iterator insert( iterator before, key_type& key, mapped_type x ) // strong
576 {
577 return insert_impl( before, key, x );
578 }
579
580 template< class U >
581 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong
582 {
583 return insert_impl( before, key, x.release() );
584 }
585
586 template< class PtrMapAdapter >
587 bool transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
588 PtrMapAdapter& from ) // strong
589 {
590 return this->single_transfer( object, from );
591 }
592
593 template< class PtrMapAdapter >
594 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
595 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
596 PtrMapAdapter& from ) // basic
597 {
598 return this->single_transfer( first, last, from );
599 }
600
601#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
602#else
603
604 template< class PtrMapAdapter, class Range >
605 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
606 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
607 size_type >::type
608 transfer( const Range& r, PtrMapAdapter& from ) // basic
609 {
610 return transfer( boost::begin(r), boost::end(r), from );
611 }
612
613#endif
614
615 template< class PtrMapAdapter >
616 size_type transfer( PtrMapAdapter& from ) // basic
617 {
618 return transfer( from.begin(), from.end(), from );
619 }
620 };
621
622 /////////////////////////////////////////////////////////////////////////
623 // ptr_multimap_adapter
624 /////////////////////////////////////////////////////////////////////////
625
626 template
627 <
628 class T,
629 class VoidPtrMultiMap,
630 class CloneAllocator = heap_clone_allocator,
631 bool Ordered = true
632 >
633 class ptr_multimap_adapter :
634 public ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
635 {
636 typedef ptr_container_detail::ptr_map_adapter_base<T,VoidPtrMultiMap,CloneAllocator,Ordered>
637 base_type;
638
639 public: // typedefs
640 typedef BOOST_DEDUCED_TYPENAME base_type::iterator
641 iterator;
642 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator
643 const_iterator;
644 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
645 size_type;
646 typedef BOOST_DEDUCED_TYPENAME base_type::key_type
647 key_type;
648 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
649 const_reference;
650 typedef BOOST_DEDUCED_TYPENAME base_type::mapped_type
651 mapped_type;
652 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type
653 auto_type;
654 typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiMap::allocator_type
655 allocator_type;
656 private:
657
658 void safe_insert( const key_type& key, auto_type ptr ) // strong
659 {
660 this->base().insert(
661 std::make_pair( key, ptr.get() ) ); // strong, commit
662 ptr.release(); // nothrow
663 }
664
665 template< typename II >
666 void map_basic_clone_and_insert( II first, II last )
667 {
668 while( first != last )
669 {
670 const_reference pair = *first.base(); // nothrow
671 auto_type ptr( this->null_policy_allocate_clone( pair.second ) );
672 // strong
673 safe_insert( key: pair.first,
674 ptr: boost::ptr_container::move( ptr ) );
675 // strong, commit
676 ++first;
677 }
678 }
679
680 public:
681
682 ptr_multimap_adapter()
683 { }
684
685 template< class SizeType >
686 ptr_multimap_adapter( SizeType n,
687 ptr_container_detail::unordered_associative_container_tag tag )
688 : base_type( n, tag )
689 { }
690
691 template< class Comp >
692 explicit ptr_multimap_adapter( const Comp& comp,
693 const allocator_type& a )
694 : base_type( comp, a ) { }
695
696 template< class Hash, class Pred, class Allocator >
697 ptr_multimap_adapter( const Hash& hash,
698 const Pred& pred,
699 const Allocator& a )
700 : base_type( hash, pred, a )
701 { }
702
703 template< class InputIterator >
704 ptr_multimap_adapter( InputIterator first, InputIterator last )
705 {
706 map_basic_clone_and_insert( first, last );
707 }
708
709 template< class InputIterator, class Comp >
710 ptr_multimap_adapter( InputIterator first, InputIterator last,
711 const Comp& comp,
712 const allocator_type& a )
713 : base_type( comp, a )
714 {
715 map_basic_clone_and_insert( first, last );
716 }
717
718 template< class InputIterator, class Hash, class Pred, class Allocator >
719 ptr_multimap_adapter( InputIterator first, InputIterator last,
720 const Hash& hash,
721 const Pred& pred,
722 const Allocator& a )
723 : base_type( hash, pred, a )
724 {
725 map_basic_clone_and_insert( first, last );
726 }
727
728 ptr_multimap_adapter( const ptr_multimap_adapter& r )
729 {
730 map_basic_clone_and_insert( r.begin(), r.end() );
731 }
732
733 template< class Key, class U, class CA, bool b >
734 ptr_multimap_adapter( const ptr_multimap_adapter<Key,U,CA,b>& r )
735 {
736 map_basic_clone_and_insert( r.begin(), r.end() );
737 }
738
739 template< class U >
740 explicit ptr_multimap_adapter( std::auto_ptr<U> r ) : base_type( r )
741 { }
742
743 ptr_multimap_adapter& operator=( ptr_multimap_adapter r )
744 {
745 this->swap( r );
746 return *this;
747 }
748
749 template< class U >
750 ptr_multimap_adapter& operator=( std::auto_ptr<U> r )
751 {
752 base_type::operator=( r );
753 return *this;
754 }
755
756 using base_type::release;
757
758 private:
759 iterator insert_impl( const key_type& key, mapped_type x ) // strong
760 {
761 this->enforce_null_policy( x,
762 "Null pointer in 'ptr_multimap_adapter::insert()'" );
763 auto_type ptr( x ); // nothrow
764 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
765 res = this->base().insert( std::make_pair( key, x ) );
766 // strong, commit
767 ptr.release(); // notrow
768 return iterator( res );
769 }
770
771 iterator insert_impl( iterator before, const key_type& key, mapped_type x ) // strong
772 {
773 this->enforce_null_policy( x,
774 "Null pointer in 'ptr_multimap_adapter::insert()'" );
775 auto_type ptr( x ); // nothrow
776 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator
777 res = this->base().insert( before.base(),
778 std::make_pair( key, x ) );
779 // strong, commit
780 ptr.release(); // notrow
781 return iterator( res );
782 }
783
784 public:
785 template< typename InputIterator >
786 void insert( InputIterator first, InputIterator last ) // basic
787 {
788 map_basic_clone_and_insert( first, last );
789 }
790
791 template< class Range >
792 void insert( const Range& r )
793 {
794 insert( boost::begin(r), boost::end(r) );
795 }
796
797 iterator insert( key_type& key, mapped_type x ) // strong
798 {
799 return insert_impl( key, x );
800 }
801
802 template< class U >
803 iterator insert( const key_type& key, std::auto_ptr<U> x )
804 {
805 return insert_impl( key, x.release() );
806 }
807
808 template< class F, class S >
809 iterator insert( iterator before, ptr_container_detail::ref_pair<F,S> p ) // strong
810 {
811 this->enforce_null_policy( p.second,
812 "Null pointer in 'ptr_multimap_adapter::insert()'" );
813 iterator res = insert_impl( before, p.first,
814 this->null_policy_allocate_clone( p.second ) );
815 return res;
816 }
817
818 iterator insert( iterator before, key_type& key, mapped_type x ) // strong
819 {
820 return insert_impl( before, key, x );
821 }
822
823 template< class U >
824 iterator insert( iterator before, const key_type& key, std::auto_ptr<U> x ) // strong
825 {
826 return insert_impl( before, key, x.release() );
827 }
828
829 template< class PtrMapAdapter >
830 void transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator object,
831 PtrMapAdapter& from ) // strong
832 {
833 this->multi_transfer( object, from );
834 }
835
836 template< class PtrMapAdapter >
837 size_type transfer( BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator first,
838 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator last,
839 PtrMapAdapter& from ) // basic
840 {
841 return this->multi_transfer( first, last, from );
842 }
843
844#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
845#else
846
847 template< class PtrMapAdapter, class Range >
848 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
849 BOOST_DEDUCED_TYPENAME PtrMapAdapter::iterator >,
850 size_type >::type
851 transfer( const Range& r, PtrMapAdapter& from ) // basic
852 {
853 return transfer( boost::begin(r), boost::end(r), from );
854 }
855
856#endif
857 template< class PtrMapAdapter >
858 void transfer( PtrMapAdapter& from ) // basic
859 {
860 transfer( from.begin(), from.end(), from );
861 BOOST_ASSERT( from.empty() );
862 }
863
864 };
865
866 template< class I, class F, class S >
867 inline bool is_null( const ptr_map_iterator<I,F,S>& i )
868 {
869 return i->second == 0;
870 }
871
872} // namespace 'boost'
873
874#endif
875

source code of boost/boost/ptr_container/ptr_map_adapter.hpp