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
|
Chris@16
|
13 #ifndef BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP
|
Chris@16
|
14 #define BOOST_PTR_CONTAINER_DETAIL_ASSOCIATIVE_PTR_CONTAINER_HPP
|
Chris@16
|
15
|
Chris@16
|
16 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
17 # pragma once
|
Chris@16
|
18 #endif
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/ptr_container/detail/reversible_ptr_container.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost
|
Chris@16
|
23 {
|
Chris@16
|
24
|
Chris@16
|
25 namespace ptr_container_detail
|
Chris@16
|
26 {
|
Chris@16
|
27 template
|
Chris@16
|
28 <
|
Chris@16
|
29 class Config,
|
Chris@16
|
30 class CloneAllocator
|
Chris@16
|
31 >
|
Chris@16
|
32 class associative_ptr_container :
|
Chris@16
|
33 public reversible_ptr_container<Config,CloneAllocator>
|
Chris@16
|
34 {
|
Chris@16
|
35 typedef reversible_ptr_container<Config,CloneAllocator>
|
Chris@16
|
36 base_type;
|
Chris@16
|
37
|
Chris@16
|
38 typedef BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
|
Chris@16
|
39 scoped_deleter;
|
Chris@16
|
40
|
Chris@16
|
41 typedef BOOST_DEDUCED_TYPENAME Config::container_type
|
Chris@16
|
42 container_type;
|
Chris@16
|
43 public: // typedefs
|
Chris@16
|
44 typedef BOOST_DEDUCED_TYPENAME Config::key_type
|
Chris@16
|
45 key_type;
|
Chris@16
|
46 typedef BOOST_DEDUCED_TYPENAME Config::key_compare
|
Chris@16
|
47 key_compare;
|
Chris@16
|
48 typedef BOOST_DEDUCED_TYPENAME Config::value_compare
|
Chris@16
|
49 value_compare;
|
Chris@16
|
50 typedef BOOST_DEDUCED_TYPENAME Config::hasher
|
Chris@16
|
51 hasher;
|
Chris@16
|
52 typedef BOOST_DEDUCED_TYPENAME Config::key_equal
|
Chris@16
|
53 key_equal;
|
Chris@16
|
54 typedef BOOST_DEDUCED_TYPENAME Config::iterator
|
Chris@16
|
55 iterator;
|
Chris@16
|
56 typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
|
Chris@16
|
57 const_iterator;
|
Chris@16
|
58 typedef BOOST_DEDUCED_TYPENAME Config::local_iterator
|
Chris@16
|
59 local_iterator;
|
Chris@16
|
60 typedef BOOST_DEDUCED_TYPENAME Config::const_local_iterator
|
Chris@16
|
61 const_local_iterator;
|
Chris@16
|
62 typedef BOOST_DEDUCED_TYPENAME base_type::size_type
|
Chris@16
|
63 size_type;
|
Chris@16
|
64 typedef BOOST_DEDUCED_TYPENAME base_type::reference
|
Chris@16
|
65 reference;
|
Chris@16
|
66 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference
|
Chris@16
|
67 const_reference;
|
Chris@16
|
68
|
Chris@16
|
69 public: // foundation
|
Chris@16
|
70 associative_ptr_container()
|
Chris@16
|
71 { }
|
Chris@16
|
72
|
Chris@16
|
73 template< class SizeType >
|
Chris@16
|
74 associative_ptr_container( SizeType n, unordered_associative_container_tag tag )
|
Chris@16
|
75 : base_type( n, tag )
|
Chris@16
|
76 { }
|
Chris@16
|
77
|
Chris@16
|
78 template< class Compare, class Allocator >
|
Chris@16
|
79 associative_ptr_container( const Compare& comp,
|
Chris@16
|
80 const Allocator& a )
|
Chris@16
|
81 : base_type( comp, a, container_type() )
|
Chris@16
|
82 { }
|
Chris@16
|
83
|
Chris@16
|
84 template< class Hash, class Pred, class Allocator >
|
Chris@16
|
85 associative_ptr_container( const Hash& hash,
|
Chris@16
|
86 const Pred& pred,
|
Chris@16
|
87 const Allocator& a )
|
Chris@16
|
88 : base_type( hash, pred, a )
|
Chris@16
|
89 { }
|
Chris@16
|
90
|
Chris@16
|
91 template< class InputIterator, class Compare, class Allocator >
|
Chris@16
|
92 associative_ptr_container( InputIterator first, InputIterator last,
|
Chris@16
|
93 const Compare& comp,
|
Chris@16
|
94 const Allocator& a )
|
Chris@16
|
95 : base_type( first, last, comp, a, container_type() )
|
Chris@16
|
96 { }
|
Chris@16
|
97
|
Chris@16
|
98 template< class InputIterator, class Hash, class Pred, class Allocator >
|
Chris@16
|
99 associative_ptr_container( InputIterator first, InputIterator last,
|
Chris@16
|
100 const Hash& hash,
|
Chris@16
|
101 const Pred& pred,
|
Chris@16
|
102 const Allocator& a )
|
Chris@16
|
103 : base_type( first, last, hash, pred, a )
|
Chris@16
|
104 { }
|
Chris@16
|
105
|
Chris@16
|
106 template< class PtrContainer >
|
Chris@16
|
107 explicit associative_ptr_container( std::auto_ptr<PtrContainer> r )
|
Chris@16
|
108 : base_type( r )
|
Chris@16
|
109 { }
|
Chris@16
|
110
|
Chris@16
|
111 associative_ptr_container( const associative_ptr_container& r )
|
Chris@16
|
112 : base_type( r.begin(), r.end(), container_type() )
|
Chris@16
|
113 { }
|
Chris@16
|
114
|
Chris@16
|
115 template< class C, class V >
|
Chris@16
|
116 associative_ptr_container( const associative_ptr_container<C,V>& r )
|
Chris@16
|
117 : base_type( r.begin(), r.end(), container_type() )
|
Chris@16
|
118 { }
|
Chris@16
|
119
|
Chris@16
|
120 template< class PtrContainer >
|
Chris@16
|
121 associative_ptr_container& operator=( std::auto_ptr<PtrContainer> r ) // nothrow
|
Chris@16
|
122 {
|
Chris@16
|
123 base_type::operator=( r );
|
Chris@16
|
124 return *this;
|
Chris@16
|
125 }
|
Chris@16
|
126
|
Chris@16
|
127 associative_ptr_container& operator=( associative_ptr_container r ) // strong
|
Chris@16
|
128 {
|
Chris@16
|
129 this->swap( r );
|
Chris@16
|
130 return *this;
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 public: // associative container interface
|
Chris@16
|
134 key_compare key_comp() const
|
Chris@16
|
135 {
|
Chris@16
|
136 return this->base().key_comp();
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 value_compare value_comp() const
|
Chris@16
|
140 {
|
Chris@16
|
141 return this->base().value_comp();
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 iterator erase( iterator before ) // nothrow
|
Chris@16
|
145 {
|
Chris@16
|
146 BOOST_ASSERT( !this->empty() );
|
Chris@16
|
147 BOOST_ASSERT( before != this->end() );
|
Chris@16
|
148
|
Chris@16
|
149 this->remove( before ); // nothrow
|
Chris@16
|
150 iterator res( before ); // nothrow
|
Chris@16
|
151 ++res; // nothrow
|
Chris@16
|
152 this->base().erase( before.base() ); // nothrow
|
Chris@16
|
153 return res; // nothrow
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 size_type erase( const key_type& x ) // nothrow
|
Chris@16
|
157 {
|
Chris@16
|
158 iterator i( this->base().find( x ) );
|
Chris@16
|
159 // nothrow
|
Chris@16
|
160 if( i == this->end() ) // nothrow
|
Chris@16
|
161 return 0u; // nothrow
|
Chris@16
|
162 this->remove( i ); // nothrow
|
Chris@16
|
163 return this->base().erase( x ); // nothrow
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 iterator erase( iterator first,
|
Chris@16
|
167 iterator last ) // nothrow
|
Chris@16
|
168 {
|
Chris@16
|
169 iterator res( last ); // nothrow
|
Chris@16
|
170 if( res != this->end() )
|
Chris@16
|
171 ++res; // nothrow
|
Chris@16
|
172
|
Chris@16
|
173 this->remove( first, last ); // nothrow
|
Chris@16
|
174 this->base().erase( first.base(), last.base() ); // nothrow
|
Chris@16
|
175 return res; // nothrow
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
Chris@16
|
179 #else
|
Chris@16
|
180 template< class Range >
|
Chris@16
|
181 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_convertible<Range&,key_type&>,
|
Chris@16
|
182 iterator >::type
|
Chris@16
|
183 erase( const Range& r )
|
Chris@16
|
184 {
|
Chris@16
|
185 return erase( boost::begin(r), boost::end(r) );
|
Chris@16
|
186 }
|
Chris@16
|
187
|
Chris@16
|
188 #endif
|
Chris@16
|
189
|
Chris@16
|
190 protected:
|
Chris@16
|
191
|
Chris@16
|
192 template< class AssociatePtrCont >
|
Chris@16
|
193 void multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
|
Chris@16
|
194 AssociatePtrCont& from ) // strong
|
Chris@16
|
195 {
|
Chris@16
|
196 BOOST_ASSERT( (void*)&from != (void*)this );
|
Chris@16
|
197 BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
Chris@16
|
198
|
Chris@16
|
199 this->base().insert( *object.base() ); // strong
|
Chris@16
|
200 from.base().erase( object.base() ); // nothrow
|
Chris@16
|
201 }
|
Chris@16
|
202
|
Chris@16
|
203 template< class AssociatePtrCont >
|
Chris@16
|
204 size_type multi_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
|
Chris@16
|
205 BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
|
Chris@16
|
206 AssociatePtrCont& from ) // basic
|
Chris@16
|
207 {
|
Chris@16
|
208 BOOST_ASSERT( (void*)&from != (void*)this );
|
Chris@16
|
209
|
Chris@16
|
210 size_type res = 0;
|
Chris@16
|
211 for( ; first != last; )
|
Chris@16
|
212 {
|
Chris@16
|
213 BOOST_ASSERT( first != from.end() );
|
Chris@16
|
214 this->base().insert( *first.base() ); // strong
|
Chris@16
|
215 BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
|
Chris@16
|
216 to_delete( first );
|
Chris@16
|
217 ++first;
|
Chris@16
|
218 from.base().erase( to_delete.base() ); // nothrow
|
Chris@16
|
219 ++res;
|
Chris@16
|
220 }
|
Chris@16
|
221
|
Chris@16
|
222 return res;
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 template< class AssociatePtrCont >
|
Chris@16
|
226 bool single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator object,
|
Chris@16
|
227 AssociatePtrCont& from ) // strong
|
Chris@16
|
228 {
|
Chris@16
|
229 BOOST_ASSERT( (void*)&from != (void*)this );
|
Chris@16
|
230 BOOST_ASSERT( !from.empty() && "Cannot transfer from empty container" );
|
Chris@16
|
231
|
Chris@16
|
232 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
|
Chris@16
|
233 this->base().insert( *object.base() ); // strong
|
Chris@16
|
234 if( p.second )
|
Chris@16
|
235 from.base().erase( object.base() ); // nothrow
|
Chris@16
|
236
|
Chris@16
|
237 return p.second;
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 template< class AssociatePtrCont >
|
Chris@16
|
241 size_type single_transfer( BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator first,
|
Chris@16
|
242 BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator last,
|
Chris@16
|
243 AssociatePtrCont& from ) // basic
|
Chris@16
|
244 {
|
Chris@16
|
245 BOOST_ASSERT( (void*)&from != (void*)this );
|
Chris@16
|
246
|
Chris@16
|
247 size_type res = 0;
|
Chris@16
|
248 for( ; first != last; )
|
Chris@16
|
249 {
|
Chris@16
|
250 BOOST_ASSERT( first != from.end() );
|
Chris@16
|
251 std::pair<BOOST_DEDUCED_TYPENAME base_type::ptr_iterator,bool> p =
|
Chris@16
|
252 this->base().insert( *first.base() ); // strong
|
Chris@16
|
253 BOOST_DEDUCED_TYPENAME AssociatePtrCont::iterator
|
Chris@16
|
254 to_delete( first );
|
Chris@16
|
255 ++first;
|
Chris@16
|
256 if( p.second )
|
Chris@16
|
257 {
|
Chris@16
|
258 from.base().erase( to_delete.base() ); // nothrow
|
Chris@16
|
259 ++res;
|
Chris@16
|
260 }
|
Chris@16
|
261 }
|
Chris@16
|
262 return res;
|
Chris@16
|
263 }
|
Chris@16
|
264
|
Chris@16
|
265 reference front()
|
Chris@16
|
266 {
|
Chris@16
|
267 BOOST_ASSERT( !this->empty() );
|
Chris@16
|
268 BOOST_ASSERT( *this->begin().base() != 0 );
|
Chris@16
|
269 return *this->begin();
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 const_reference front() const
|
Chris@16
|
273 {
|
Chris@16
|
274 return const_cast<associative_ptr_container*>(this)->front();
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 reference back()
|
Chris@16
|
278 {
|
Chris@16
|
279 BOOST_ASSERT( !this->empty() );
|
Chris@16
|
280 BOOST_ASSERT( *(--this->end()).base() != 0 );
|
Chris@16
|
281 return *--this->end();
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 const_reference back() const
|
Chris@16
|
285 {
|
Chris@16
|
286 return const_cast<associative_ptr_container*>(this)->back();
|
Chris@16
|
287 }
|
Chris@16
|
288
|
Chris@16
|
289 protected: // unordered interface
|
Chris@16
|
290 hasher hash_function() const
|
Chris@16
|
291 {
|
Chris@16
|
292 return this->base().hash_function();
|
Chris@16
|
293 }
|
Chris@16
|
294
|
Chris@16
|
295 key_equal key_eq() const
|
Chris@16
|
296 {
|
Chris@16
|
297 return this->base().key_eq();
|
Chris@16
|
298 }
|
Chris@16
|
299
|
Chris@16
|
300 size_type bucket_count() const
|
Chris@16
|
301 {
|
Chris@16
|
302 return this->base().bucket_count();
|
Chris@16
|
303 }
|
Chris@16
|
304
|
Chris@16
|
305 size_type max_bucket_count() const
|
Chris@16
|
306 {
|
Chris@16
|
307 return this->base().max_bucket_count();
|
Chris@16
|
308 }
|
Chris@16
|
309
|
Chris@16
|
310 size_type bucket_size( size_type n ) const
|
Chris@16
|
311 {
|
Chris@16
|
312 return this->base().bucket_size( n );
|
Chris@16
|
313 }
|
Chris@16
|
314
|
Chris@16
|
315 float load_factor() const
|
Chris@16
|
316 {
|
Chris@16
|
317 return this->base().load_factor();
|
Chris@16
|
318 }
|
Chris@16
|
319
|
Chris@16
|
320 float max_load_factor() const
|
Chris@16
|
321 {
|
Chris@16
|
322 return this->base().max_load_factor();
|
Chris@16
|
323 }
|
Chris@16
|
324
|
Chris@16
|
325 void max_load_factor( float factor )
|
Chris@16
|
326 {
|
Chris@16
|
327 return this->base().max_load_factor( factor );
|
Chris@16
|
328 }
|
Chris@16
|
329
|
Chris@16
|
330 void rehash( size_type n )
|
Chris@16
|
331 {
|
Chris@16
|
332 this->base().rehash( n );
|
Chris@16
|
333 }
|
Chris@16
|
334
|
Chris@16
|
335 public:
|
Chris@16
|
336 #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006))
|
Chris@16
|
337 iterator begin()
|
Chris@16
|
338 {
|
Chris@16
|
339 return base_type::begin();
|
Chris@16
|
340 }
|
Chris@16
|
341
|
Chris@16
|
342 const_iterator begin() const
|
Chris@16
|
343 {
|
Chris@16
|
344 return base_type::begin();
|
Chris@16
|
345 }
|
Chris@16
|
346
|
Chris@16
|
347 iterator end()
|
Chris@16
|
348 {
|
Chris@16
|
349 return base_type::end();
|
Chris@16
|
350 }
|
Chris@16
|
351
|
Chris@16
|
352 const_iterator end() const
|
Chris@16
|
353 {
|
Chris@16
|
354 return base_type::end();
|
Chris@16
|
355 }
|
Chris@16
|
356
|
Chris@16
|
357 const_iterator cbegin() const
|
Chris@16
|
358 {
|
Chris@16
|
359 return base_type::cbegin();
|
Chris@16
|
360 }
|
Chris@16
|
361
|
Chris@16
|
362 const_iterator cend() const
|
Chris@16
|
363 {
|
Chris@16
|
364 return base_type::cend();
|
Chris@16
|
365 }
|
Chris@16
|
366 #else
|
Chris@16
|
367 using base_type::begin;
|
Chris@16
|
368 using base_type::end;
|
Chris@16
|
369 using base_type::cbegin;
|
Chris@16
|
370 using base_type::cend;
|
Chris@16
|
371 #endif
|
Chris@16
|
372
|
Chris@16
|
373 protected:
|
Chris@16
|
374 local_iterator begin( size_type n )
|
Chris@16
|
375 {
|
Chris@16
|
376 return local_iterator( this->base().begin( n ) );
|
Chris@16
|
377 }
|
Chris@16
|
378
|
Chris@16
|
379 const_local_iterator begin( size_type n ) const
|
Chris@16
|
380 {
|
Chris@16
|
381 return const_local_iterator( this->base().begin( n ) );
|
Chris@16
|
382 }
|
Chris@16
|
383
|
Chris@16
|
384 local_iterator end( size_type n )
|
Chris@16
|
385 {
|
Chris@16
|
386 return local_iterator( this->base().end( n ) );
|
Chris@16
|
387 }
|
Chris@16
|
388
|
Chris@16
|
389 const_local_iterator end( size_type n ) const
|
Chris@16
|
390 {
|
Chris@16
|
391 return const_local_iterator( this->base().end( n ) );
|
Chris@16
|
392 }
|
Chris@16
|
393
|
Chris@16
|
394 const_local_iterator cbegin( size_type n ) const
|
Chris@16
|
395 {
|
Chris@16
|
396 return const_local_iterator( this->base().cbegin( n ) );
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399 const_local_iterator cend( size_type n )
|
Chris@16
|
400 {
|
Chris@16
|
401 return const_local_iterator( this->base().cend( n ) );
|
Chris@16
|
402 }
|
Chris@16
|
403
|
Chris@16
|
404 }; // class 'associative_ptr_container'
|
Chris@16
|
405
|
Chris@16
|
406 } // namespace 'ptr_container_detail'
|
Chris@16
|
407
|
Chris@16
|
408 } // namespace 'boost'
|
Chris@16
|
409
|
Chris@16
|
410
|
Chris@16
|
411 #endif
|