ossrv_pub/boost_apis/boost/pending/container_traits.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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.
       
    46 namespace 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