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