Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/pending/container_traits.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // (C) Copyright Jeremy Siek 2004 | |
2 // (C) Copyright Thomas Claveirole 2010 | |
3 // (C) Copyright Ignacy Gawedzki 2010 | |
4 // Distributed under the Boost Software License, Version 1.0. (See | |
5 // accompanying file LICENSE_1_0.txt or copy at | |
6 // http://www.boost.org/LICENSE_1_0.txt) | |
7 | |
8 #ifndef BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H | |
9 #define BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H | |
10 | |
11 // Sure would be nice to be able to forward declare these | |
12 // instead of pulling in all the headers. Too bad that | |
13 // is not legal. There ought to be a standard <stlfwd> header. -JGS | |
14 | |
15 #include <boost/next_prior.hpp> | |
16 | |
17 #include <algorithm> // for std::remove | |
18 #include <vector> | |
19 #include <list> | |
20 #include <map> | |
21 #include <set> | |
22 #include <boost/unordered_set.hpp> | |
23 #include <boost/unordered_map.hpp> | |
24 | |
25 #if !defined BOOST_NO_SLIST | |
26 # ifdef BOOST_SLIST_HEADER | |
27 # include BOOST_SLIST_HEADER | |
28 # else | |
29 # include <slist> | |
30 # endif | |
31 #endif | |
32 | |
33 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |
34 // Stay out of the way of concept checking class templates | |
35 # define Container Container_ | |
36 # define AssociativeContainer AssociativeContainer_ | |
37 #endif | |
38 | |
39 // The content of this file is in 'graph_detail' because otherwise | |
40 // there will be name clashes with | |
41 // sandbox/boost/sequence_algo/container_traits.hpp | |
42 // The 'detail' subnamespace will still cause problems. | |
43 namespace boost { namespace graph_detail { | |
44 | |
45 //====================================================================== | |
46 // Container Category Tags | |
47 // | |
48 // They use virtual inheritance because there are lots of | |
49 // inheritance diamonds. | |
50 | |
51 struct container_tag { }; | |
52 struct forward_container_tag : virtual public container_tag { }; | |
53 struct reversible_container_tag : virtual public forward_container_tag { }; | |
54 struct random_access_container_tag | |
55 : virtual public reversible_container_tag { }; | |
56 | |
57 struct sequence_tag : virtual public forward_container_tag { }; | |
58 | |
59 struct associative_container_tag : virtual public forward_container_tag { }; | |
60 | |
61 struct sorted_associative_container_tag | |
62 : virtual public associative_container_tag, | |
63 virtual public reversible_container_tag { }; | |
64 | |
65 struct front_insertion_sequence_tag : virtual public sequence_tag { }; | |
66 struct back_insertion_sequence_tag : virtual public sequence_tag { }; | |
67 | |
68 struct unique_associative_container_tag | |
69 : virtual public associative_container_tag { }; | |
70 struct multiple_associative_container_tag | |
71 : virtual public associative_container_tag { }; | |
72 struct simple_associative_container_tag | |
73 : virtual public associative_container_tag { }; | |
74 struct pair_associative_container_tag | |
75 : virtual public associative_container_tag { }; | |
76 | |
77 | |
78 //====================================================================== | |
79 // Iterator Stability Tags | |
80 // | |
81 // Do mutating operations such as insert/erase/resize invalidate all | |
82 // outstanding iterators? | |
83 | |
84 struct stable_tag { }; | |
85 struct unstable_tag { }; | |
86 | |
87 //====================================================================== | |
88 // Container Traits Class and container_category() function | |
89 | |
90 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
91 // don't use this unless there is partial specialization | |
92 template <class Container> | |
93 struct container_traits { | |
94 typedef typename Container::category category; | |
95 typedef typename Container::iterator_stability iterator_stability; | |
96 }; | |
97 #endif | |
98 | |
99 // Use this as a compile-time assertion that X is stable | |
100 inline void require_stable(stable_tag) { } | |
101 | |
102 // std::vector | |
103 struct vector_tag : | |
104 virtual public random_access_container_tag, | |
105 virtual public back_insertion_sequence_tag { }; | |
106 | |
107 template <class T, class Alloc> | |
108 vector_tag container_category(const std::vector<T,Alloc>&) | |
109 { return vector_tag(); } | |
110 | |
111 template <class T, class Alloc> | |
112 unstable_tag iterator_stability(const std::vector<T,Alloc>&) | |
113 { return unstable_tag(); } | |
114 | |
115 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
116 template <class T, class Alloc> | |
117 struct container_traits< std::vector<T,Alloc> > { | |
118 typedef vector_tag category; | |
119 typedef unstable_tag iterator_stability; | |
120 }; | |
121 #endif | |
122 | |
123 // std::list | |
124 struct list_tag : | |
125 virtual public reversible_container_tag, | |
126 virtual public back_insertion_sequence_tag | |
127 // this causes problems for push_dispatch... | |
128 // virtual public front_insertion_sequence_tag | |
129 { }; | |
130 | |
131 template <class T, class Alloc> | |
132 list_tag container_category(const std::list<T,Alloc>&) | |
133 { return list_tag(); } | |
134 | |
135 template <class T, class Alloc> | |
136 stable_tag iterator_stability(const std::list<T,Alloc>&) | |
137 { return stable_tag(); } | |
138 | |
139 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
140 template <class T, class Alloc> | |
141 struct container_traits< std::list<T,Alloc> > { | |
142 typedef list_tag category; | |
143 typedef stable_tag iterator_stability; | |
144 }; | |
145 #endif | |
146 | |
147 | |
148 // std::slist | |
149 #ifndef BOOST_NO_SLIST | |
150 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
151 template <class T, class Alloc> | |
152 struct container_traits<BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc> > { | |
153 typedef front_insertion_sequence_tag category; | |
154 typedef stable_tag iterator_stability; | |
155 }; | |
156 #endif | |
157 template <class T, class Alloc> | |
158 front_insertion_sequence_tag container_category( | |
159 const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>& | |
160 ) | |
161 { return front_insertion_sequence_tag(); } | |
162 | |
163 template <class T, class Alloc> | |
164 stable_tag iterator_stability( | |
165 const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&) | |
166 { return stable_tag(); } | |
167 #endif | |
168 | |
169 | |
170 // std::set | |
171 struct set_tag : | |
172 virtual public sorted_associative_container_tag, | |
173 virtual public simple_associative_container_tag, | |
174 virtual public unique_associative_container_tag | |
175 { }; | |
176 | |
177 template <class Key, class Cmp, class Alloc> | |
178 set_tag container_category(const std::set<Key,Cmp,Alloc>&) | |
179 { return set_tag(); } | |
180 | |
181 template <class Key, class Cmp, class Alloc> | |
182 stable_tag iterator_stability(const std::set<Key,Cmp,Alloc>&) | |
183 { return stable_tag(); } | |
184 | |
185 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
186 template <class Key, class Cmp, class Alloc> | |
187 struct container_traits< std::set<Key,Cmp,Alloc> > { | |
188 typedef set_tag category; | |
189 typedef stable_tag iterator_stability; | |
190 }; | |
191 #endif | |
192 | |
193 // std::multiset | |
194 struct multiset_tag : | |
195 virtual public sorted_associative_container_tag, | |
196 virtual public simple_associative_container_tag, | |
197 virtual public multiple_associative_container_tag | |
198 { }; | |
199 | |
200 template <class Key, class Cmp, class Alloc> | |
201 multiset_tag container_category(const std::multiset<Key,Cmp,Alloc>&) | |
202 { return multiset_tag(); } | |
203 | |
204 template <class Key, class Cmp, class Alloc> | |
205 stable_tag iterator_stability(const std::multiset<Key,Cmp,Alloc>&) | |
206 { return stable_tag(); } | |
207 | |
208 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
209 template <class Key, class Cmp, class Alloc> | |
210 struct container_traits< std::multiset<Key,Cmp,Alloc> > { | |
211 typedef multiset_tag category; | |
212 typedef stable_tag iterator_stability; | |
213 }; | |
214 #endif | |
215 | |
216 // deque | |
217 | |
218 // std::map | |
219 struct map_tag : | |
220 virtual public sorted_associative_container_tag, | |
221 virtual public pair_associative_container_tag, | |
222 virtual public unique_associative_container_tag | |
223 { }; | |
224 | |
225 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
226 template <class Key, class T, class Cmp, class Alloc> | |
227 struct container_traits< std::map<Key,T,Cmp,Alloc> > { | |
228 typedef map_tag category; | |
229 typedef stable_tag iterator_stability; | |
230 }; | |
231 #endif | |
232 | |
233 template <class Key, class T, class Cmp, class Alloc> | |
234 map_tag container_category(const std::map<Key,T,Cmp,Alloc>&) | |
235 { return map_tag(); } | |
236 | |
237 template <class Key, class T, class Cmp, class Alloc> | |
238 stable_tag iterator_stability(const std::map<Key,T,Cmp,Alloc>&) | |
239 { return stable_tag(); } | |
240 | |
241 // std::multimap | |
242 struct multimap_tag : | |
243 virtual public sorted_associative_container_tag, | |
244 virtual public pair_associative_container_tag, | |
245 virtual public multiple_associative_container_tag | |
246 { }; | |
247 | |
248 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
249 template <class Key, class T, class Cmp, class Alloc> | |
250 struct container_traits< std::multimap<Key,T,Cmp,Alloc> > { | |
251 typedef multimap_tag category; | |
252 typedef stable_tag iterator_stability; | |
253 }; | |
254 #endif | |
255 | |
256 template <class Key, class T, class Cmp, class Alloc> | |
257 multimap_tag container_category(const std::multimap<Key,T,Cmp,Alloc>&) | |
258 { return multimap_tag(); } | |
259 | |
260 template <class Key, class T, class Cmp, class Alloc> | |
261 stable_tag iterator_stability(const std::multimap<Key,T,Cmp,Alloc>&) | |
262 { return stable_tag(); } | |
263 | |
264 | |
265 // hash_set, hash_map | |
266 | |
267 struct unordered_set_tag : | |
268 virtual public simple_associative_container_tag, | |
269 virtual public unique_associative_container_tag | |
270 { }; | |
271 | |
272 struct unordered_multiset_tag : | |
273 virtual public simple_associative_container_tag, | |
274 virtual public multiple_associative_container_tag | |
275 { }; | |
276 | |
277 | |
278 struct unordered_map_tag : | |
279 virtual public pair_associative_container_tag, | |
280 virtual public unique_associative_container_tag | |
281 { }; | |
282 | |
283 struct unordered_multimap_tag : | |
284 virtual public pair_associative_container_tag, | |
285 virtual public multiple_associative_container_tag | |
286 { }; | |
287 | |
288 | |
289 #ifndef BOOST_NO_HASH | |
290 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | |
291 template <class Key, class Eq, class Hash, class Alloc> | |
292 struct container_traits< boost::unordered_set<Key,Eq,Hash,Alloc> > { | |
293 typedef unordered_set_tag category; | |
294 typedef unstable_tag iterator_stability; | |
295 }; | |
296 template <class Key, class T, class Eq, class Hash, class Alloc> | |
297 struct container_traits< boost::unordered_map<Key,T,Eq,Hash,Alloc> > { | |
298 typedef unordered_map_tag category; | |
299 typedef unstable_tag iterator_stability; | |
300 }; | |
301 template <class Key, class Eq, class Hash, class Alloc> | |
302 struct container_traits< boost::unordered_multiset<Key,Eq,Hash,Alloc> > { | |
303 typedef unordered_multiset_tag category; | |
304 typedef unstable_tag iterator_stability; | |
305 }; | |
306 template <class Key, class T, class Eq, class Hash, class Alloc> | |
307 struct container_traits< boost::unordered_multimap<Key,T,Eq,Hash,Alloc> > { | |
308 typedef unordered_multimap_tag category; | |
309 typedef unstable_tag iterator_stability; | |
310 }; | |
311 #endif | |
312 template <class Key, class Eq, class Hash, class Alloc> | |
313 unordered_set_tag | |
314 container_category(const boost::unordered_set<Key,Eq,Hash,Alloc>&) | |
315 { return unordered_set_tag(); } | |
316 | |
317 template <class Key, class T, class Eq, class Hash, class Alloc> | |
318 unordered_map_tag | |
319 container_category(const boost::unordered_map<Key,T,Eq,Hash,Alloc>&) | |
320 { return unordered_map_tag(); } | |
321 | |
322 template <class Key, class Eq, class Hash, class Alloc> | |
323 unstable_tag iterator_stability(const boost::unordered_set<Key,Eq,Hash,Alloc>&) | |
324 { return unstable_tag(); } | |
325 | |
326 template <class Key, class T, class Eq, class Hash, class Alloc> | |
327 unstable_tag iterator_stability(const boost::unordered_map<Key,T,Eq,Hash,Alloc>&) | |
328 { return unstable_tag(); } | |
329 template <class Key, class Eq, class Hash, class Alloc> | |
330 unordered_multiset_tag | |
331 container_category(const boost::unordered_multiset<Key,Eq,Hash,Alloc>&) | |
332 { return unordered_multiset_tag(); } | |
333 | |
334 template <class Key, class T, class Eq, class Hash, class Alloc> | |
335 unordered_multimap_tag | |
336 container_category(const boost::unordered_multimap<Key,T,Eq,Hash,Alloc>&) | |
337 { return unordered_multimap_tag(); } | |
338 | |
339 template <class Key, class Eq, class Hash, class Alloc> | |
340 unstable_tag | |
341 iterator_stability(const boost::unordered_multiset<Key,Eq,Hash,Alloc>&) | |
342 { return unstable_tag(); } | |
343 | |
344 template <class Key, class T, class Eq, class Hash, class Alloc> | |
345 unstable_tag | |
346 iterator_stability(const boost::unordered_multimap<Key,T,Eq,Hash,Alloc>&) | |
347 { return unstable_tag(); } | |
348 #endif | |
349 | |
350 | |
351 | |
352 //=========================================================================== | |
353 // Generalized Container Functions | |
354 | |
355 | |
356 // Erase | |
357 template <class Sequence, class T> | |
358 void erase_dispatch(Sequence& c, const T& x, | |
359 sequence_tag) | |
360 { | |
361 c.erase(std::remove(c.begin(), c.end(), x), c.end()); | |
362 } | |
363 | |
364 template <class AssociativeContainer, class T> | |
365 void erase_dispatch(AssociativeContainer& c, const T& x, | |
366 associative_container_tag) | |
367 { | |
368 c.erase(x); | |
369 } | |
370 template <class Container, class T> | |
371 void erase(Container& c, const T& x) | |
372 { | |
373 erase_dispatch(c, x, container_category(c)); | |
374 } | |
375 | |
376 // Erase If | |
377 template <class Sequence, class Predicate, class IteratorStability> | |
378 void erase_if_dispatch(Sequence& c, Predicate p, | |
379 sequence_tag, IteratorStability) | |
380 { | |
381 #if 0 | |
382 c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); | |
383 #else | |
384 if (! c.empty()) | |
385 c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); | |
386 #endif | |
387 } | |
388 template <class AssociativeContainer, class Predicate> | |
389 void erase_if_dispatch(AssociativeContainer& c, Predicate p, | |
390 associative_container_tag, stable_tag) | |
391 { | |
392 typename AssociativeContainer::iterator i, next; | |
393 for (i = next = c.begin(); next != c.end(); i = next) { | |
394 ++next; | |
395 if (p(*i)) | |
396 c.erase(i); | |
397 } | |
398 } | |
399 template <class AssociativeContainer, class Predicate> | |
400 void erase_if_dispatch(AssociativeContainer& c, Predicate p, | |
401 associative_container_tag, unstable_tag) | |
402 { | |
403 // This method is really slow, so hopefully we won't have any | |
404 // associative containers with unstable iterators! | |
405 // Is there a better way to do this? | |
406 typename AssociativeContainer::iterator i; | |
407 typename AssociativeContainer::size_type n = c.size(); | |
408 while (n--) | |
409 for (i = c.begin(); i != c.end(); ++i) | |
410 if (p(*i)) { | |
411 c.erase(i); | |
412 break; | |
413 } | |
414 } | |
415 template <class Container, class Predicate> | |
416 void erase_if(Container& c, Predicate p) | |
417 { | |
418 erase_if_dispatch(c, p, container_category(c), iterator_stability(c)); | |
419 } | |
420 | |
421 // Push | |
422 template <class Container, class T> | |
423 std::pair<typename Container::iterator, bool> | |
424 push_dispatch(Container& c, const T& v, back_insertion_sequence_tag) | |
425 { | |
426 c.push_back(v); | |
427 return std::make_pair(boost::prior(c.end()), true); | |
428 } | |
429 | |
430 template <class Container, class T> | |
431 std::pair<typename Container::iterator, bool> | |
432 push_dispatch(Container& c, const T& v, front_insertion_sequence_tag) | |
433 { | |
434 c.push_front(v); | |
435 return std::make_pair(c.begin(), true); | |
436 } | |
437 | |
438 template <class AssociativeContainer, class T> | |
439 std::pair<typename AssociativeContainer::iterator, bool> | |
440 push_dispatch(AssociativeContainer& c, const T& v, | |
441 unique_associative_container_tag) | |
442 { | |
443 return c.insert(v); | |
444 } | |
445 | |
446 template <class AssociativeContainer, class T> | |
447 std::pair<typename AssociativeContainer::iterator, bool> | |
448 push_dispatch(AssociativeContainer& c, const T& v, | |
449 multiple_associative_container_tag) | |
450 { | |
451 return std::make_pair(c.insert(v), true); | |
452 } | |
453 | |
454 template <class Container, class T> | |
455 std::pair<typename Container::iterator,bool> | |
456 push(Container& c, const T& v) | |
457 { | |
458 return push_dispatch(c, v, container_category(c)); | |
459 } | |
460 | |
461 // Find | |
462 template <class Container, class Value> | |
463 typename Container::iterator | |
464 find_dispatch(Container& c, | |
465 const Value& value, | |
466 container_tag) | |
467 { | |
468 return std::find(c.begin(), c.end(), value); | |
469 } | |
470 | |
471 template <class AssociativeContainer, class Value> | |
472 typename AssociativeContainer::iterator | |
473 find_dispatch(AssociativeContainer& c, | |
474 const Value& value, | |
475 associative_container_tag) | |
476 { | |
477 return c.find(value); | |
478 } | |
479 | |
480 template <class Container, class Value> | |
481 typename Container::iterator | |
482 find(Container& c, | |
483 const Value& value) | |
484 { | |
485 return find_dispatch(c, value, | |
486 graph_detail::container_category(c)); | |
487 } | |
488 | |
489 // Find (const versions) | |
490 template <class Container, class Value> | |
491 typename Container::const_iterator | |
492 find_dispatch(const Container& c, | |
493 const Value& value, | |
494 container_tag) | |
495 { | |
496 return std::find(c.begin(), c.end(), value); | |
497 } | |
498 | |
499 template <class AssociativeContainer, class Value> | |
500 typename AssociativeContainer::const_iterator | |
501 find_dispatch(const AssociativeContainer& c, | |
502 const Value& value, | |
503 associative_container_tag) | |
504 { | |
505 return c.find(value); | |
506 } | |
507 | |
508 template <class Container, class Value> | |
509 typename Container::const_iterator | |
510 find(const Container& c, | |
511 const Value& value) | |
512 { | |
513 return find_dispatch(c, value, | |
514 graph_detail::container_category(c)); | |
515 } | |
516 | |
517 // Equal range | |
518 #if 0 | |
519 // Make the dispatch fail if c is not an Associative Container (and thus | |
520 // doesn't have equal_range unless it is sorted, which we cannot check | |
521 // statically and is not typically true for BGL's uses of this function). | |
522 template <class Container, | |
523 class LessThanComparable> | |
524 std::pair<typename Container::iterator, typename Container::iterator> | |
525 equal_range_dispatch(Container& c, | |
526 const LessThanComparable& value, | |
527 container_tag) | |
528 { | |
529 // c must be sorted for std::equal_range to behave properly. | |
530 return std::equal_range(c.begin(), c.end(), value); | |
531 } | |
532 #endif | |
533 | |
534 template <class AssociativeContainer, class Value> | |
535 std::pair<typename AssociativeContainer::iterator, | |
536 typename AssociativeContainer::iterator> | |
537 equal_range_dispatch(AssociativeContainer& c, | |
538 const Value& value, | |
539 associative_container_tag) | |
540 { | |
541 return c.equal_range(value); | |
542 } | |
543 | |
544 template <class Container, class Value> | |
545 std::pair<typename Container::iterator, typename Container::iterator> | |
546 equal_range(Container& c, | |
547 const Value& value) | |
548 { | |
549 return equal_range_dispatch(c, value, | |
550 graph_detail::container_category(c)); | |
551 } | |
552 | |
553 }} // namespace boost::graph_detail | |
554 | |
555 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |
556 // Stay out of the way of concept checking class templates | |
557 # undef Container | |
558 # undef AssociativeContainer | |
559 #endif | |
560 | |
561 #endif // BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H |