|
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_PTR_SET_ADAPTER_HPP |
|
13 #define BOOST_PTR_CONTAINER_PTR_SET_ADAPTER_HPP |
|
14 |
|
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
|
16 # pragma once |
|
17 #endif |
|
18 |
|
19 #include <boost/ptr_container/detail/associative_ptr_container.hpp> |
|
20 #include <boost/ptr_container/detail/void_ptr_iterator.hpp> |
|
21 #include <boost/range/iterator_range.hpp> |
|
22 |
|
23 namespace boost |
|
24 { |
|
25 namespace ptr_container_detail |
|
26 { |
|
27 template |
|
28 < |
|
29 class Key, |
|
30 class VoidPtrSet |
|
31 > |
|
32 struct set_config |
|
33 { |
|
34 typedef VoidPtrSet |
|
35 void_container_type; |
|
36 |
|
37 typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type |
|
38 allocator_type; |
|
39 |
|
40 typedef Key value_type; |
|
41 |
|
42 typedef value_type |
|
43 key_type; |
|
44 |
|
45 typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::value_compare |
|
46 value_compare; |
|
47 |
|
48 typedef value_compare |
|
49 key_compare; |
|
50 |
|
51 typedef void_ptr_iterator< |
|
52 BOOST_DEDUCED_TYPENAME VoidPtrSet::iterator, Key > |
|
53 iterator; |
|
54 |
|
55 typedef void_ptr_iterator< |
|
56 BOOST_DEDUCED_TYPENAME VoidPtrSet::const_iterator, const Key > |
|
57 const_iterator; |
|
58 |
|
59 template< class Iter > |
|
60 static Key* get_pointer( Iter i ) |
|
61 { |
|
62 return static_cast<Key*>( *i.base() ); |
|
63 } |
|
64 |
|
65 template< class Iter > |
|
66 static const Key* get_const_pointer( Iter i ) |
|
67 { |
|
68 return static_cast<const Key*>( *i.base() ); |
|
69 } |
|
70 |
|
71 BOOST_STATIC_CONSTANT(bool, allow_null = false ); |
|
72 }; |
|
73 |
|
74 |
|
75 |
|
76 template |
|
77 < |
|
78 class Key, |
|
79 class VoidPtrSet, |
|
80 class CloneAllocator = heap_clone_allocator |
|
81 > |
|
82 class ptr_set_adapter_base |
|
83 : public ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet>, |
|
84 CloneAllocator > |
|
85 { |
|
86 typedef ptr_container_detail::associative_ptr_container< set_config<Key,VoidPtrSet>, |
|
87 CloneAllocator > |
|
88 base_type; |
|
89 public: |
|
90 typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
|
91 iterator; |
|
92 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator |
|
93 const_iterator; |
|
94 typedef Key key_type; |
|
95 typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
|
96 size_type; |
|
97 |
|
98 private: |
|
99 ptr_set_adapter_base() |
|
100 : base_type( BOOST_DEDUCED_TYPENAME VoidPtrSet::key_compare(), |
|
101 BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type() ) |
|
102 { } |
|
103 |
|
104 public: |
|
105 |
|
106 template< class Compare, class Allocator > |
|
107 ptr_set_adapter_base( const Compare& comp, |
|
108 const Allocator& a ) |
|
109 : base_type( comp, a ) |
|
110 { } |
|
111 |
|
112 template< class InputIterator, class Compare, class Allocator > |
|
113 ptr_set_adapter_base( InputIterator first, InputIterator last, |
|
114 const Compare& comp, |
|
115 const Allocator& a ) |
|
116 : base_type( first, last, comp, a ) |
|
117 { } |
|
118 |
|
119 template< class PtrContainer > |
|
120 ptr_set_adapter_base( std::auto_ptr<PtrContainer> clone ) |
|
121 : base_type( clone ) |
|
122 { } |
|
123 |
|
124 template< typename PtrContainer > |
|
125 void operator=( std::auto_ptr<PtrContainer> clone ) |
|
126 { |
|
127 base_type::operator=( clone ); |
|
128 } |
|
129 |
|
130 iterator find( const key_type& x ) |
|
131 { |
|
132 return iterator( this->c_private(). |
|
133 find( const_cast<key_type*>(&x) ) ); |
|
134 } |
|
135 |
|
136 const_iterator find( const key_type& x ) const |
|
137 { |
|
138 return const_iterator( this->c_private(). |
|
139 find( const_cast<key_type*>(&x) ) ); |
|
140 } |
|
141 |
|
142 size_type count( const key_type& x ) const |
|
143 { |
|
144 return this->c_private().count( const_cast<key_type*>(&x) ); |
|
145 } |
|
146 |
|
147 iterator lower_bound( const key_type& x ) |
|
148 { |
|
149 return iterator( this->c_private(). |
|
150 lower_bound( const_cast<key_type*>(&x) ) ); |
|
151 } |
|
152 |
|
153 const_iterator lower_bound( const key_type& x ) const |
|
154 { |
|
155 return const_iterator( this->c_private(). |
|
156 lower_bound( const_cast<key_type*>(&x) ) ); |
|
157 } |
|
158 |
|
159 iterator upper_bound( const key_type& x ) |
|
160 { |
|
161 return iterator( this->c_private(). |
|
162 upper_bound( const_cast<key_type*>(&x) ) ); |
|
163 } |
|
164 |
|
165 const_iterator upper_bound( const key_type& x ) const |
|
166 { |
|
167 return const_iterator( this->c_private(). |
|
168 upper_bound( const_cast<key_type*>(&x) ) ); |
|
169 } |
|
170 |
|
171 iterator_range<iterator> equal_range( const key_type& x ) |
|
172 { |
|
173 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator, |
|
174 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator> |
|
175 p = this->c_private(). |
|
176 equal_range( const_cast<key_type*>(&x) ); |
|
177 return make_iterator_range( iterator( p.first ), |
|
178 iterator( p.second ) ); |
|
179 } |
|
180 |
|
181 iterator_range<const_iterator> equal_range( const key_type& x ) const |
|
182 { |
|
183 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator, |
|
184 BOOST_DEDUCED_TYPENAME base_type::ptr_const_iterator> |
|
185 p = this->c_private(). |
|
186 equal_range( const_cast<key_type*>(&x) ); |
|
187 return make_iterator_range( const_iterator( p.first ), |
|
188 const_iterator( p.second ) ); |
|
189 } |
|
190 |
|
191 }; |
|
192 |
|
193 } // ptr_container_detail |
|
194 |
|
195 ///////////////////////////////////////////////////////////////////////// |
|
196 // ptr_set_adapter |
|
197 ///////////////////////////////////////////////////////////////////////// |
|
198 |
|
199 template |
|
200 < |
|
201 class Key, |
|
202 class VoidPtrSet, |
|
203 class CloneAllocator = heap_clone_allocator |
|
204 > |
|
205 class ptr_set_adapter : |
|
206 public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator> |
|
207 { |
|
208 typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrSet,CloneAllocator> |
|
209 base_type; |
|
210 |
|
211 public: // typedefs |
|
212 |
|
213 typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
|
214 iterator; |
|
215 typedef BOOST_DEDUCED_TYPENAME base_type::const_iterator |
|
216 const_iterator; |
|
217 typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
|
218 size_type; |
|
219 typedef Key key_type; |
|
220 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type |
|
221 auto_type; |
|
222 typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::key_compare |
|
223 key_compare; |
|
224 typedef BOOST_DEDUCED_TYPENAME VoidPtrSet::allocator_type |
|
225 allocator_type; |
|
226 private: |
|
227 |
|
228 template< typename II > |
|
229 void set_basic_clone_and_insert( II first, II last ) // basic |
|
230 { |
|
231 while( first != last ) |
|
232 { |
|
233 if( this->find( *first ) == this->end() ) |
|
234 insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit |
|
235 ++first; |
|
236 } |
|
237 } |
|
238 |
|
239 public: |
|
240 |
|
241 explicit ptr_set_adapter( const key_compare& comp = key_compare(), |
|
242 const allocator_type& a = allocator_type() ) |
|
243 : base_type( comp, a ) |
|
244 { |
|
245 BOOST_ASSERT( this->empty() ); |
|
246 } |
|
247 |
|
248 template< class InputIterator, class Compare, class Allocator > |
|
249 ptr_set_adapter( InputIterator first, InputIterator last, |
|
250 const Compare& comp = Compare(), |
|
251 const Allocator a = Allocator() ) |
|
252 : base_type( comp, a ) |
|
253 { |
|
254 BOOST_ASSERT( this->empty() ); |
|
255 set_basic_clone_and_insert( first, last ); |
|
256 } |
|
257 |
|
258 template< class T > |
|
259 ptr_set_adapter( std::auto_ptr<T> r ) : base_type( r ) |
|
260 { } |
|
261 |
|
262 template< class T > |
|
263 void operator=( std::auto_ptr<T> r ) |
|
264 { |
|
265 base_type::operator=( r ); |
|
266 } |
|
267 |
|
268 std::pair<iterator,bool> insert( key_type* x ) // strong |
|
269 { |
|
270 this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" ); |
|
271 |
|
272 auto_type ptr( x ); |
|
273 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> |
|
274 res = this->c_private().insert( x ); |
|
275 if( res.second ) |
|
276 ptr.release(); |
|
277 return std::make_pair( iterator( res.first ), res.second ); |
|
278 } |
|
279 |
|
280 template< class U > |
|
281 std::pair<iterator,bool> insert( std::auto_ptr<U> x ) |
|
282 { |
|
283 return insert( x.release() ); |
|
284 } |
|
285 |
|
286 |
|
287 iterator insert( iterator where, key_type* x ) // strong |
|
288 { |
|
289 this->enforce_null_policy( x, "Null pointer in 'ptr_set::insert()'" ); |
|
290 |
|
291 auto_type ptr( x ); |
|
292 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator |
|
293 res = this->c_private().insert( where.base(), x ); |
|
294 if( *res == x ) |
|
295 ptr.release(); |
|
296 return iterator( res); |
|
297 } |
|
298 |
|
299 template< class U > |
|
300 iterator insert( iterator where, std::auto_ptr<U> x ) |
|
301 { |
|
302 return insert( where, x.release() ); |
|
303 } |
|
304 |
|
305 template< typename InputIterator > |
|
306 void insert( InputIterator first, InputIterator last ) // basic |
|
307 { |
|
308 set_basic_clone_and_insert( first, last ); |
|
309 } |
|
310 |
|
311 #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
|
312 #else |
|
313 |
|
314 template< class Range > |
|
315 BOOST_DEDUCED_TYPENAME |
|
316 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type |
|
317 insert( const Range& r ) |
|
318 { |
|
319 insert( boost::begin(r), boost::end(r) ); |
|
320 } |
|
321 |
|
322 #endif |
|
323 |
|
324 template< class PtrSetAdapter > |
|
325 bool transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, |
|
326 PtrSetAdapter& from ) // strong |
|
327 { |
|
328 return this->single_transfer( object, from ); |
|
329 } |
|
330 |
|
331 template< class PtrSetAdapter > |
|
332 size_type |
|
333 transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, |
|
334 BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, |
|
335 PtrSetAdapter& from ) // basic |
|
336 { |
|
337 return this->single_transfer( first, last, from ); |
|
338 } |
|
339 |
|
340 #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
|
341 #else |
|
342 |
|
343 template< class PtrSetAdapter, class Range > |
|
344 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, |
|
345 BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, |
|
346 size_type >::type |
|
347 transfer( const Range& r, PtrSetAdapter& from ) // basic |
|
348 { |
|
349 return transfer( boost::begin(r), boost::end(r), from ); |
|
350 } |
|
351 |
|
352 #endif |
|
353 |
|
354 template< class PtrSetAdapter > |
|
355 size_type transfer( PtrSetAdapter& from ) // basic |
|
356 { |
|
357 return transfer( from.begin(), from.end(), from ); |
|
358 } |
|
359 |
|
360 }; |
|
361 |
|
362 ///////////////////////////////////////////////////////////////////////// |
|
363 // ptr_multiset_adapter |
|
364 ///////////////////////////////////////////////////////////////////////// |
|
365 |
|
366 template |
|
367 < |
|
368 class Key, |
|
369 class VoidPtrMultiSet, |
|
370 class CloneAllocator = heap_clone_allocator |
|
371 > |
|
372 class ptr_multiset_adapter : |
|
373 public ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator> |
|
374 { |
|
375 typedef ptr_container_detail::ptr_set_adapter_base<Key,VoidPtrMultiSet,CloneAllocator> base_type; |
|
376 |
|
377 public: // typedefs |
|
378 |
|
379 typedef BOOST_DEDUCED_TYPENAME base_type::iterator |
|
380 iterator; |
|
381 typedef BOOST_DEDUCED_TYPENAME base_type::size_type |
|
382 size_type; |
|
383 typedef Key key_type; |
|
384 typedef BOOST_DEDUCED_TYPENAME base_type::auto_type |
|
385 auto_type; |
|
386 typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::key_compare |
|
387 key_compare; |
|
388 typedef BOOST_DEDUCED_TYPENAME VoidPtrMultiSet::allocator_type |
|
389 allocator_type; |
|
390 private: |
|
391 template< typename II > |
|
392 void set_basic_clone_and_insert( II first, II last ) // basic |
|
393 { |
|
394 while( first != last ) |
|
395 { |
|
396 insert( CloneAllocator::allocate_clone( *first ) ); // strong, commit |
|
397 ++first; |
|
398 } |
|
399 } |
|
400 |
|
401 public: |
|
402 |
|
403 explicit ptr_multiset_adapter( const key_compare& comp = key_compare(), |
|
404 const allocator_type& a = allocator_type() ) |
|
405 : base_type( comp, a ) |
|
406 { } |
|
407 |
|
408 template< class InputIterator > |
|
409 ptr_multiset_adapter( InputIterator first, InputIterator last, |
|
410 const key_compare& comp = key_compare(), |
|
411 const allocator_type& a = allocator_type() ) |
|
412 : base_type( comp, a ) |
|
413 { |
|
414 set_basic_clone_and_insert( first, last ); |
|
415 } |
|
416 |
|
417 template< class T > |
|
418 ptr_multiset_adapter( std::auto_ptr<T> r ) : base_type( r ) |
|
419 { } |
|
420 |
|
421 template< class T > |
|
422 void operator=( std::auto_ptr<T> r ) |
|
423 { |
|
424 base_type::operator=( r ); |
|
425 } |
|
426 |
|
427 iterator insert( iterator before, key_type* x ) // strong |
|
428 { |
|
429 return base_type::insert( before, x ); |
|
430 } |
|
431 |
|
432 template< class U > |
|
433 iterator insert( iterator before, std::auto_ptr<U> x ) |
|
434 { |
|
435 return insert( before, x.release() ); |
|
436 } |
|
437 |
|
438 iterator insert( key_type* x ) // strong |
|
439 { |
|
440 this->enforce_null_policy( x, "Null pointer in 'ptr_multiset::insert()'" ); |
|
441 |
|
442 auto_type ptr( x ); |
|
443 BOOST_DEDUCED_TYPENAME base_type::ptr_iterator |
|
444 res = this->c_private().insert( x ); |
|
445 ptr.release(); |
|
446 return iterator( res ); |
|
447 } |
|
448 |
|
449 template< class U > |
|
450 iterator insert( std::auto_ptr<U> x ) |
|
451 { |
|
452 return insert( x.release() ); |
|
453 } |
|
454 |
|
455 template< typename InputIterator > |
|
456 void insert( InputIterator first, InputIterator last ) // basic |
|
457 { |
|
458 set_basic_clone_and_insert( first, last ); |
|
459 } |
|
460 |
|
461 #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
|
462 #else |
|
463 |
|
464 template< class Range > |
|
465 BOOST_DEDUCED_TYPENAME |
|
466 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type |
|
467 insert( const Range& r ) |
|
468 { |
|
469 insert( boost::begin(r), boost::end(r) ); |
|
470 } |
|
471 |
|
472 #endif |
|
473 |
|
474 template< class PtrSetAdapter > |
|
475 void transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator object, |
|
476 PtrSetAdapter& from ) // strong |
|
477 { |
|
478 this->multi_transfer( object, from ); |
|
479 } |
|
480 |
|
481 template< class PtrSetAdapter > |
|
482 size_type transfer( BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator first, |
|
483 BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator last, |
|
484 PtrSetAdapter& from ) // basic |
|
485 { |
|
486 return this->multi_transfer( first, last, from ); |
|
487 } |
|
488 |
|
489 #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) |
|
490 #else |
|
491 |
|
492 template< class PtrSetAdapter, class Range > |
|
493 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range, |
|
494 BOOST_DEDUCED_TYPENAME PtrSetAdapter::iterator >, size_type >::type |
|
495 transfer( const Range& r, PtrSetAdapter& from ) // basic |
|
496 { |
|
497 return transfer( boost::begin(r), boost::end(r), from ); |
|
498 } |
|
499 |
|
500 #endif |
|
501 |
|
502 template< class PtrSetAdapter > |
|
503 void transfer( PtrSetAdapter& from ) // basic |
|
504 { |
|
505 transfer( from.begin(), from.end(), from ); |
|
506 BOOST_ASSERT( from.empty() ); |
|
507 } |
|
508 |
|
509 }; |
|
510 |
|
511 } // namespace 'boost' |
|
512 |
|
513 #endif |