Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/pending/container_traits.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 12.8 KB
Line 
1//  (C) Copyright Jeremy Siek 2004
2//  Distributed under the Boost Software License, Version 1.0. (See
3//  accompanying file LICENSE_1_0.txt or copy at
4//  http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
7#define BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
8
9// Sure would be nice to be able to forward declare these
10// instead of pulling in all the headers. Too bad that
11// is not legal. There ought to be a standard <stlfwd> header. -JGS
12
13#include <boost/next_prior.hpp>
14
15#include <algorithm>   // for std::remove
16#include <vector>
17#include <list>
18#include <map>
19#include <set>
20
21#if !defined BOOST_NO_HASH
22#  ifdef BOOST_HASH_SET_HEADER
23#    include BOOST_HASH_SET_HEADER
24#  else
25#    include <hash_set>
26#  endif
27#  ifdef BOOST_HASH_MAP_HEADER
28#    include BOOST_HASH_MAP_HEADER
29#  else
30#    include <hash_map>
31#  endif
32#endif
33
34#if !defined BOOST_NO_SLIST
35#  ifdef BOOST_SLIST_HEADER
36#    include BOOST_SLIST_HEADER
37#  else
38#    include <slist>
39#  endif
40#endif
41
42// The content of this file is in 'graph_detail' because otherwise
43// there will be name clashes with
44// sandbox/boost/sequence_algo/container_traits.hpp
45// The 'detail' subnamespace will still cause problems.
46namespace boost { namespace graph_detail {
47
48  //======================================================================
49  // Container Category Tags
50  //
51  //   They use virtual inheritance because there are lots of
52  //   inheritance diamonds.
53
54  struct container_tag { };
55  struct forward_container_tag : virtual public container_tag { };
56  struct reversible_container_tag : virtual public forward_container_tag { };
57  struct random_access_container_tag
58    : virtual public reversible_container_tag { };
59 
60  struct sequence_tag : virtual public forward_container_tag { };
61
62  struct associative_container_tag : virtual public forward_container_tag { };
63
64  struct sorted_associative_container_tag 
65    : virtual public associative_container_tag,
66      virtual public reversible_container_tag { };
67
68  struct front_insertion_sequence_tag : virtual public sequence_tag { };
69  struct back_insertion_sequence_tag : virtual public sequence_tag { };
70
71  struct unique_associative_container_tag 
72    : virtual public associative_container_tag { };
73  struct multiple_associative_container_tag 
74    : virtual public associative_container_tag { };
75  struct simple_associative_container_tag 
76    : virtual public associative_container_tag { };
77  struct pair_associative_container_tag 
78    : virtual public associative_container_tag { };
79
80
81  //======================================================================
82  // Iterator Stability Tags
83  //
84  // Do mutating operations such as insert/erase/resize invalidate all
85  // outstanding iterators?
86
87  struct stable_tag { };
88  struct unstable_tag { };
89
90  //======================================================================
91  // Container Traits Class and container_category() function
92
93#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
94  // don't use this unless there is partial specialization
95  template <class Container>
96  struct container_traits {
97    typedef typename Container::category category;
98    typedef typename Container::iterator_stability iterator_stability;
99  };
100#endif
101
102  // Use this as a compile-time assertion that X is stable
103  inline void require_stable(stable_tag) { }
104
105  // std::vector
106  struct vector_tag :
107    virtual public random_access_container_tag,
108    virtual public back_insertion_sequence_tag { };
109
110  template <class T, class Alloc>
111  vector_tag container_category(const std::vector<T,Alloc>&)
112    { return vector_tag(); }
113
114  template <class T, class Alloc>
115  unstable_tag iterator_stability(const std::vector<T,Alloc>&)
116    { return unstable_tag(); }
117
118#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
119  template <class T, class Alloc>
120  struct container_traits< std::vector<T,Alloc> > {
121    typedef vector_tag category;
122    typedef unstable_tag iterator_stability;
123  };
124#endif
125
126  // std::list
127  struct list_tag :
128    virtual public reversible_container_tag,
129    virtual public back_insertion_sequence_tag
130    // this causes problems for push_dispatch...
131    //    virtual public front_insertion_sequence_tag
132    { };
133
134  template <class T, class Alloc>
135  list_tag container_category(const std::list<T,Alloc>&)
136    { return list_tag(); }
137
138  template <class T, class Alloc>
139  stable_tag iterator_stability(const std::list<T,Alloc>&)
140    { return stable_tag(); }
141
142#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
143  template <class T, class Alloc>
144  struct container_traits< std::list<T,Alloc> > {
145    typedef list_tag category;
146    typedef stable_tag iterator_stability;
147  };
148#endif
149
150
151  // std::slist
152#ifndef BOOST_NO_SLIST
153# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
154  template <class T, class Alloc>
155  struct container_traits<BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc> > {
156    typedef front_insertion_sequence_tag category;
157    typedef stable_tag iterator_stability;
158  };
159#endif
160  template <class T, class Alloc>
161  front_insertion_sequence_tag container_category(
162  const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&
163  )
164    { return front_insertion_sequence_tag(); }
165
166  template <class T, class Alloc>
167  stable_tag iterator_stability(
168  const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&)
169    { return stable_tag(); }
170#endif
171
172
173  // std::set
174  struct set_tag :
175    virtual public sorted_associative_container_tag,
176    virtual public simple_associative_container_tag,
177    virtual public unique_associative_container_tag
178    { };
179
180  template <class Key, class Cmp, class Alloc> 
181  set_tag container_category(const std::set<Key,Cmp,Alloc>&)
182  { return set_tag(); }
183
184  template <class Key, class Cmp, class Alloc> 
185  stable_tag iterator_stability(const std::set<Key,Cmp,Alloc>&)
186  { return stable_tag(); }
187
188#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
189  template <class Key, class Cmp, class Alloc> 
190  struct container_traits< std::set<Key,Cmp,Alloc> > {
191    typedef set_tag category;
192    typedef stable_tag iterator_stability;
193  };
194#endif
195
196  // std::multiset
197  struct multiset_tag :
198    virtual public sorted_associative_container_tag,
199    virtual public simple_associative_container_tag,
200    virtual public multiple_associative_container_tag
201    { };
202
203  template <class Key, class Cmp, class Alloc> 
204  multiset_tag container_category(const std::multiset<Key,Cmp,Alloc>&)
205  { return multiset_tag(); }
206
207  template <class Key, class Cmp, class Alloc> 
208  stable_tag iterator_stability(const std::multiset<Key,Cmp,Alloc>&)
209  { return stable_tag(); }
210
211#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
212  template <class Key, class Cmp, class Alloc> 
213  struct container_traits< std::multiset<Key,Cmp,Alloc> > {
214    typedef multiset_tag category;
215    typedef stable_tag iterator_stability;
216  };
217#endif
218
219  // deque
220
221  // std::map
222  struct map_tag :
223    virtual public sorted_associative_container_tag,
224    virtual public pair_associative_container_tag,
225    virtual public unique_associative_container_tag
226    { };
227
228#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
229  template <class Key, class T, class Cmp, class Alloc> 
230  struct container_traits< std::map<Key,T,Cmp,Alloc> > {
231    typedef map_tag category;
232    typedef stable_tag iterator_stability;
233  };
234#endif
235
236  template <class Key, class T, class Cmp, class Alloc> 
237  map_tag container_category(const std::map<Key,T,Cmp,Alloc>&)
238  { return map_tag(); }
239
240  template <class Key, class T, class Cmp, class Alloc> 
241  stable_tag iterator_stability(const std::map<Key,T,Cmp,Alloc>&)
242  { return stable_tag(); }
243
244  // std::multimap
245  struct multimap_tag :
246    virtual public sorted_associative_container_tag,
247    virtual public pair_associative_container_tag,
248    virtual public multiple_associative_container_tag
249    { };
250
251#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
252  template <class Key, class T, class Cmp, class Alloc> 
253  struct container_traits< std::multimap<Key,T,Cmp,Alloc> > {
254    typedef multimap_tag category;
255    typedef stable_tag iterator_stability;
256  };
257#endif
258
259  template <class Key, class T, class Cmp, class Alloc> 
260  multimap_tag container_category(const std::multimap<Key,T,Cmp,Alloc>&)
261  { return multimap_tag(); }
262
263  template <class Key, class T, class Cmp, class Alloc> 
264  stable_tag iterator_stability(const std::multimap<Key,T,Cmp,Alloc>&)
265  { return stable_tag(); }
266
267
268 // hash_set, hash_map
269
270#ifndef BOOST_NO_HASH
271#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
272  template <class Key, class Eq, class Hash, class Alloc> 
273  struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc> > {
274    typedef set_tag category;
275    typedef stable_tag iterator_stability; // is this right?
276  };
277  template <class Key, class T, class Eq, class Hash, class Alloc>
278  struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc> > {
279    typedef map_tag category;
280    typedef stable_tag iterator_stability; // is this right?
281  };
282#endif
283  template <class Key, class Eq, class Hash, class Alloc>
284  set_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc>&)
285  { return set_tag(); }
286
287  template <class Key, class T, class Eq, class Hash, class Alloc>
288  map_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc>&)
289  { return map_tag(); }
290
291  template <class Key, class Eq, class Hash, class Alloc>
292  stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc>&)
293  { return stable_tag(); }
294
295  template <class Key, class T, class Eq, class Hash, class Alloc>
296  stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc>&)
297  { return stable_tag(); }
298#endif
299
300
301
302  //===========================================================================
303  // Generalized Container Functions
304
305
306  // Erase
307  template <class Sequence, class T>
308  void erase_dispatch(Sequence& c, const T& x, 
309                      sequence_tag)
310  {
311    c.erase(std::remove(c.begin(), c.end(), x), c.end());
312  }
313
314  template <class AssociativeContainer, class T>
315  void erase_dispatch(AssociativeContainer& c, const T& x, 
316                      associative_container_tag)
317  {
318    c.erase(x);
319  }
320  template <class Container, class T>
321  void erase(Container& c, const T& x)
322  {
323    erase_dispatch(c, x, container_category(c));
324  }
325
326  // Erase If
327  template <class Sequence, class Predicate, class IteratorStability>
328  void erase_if_dispatch(Sequence& c, Predicate p,
329                         sequence_tag, IteratorStability)
330  {
331#if 0
332    c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
333#else
334    if (! c.empty())
335      c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
336#endif
337  }
338  template <class AssociativeContainer, class Predicate>
339  void erase_if_dispatch(AssociativeContainer& c, Predicate p,
340                         associative_container_tag, stable_tag)
341  {
342    typename AssociativeContainer::iterator i, next;
343    for (i = next = c.begin(); next != c.end(); i = next) {
344      ++next;
345      if (p(*i))
346        c.erase(i);
347    }
348  }
349  template <class AssociativeContainer, class Predicate>
350  void erase_if_dispatch(AssociativeContainer& c, Predicate p,
351                         associative_container_tag, unstable_tag)
352  {
353    // This method is really slow, so hopefully we won't have any
354    // associative containers with unstable iterators!
355    // Is there a better way to do this?
356    typename AssociativeContainer::iterator i;
357    typename AssociativeContainer::size_type n = c.size();
358    while (n--)
359      for (i = c.begin(); i != c.end(); ++i)
360        if (p(*i)) {
361          c.erase(i);
362          break;
363        }
364  }
365  template <class Container, class Predicate>
366  void erase_if(Container& c, Predicate p)
367  {
368    erase_if_dispatch(c, p, container_category(c), iterator_stability(c));
369  }
370
371  // Push
372  template <class Container, class T>
373  std::pair<typename Container::iterator, bool>
374  push_dispatch(Container& c, const T& v, back_insertion_sequence_tag)
375  {
376    c.push_back(v);
377    return std::make_pair(boost::prior(c.end()), true);
378  }
379
380  template <class Container, class T>
381  std::pair<typename Container::iterator, bool>
382  push_dispatch(Container& c, const T& v, front_insertion_sequence_tag)
383  {
384    c.push_front(v);
385    return std::make_pair(c.begin(), true);
386  }
387
388  template <class AssociativeContainer, class T>
389  std::pair<typename AssociativeContainer::iterator, bool>
390  push_dispatch(AssociativeContainer& c, const T& v, 
391                unique_associative_container_tag)
392  {
393    return c.insert(v);
394  }
395
396  template <class AssociativeContainer, class T>
397  std::pair<typename AssociativeContainer::iterator, bool>
398  push_dispatch(AssociativeContainer& c, const T& v,
399                multiple_associative_container_tag)
400  {
401    return std::make_pair(c.insert(v), true);
402  }
403
404  template <class Container, class T>
405  std::pair<typename Container::iterator,bool>
406  push(Container& c, const T& v)
407  {
408    return push_dispatch(c, v, container_category(c));
409  }
410
411}} // namespace boost::graph_detail
412
413#endif // BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
Note: See TracBrowser for help on using the repository browser.