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