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'