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