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