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