2 // Boost.Pointer Container
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)
9 // For more information, see http://www.boost.org/libs/ptr_container/
12 #ifndef BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP
13 #define BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/ptr_container/detail/associative_ptr_container.hpp>
20 #include <boost/ptr_container/detail/meta_functions.hpp>
21 #include <boost/ptr_container/detail/void_ptr_iterator.hpp>
22 #include <boost/range/iterator_range.hpp>
26 namespace ptr_container_detail
39 typedef BOOST_DEDUCED_TYPENAME
VoidPtrSet::allocator_type
42 typedef Key value_type
;
47 typedef BOOST_DEDUCED_TYPENAME
48 mpl::eval_if_c
<Ordered
,
49 select_value_compare
<VoidPtrSet
>,
50 mpl::identity
<void> >::type
56 typedef BOOST_DEDUCED_TYPENAME
57 mpl::eval_if_c
<Ordered
,
59 select_hasher
<VoidPtrSet
> >::type
62 typedef BOOST_DEDUCED_TYPENAME
63 mpl::eval_if_c
<Ordered
,
65 select_key_equal
<VoidPtrSet
> >::type
68 typedef BOOST_DEDUCED_TYPENAME
70 ordered_associative_container_tag
,
71 unordered_associative_container_tag
>::type
74 typedef void_ptr_iterator
<
75 BOOST_DEDUCED_TYPENAME
VoidPtrSet::iterator
, Key
>
78 typedef void_ptr_iterator
<
79 BOOST_DEDUCED_TYPENAME
VoidPtrSet::const_iterator
, const Key
>
82 typedef void_ptr_iterator
<
83 BOOST_DEDUCED_TYPENAME
84 mpl::eval_if_c
<Ordered
,
85 select_iterator
<VoidPtrSet
>,
86 select_local_iterator
<VoidPtrSet
> >::type
,
90 typedef void_ptr_iterator
<
91 BOOST_DEDUCED_TYPENAME
92 mpl::eval_if_c
<Ordered
,
93 select_iterator
<VoidPtrSet
>,
94 select_const_local_iterator
<VoidPtrSet
> >::type
,
98 template< class Iter
>
99 static Key
* get_pointer( Iter i
)
101 return static_cast<Key
*>( *i
.base() );
104 template< class Iter
>
105 static const Key
* get_const_pointer( Iter i
)
107 return static_cast<const Key
*>( *i
.base() );
110 BOOST_STATIC_CONSTANT(bool, allow_null
= false );
119 class CloneAllocator
= heap_clone_allocator
,
122 class ptr_set_adapter_base
123 : public ptr_container_detail::associative_ptr_container
< set_config
<Key
,VoidPtrSet
,Ordered
>,
126 typedef ptr_container_detail::associative_ptr_container
< set_config
<Key
,VoidPtrSet
,Ordered
>,
130 typedef BOOST_DEDUCED_TYPENAME
base_type::iterator
132 typedef BOOST_DEDUCED_TYPENAME
base_type::const_iterator
134 typedef Key key_type
;
135 typedef BOOST_DEDUCED_TYPENAME
base_type::size_type
139 ptr_set_adapter_base()
142 template< class SizeType
>
143 ptr_set_adapter_base( SizeType n
,
144 ptr_container_detail::unordered_associative_container_tag tag
)
145 : base_type( n
, tag
)
148 template< class Compare
, class Allocator
>
149 ptr_set_adapter_base( const Compare
& comp
,
151 : base_type( comp
, a
)
154 template< class Hash
, class Pred
, class Allocator
>
155 ptr_set_adapter_base( const Hash
& hash
,
158 : base_type( hash
, pred
, a
)
161 template< class InputIterator
, class Compare
, class Allocator
>
162 ptr_set_adapter_base( InputIterator first
, InputIterator last
,
165 : base_type( first
, last
, comp
, a
)
168 template< class InputIterator
, class Hash
, class Pred
, class Allocator
>
169 ptr_set_adapter_base( InputIterator first
, InputIterator last
,
173 : base_type( first
, last
, hash
, pred
, a
)
176 template< class U
, class Set
, class CA
, bool b
>
177 ptr_set_adapter_base( const ptr_set_adapter_base
<U
,Set
,CA
,b
>& r
)
181 ptr_set_adapter_base( const ptr_set_adapter_base
& r
)
185 template< class PtrContainer
>
186 explicit ptr_set_adapter_base( std::auto_ptr
<PtrContainer
> clone
)
190 ptr_set_adapter_base
& operator=( ptr_set_adapter_base r
)
196 template< typename PtrContainer
>
197 ptr_set_adapter_base
& operator=( std::auto_ptr
<PtrContainer
> clone
)
199 base_type::operator=( clone
);
203 using base_type::erase
;
205 size_type
erase( const key_type
& x
) // nothrow
207 key_type
* key
= const_cast<key_type
*>(&x
);
208 iterator
i( this->base().find( key
) );
209 if( i
== this->end() ) // nothrow
210 return 0u; // nothrow
211 key
= static_cast<key_type
*>(*i
.base()); // nothrow
212 size_type res
= this->base().erase( key
); // nothrow
213 this->remove( key
); // nothrow
218 iterator
find( const key_type
& x
)
220 return iterator( this->base().
221 find( const_cast<key_type
*>(&x
) ) );
224 const_iterator
find( const key_type
& x
) const
226 return const_iterator( this->base().
227 find( const_cast<key_type
*>(&x
) ) );
230 size_type
count( const key_type
& x
) const
232 return this->base().count( const_cast<key_type
*>(&x
) );
235 iterator
lower_bound( const key_type
& x
)
237 return iterator( this->base().
238 lower_bound( const_cast<key_type
*>(&x
) ) );
241 const_iterator
lower_bound( const key_type
& x
) const
243 return const_iterator( this->base().
244 lower_bound( const_cast<key_type
*>(&x
) ) );
247 iterator
upper_bound( const key_type
& x
)
249 return iterator( this->base().
250 upper_bound( const_cast<key_type
*>(&x
) ) );
253 const_iterator
upper_bound( const key_type
& x
) const
255 return const_iterator( this->base().
256 upper_bound( const_cast<key_type
*>(&x
) ) );
259 iterator_range
<iterator
> equal_range( const key_type
& x
)
261 std::pair
<BOOST_DEDUCED_TYPENAME
base_type::ptr_iterator
,
262 BOOST_DEDUCED_TYPENAME
base_type::ptr_iterator
>
264 equal_range( const_cast<key_type
*>(&x
) );
265 return make_iterator_range( iterator( p
.first
),
266 iterator( p
.second
) );
269 iterator_range
<const_iterator
> equal_range( const key_type
& x
) const
271 std::pair
<BOOST_DEDUCED_TYPENAME
base_type::ptr_const_iterator
,
272 BOOST_DEDUCED_TYPENAME
base_type::ptr_const_iterator
>
274 equal_range( const_cast<key_type
*>(&x
) );
275 return make_iterator_range( const_iterator( p
.first
),
276 const_iterator( p
.second
) );
280 size_type
bucket( const key_type
& key
) const
282 return this->base().bucket( const_cast<key_type
*>(&key
) );
286 } // ptr_container_detail
288 /////////////////////////////////////////////////////////////////////////
290 /////////////////////////////////////////////////////////////////////////
296 class CloneAllocator
= heap_clone_allocator
,
299 class ptr_set_adapter
:
300 public ptr_container_detail::ptr_set_adapter_base
<Key
,VoidPtrSet
,CloneAllocator
,Ordered
>
302 typedef ptr_container_detail::ptr_set_adapter_base
<Key
,VoidPtrSet
,CloneAllocator
,Ordered
>
307 typedef BOOST_DEDUCED_TYPENAME
base_type::iterator
309 typedef BOOST_DEDUCED_TYPENAME
base_type::const_iterator
311 typedef BOOST_DEDUCED_TYPENAME
base_type::size_type
313 typedef Key key_type
;
314 typedef BOOST_DEDUCED_TYPENAME
base_type::auto_type
316 typedef BOOST_DEDUCED_TYPENAME
VoidPtrSet::allocator_type
320 template< typename II
>
321 void set_basic_clone_and_insert( II first
, II last
) // basic
323 while( first
!= last
)
325 if( this->find( *first
) == this->end() )
326 insert( CloneAllocator::allocate_clone( *first
) ); // strong, commit
335 template< class SizeType
>
336 ptr_set_adapter( SizeType n
,
337 ptr_container_detail::unordered_associative_container_tag tag
)
338 : base_type( n
, tag
)
341 template< class Comp
>
342 explicit ptr_set_adapter( const Comp
& comp
,
343 const allocator_type
& a
)
344 : base_type( comp
, a
)
346 BOOST_ASSERT( this->empty() );
349 template< class Hash
, class Pred
, class Allocator
>
350 ptr_set_adapter( const Hash
& hash
,
353 : base_type( hash
, pred
, a
)
356 template< class InputIterator
>
357 ptr_set_adapter( InputIterator first
, InputIterator last
)
358 : base_type( first
, last
)
361 template< class InputIterator
, class Compare
, class Allocator
>
362 ptr_set_adapter( InputIterator first
, InputIterator last
,
364 const Allocator a
= Allocator() )
365 : base_type( comp
, a
)
367 BOOST_ASSERT( this->empty() );
368 set_basic_clone_and_insert( first
, last
);
371 template< class InputIterator
, class Hash
, class Pred
, class Allocator
>
372 ptr_set_adapter( InputIterator first
, InputIterator last
,
376 : base_type( first
, last
, hash
, pred
, a
)
379 explicit ptr_set_adapter( const ptr_set_adapter
& r
)
383 template< class U
, class Set
, class CA
, bool b
>
384 explicit ptr_set_adapter( const ptr_set_adapter
<U
,Set
,CA
,b
>& r
)
388 template< class PtrContainer
>
389 explicit ptr_set_adapter( std::auto_ptr
<PtrContainer
> clone
)
393 template< class U
, class Set
, class CA
, bool b
>
394 ptr_set_adapter
& operator=( const ptr_set_adapter
<U
,Set
,CA
,b
>& r
)
396 base_type::operator=( r
);
401 void operator=( std::auto_ptr
<T
> r
)
403 base_type::operator=( r
);
406 std::pair
<iterator
,bool> insert( key_type
* x
) // strong
408 this->enforce_null_policy( x
, "Null pointer in 'ptr_set::insert()'" );
411 std::pair
<BOOST_DEDUCED_TYPENAME
base_type::ptr_iterator
,bool>
412 res
= this->base().insert( x
);
415 return std::make_pair( iterator( res
.first
), res
.second
);
419 std::pair
<iterator
,bool> insert( std::auto_ptr
<U
> x
)
421 return insert( x
.release() );
425 iterator
insert( iterator where
, key_type
* x
) // strong
427 this->enforce_null_policy( x
, "Null pointer in 'ptr_set::insert()'" );
430 BOOST_DEDUCED_TYPENAME
base_type::ptr_iterator
431 res
= this->base().insert( where
.base(), x
);
434 return iterator( res
);
438 iterator
insert( iterator where
, std::auto_ptr
<U
> x
)
440 return insert( where
, x
.release() );
443 template< typename InputIterator
>
444 void insert( InputIterator first
, InputIterator last
) // basic
446 set_basic_clone_and_insert( first
, last
);
449 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
452 template< class Range
>
453 BOOST_DEDUCED_TYPENAME
454 boost::disable_if
< ptr_container_detail::is_pointer_or_integral
<Range
> >::type
455 insert( const Range
& r
)
457 insert( boost::begin(r
), boost::end(r
) );
462 template< class PtrSetAdapter
>
463 bool transfer( BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator object
,
464 PtrSetAdapter
& from
) // strong
466 return this->single_transfer( object
, from
);
469 template< class PtrSetAdapter
>
471 transfer( BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator first
,
472 BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator last
,
473 PtrSetAdapter
& from
) // basic
475 return this->single_transfer( first
, last
, from
);
478 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
481 template< class PtrSetAdapter
, class Range
>
482 BOOST_DEDUCED_TYPENAME
boost::disable_if
< boost::is_same
< Range
,
483 BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator
>,
485 transfer( const Range
& r
, PtrSetAdapter
& from
) // basic
487 return transfer( boost::begin(r
), boost::end(r
), from
);
492 template< class PtrSetAdapter
>
493 size_type
transfer( PtrSetAdapter
& from
) // basic
495 return transfer( from
.begin(), from
.end(), from
);
500 /////////////////////////////////////////////////////////////////////////
501 // ptr_multiset_adapter
502 /////////////////////////////////////////////////////////////////////////
507 class VoidPtrMultiSet
,
508 class CloneAllocator
= heap_clone_allocator
,
511 class ptr_multiset_adapter
:
512 public ptr_container_detail::ptr_set_adapter_base
<Key
,VoidPtrMultiSet
,CloneAllocator
,Ordered
>
514 typedef ptr_container_detail::ptr_set_adapter_base
<Key
,VoidPtrMultiSet
,CloneAllocator
,Ordered
> base_type
;
518 typedef BOOST_DEDUCED_TYPENAME
base_type::iterator
520 typedef BOOST_DEDUCED_TYPENAME
base_type::size_type
522 typedef Key key_type
;
523 typedef BOOST_DEDUCED_TYPENAME
base_type::auto_type
525 typedef BOOST_DEDUCED_TYPENAME
VoidPtrMultiSet::allocator_type
528 template< typename II
>
529 void set_basic_clone_and_insert( II first
, II last
) // basic
531 while( first
!= last
)
533 insert( CloneAllocator::allocate_clone( *first
) ); // strong, commit
539 ptr_multiset_adapter()
542 template< class SizeType
>
543 ptr_multiset_adapter( SizeType n
,
544 ptr_container_detail::unordered_associative_container_tag tag
)
545 : base_type( n
, tag
)
548 template< class Comp
>
549 explicit ptr_multiset_adapter( const Comp
& comp
,
550 const allocator_type
& a
)
551 : base_type( comp
, a
)
554 template< class Hash
, class Pred
, class Allocator
>
555 ptr_multiset_adapter( const Hash
& hash
,
558 : base_type( hash
, pred
, a
)
561 template< class InputIterator
>
562 ptr_multiset_adapter( InputIterator first
, InputIterator last
)
563 : base_type( first
, last
)
566 template< class InputIterator
, class Comp
>
567 ptr_multiset_adapter( InputIterator first
, InputIterator last
,
569 const allocator_type
& a
= allocator_type() )
570 : base_type( comp
, a
)
572 set_basic_clone_and_insert( first
, last
);
575 template< class InputIterator
, class Hash
, class Pred
, class Allocator
>
576 ptr_multiset_adapter( InputIterator first
, InputIterator last
,
580 : base_type( first
, last
, hash
, pred
, a
)
583 template< class U
, class Set
, class CA
, bool b
>
584 explicit ptr_multiset_adapter( const ptr_multiset_adapter
<U
,Set
,CA
,b
>& r
)
588 template< class PtrContainer
>
589 explicit ptr_multiset_adapter( std::auto_ptr
<PtrContainer
> clone
)
593 template< class U
, class Set
, class CA
, bool b
>
594 ptr_multiset_adapter
& operator=( const ptr_multiset_adapter
<U
,Set
,CA
,b
>& r
)
596 base_type::operator=( r
);
601 void operator=( std::auto_ptr
<T
> r
)
603 base_type::operator=( r
);
606 iterator
insert( iterator before
, key_type
* x
) // strong
608 return base_type::insert( before
, x
);
612 iterator
insert( iterator before
, std::auto_ptr
<U
> x
)
614 return insert( before
, x
.release() );
617 iterator
insert( key_type
* x
) // strong
619 this->enforce_null_policy( x
, "Null pointer in 'ptr_multiset::insert()'" );
622 BOOST_DEDUCED_TYPENAME
base_type::ptr_iterator
623 res
= this->base().insert( x
);
625 return iterator( res
);
629 iterator
insert( std::auto_ptr
<U
> x
)
631 return insert( x
.release() );
634 template< typename InputIterator
>
635 void insert( InputIterator first
, InputIterator last
) // basic
637 set_basic_clone_and_insert( first
, last
);
640 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
643 template< class Range
>
644 BOOST_DEDUCED_TYPENAME
645 boost::disable_if
< ptr_container_detail::is_pointer_or_integral
<Range
> >::type
646 insert( const Range
& r
)
648 insert( boost::begin(r
), boost::end(r
) );
653 template< class PtrSetAdapter
>
654 void transfer( BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator object
,
655 PtrSetAdapter
& from
) // strong
657 this->multi_transfer( object
, from
);
660 template< class PtrSetAdapter
>
661 size_type
transfer( BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator first
,
662 BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator last
,
663 PtrSetAdapter
& from
) // basic
665 return this->multi_transfer( first
, last
, from
);
668 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
671 template< class PtrSetAdapter
, class Range
>
672 BOOST_DEDUCED_TYPENAME
boost::disable_if
< boost::is_same
< Range
,
673 BOOST_DEDUCED_TYPENAME
PtrSetAdapter::iterator
>, size_type
>::type
674 transfer( const Range
& r
, PtrSetAdapter
& from
) // basic
676 return transfer( boost::begin(r
), boost::end(r
), from
);
681 template< class PtrSetAdapter
>
682 void transfer( PtrSetAdapter
& from
) // basic
684 transfer( from
.begin(), from
.end(), from
);
685 BOOST_ASSERT( from
.empty() );
690 } // namespace 'boost'