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