os/ossrv/ossrv_pub/boost_apis/boost/property_map.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
//  (C) Copyright Jeremy Siek 1999-2001.
sl@0
     2
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     3
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     4
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     5
sl@0
     6
//  See http://www.boost.org/libs/property_map for documentation.
sl@0
     7
sl@0
     8
#ifndef BOOST_PROPERTY_MAP_HPP
sl@0
     9
#define BOOST_PROPERTY_MAP_HPP
sl@0
    10
sl@0
    11
#include <cassert>
sl@0
    12
#include <boost/config.hpp>
sl@0
    13
#include <boost/pending/cstddef.hpp>
sl@0
    14
#include <boost/detail/iterator.hpp>
sl@0
    15
#include <boost/concept_check.hpp>
sl@0
    16
#include <boost/concept_archetype.hpp>
sl@0
    17
sl@0
    18
namespace boost {
sl@0
    19
sl@0
    20
  //=========================================================================
sl@0
    21
  // property_traits class
sl@0
    22
sl@0
    23
  template <typename PA>
sl@0
    24
  struct property_traits {
sl@0
    25
    typedef typename PA::key_type key_type;
sl@0
    26
    typedef typename PA::value_type value_type; 
sl@0
    27
    typedef typename PA::reference reference;
sl@0
    28
    typedef typename PA::category   category;
sl@0
    29
  };
sl@0
    30
sl@0
    31
  //=========================================================================
sl@0
    32
  // property_traits category tags
sl@0
    33
sl@0
    34
  namespace detail {
sl@0
    35
    enum ePropertyMapID { READABLE_PA, WRITABLE_PA, 
sl@0
    36
                          READ_WRITE_PA, LVALUE_PA, OP_BRACKET_PA, 
sl@0
    37
                          RAND_ACCESS_ITER_PA, LAST_PA };
sl@0
    38
  }
sl@0
    39
  struct readable_property_map_tag { enum { id = detail::READABLE_PA }; };
sl@0
    40
  struct writable_property_map_tag { enum { id = detail::WRITABLE_PA }; };
sl@0
    41
  struct read_write_property_map_tag :
sl@0
    42
    public readable_property_map_tag,
sl@0
    43
    public writable_property_map_tag
sl@0
    44
  { enum { id = detail::READ_WRITE_PA }; };
sl@0
    45
sl@0
    46
  struct lvalue_property_map_tag : public read_write_property_map_tag
sl@0
    47
  { enum { id = detail::LVALUE_PA }; };
sl@0
    48
sl@0
    49
  //=========================================================================
sl@0
    50
  // property_traits specialization for pointers
sl@0
    51
sl@0
    52
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
sl@0
    53
  // The user will just have to create their own specializations for
sl@0
    54
  // other pointers types if the compiler does not have partial
sl@0
    55
  // specializations. Sorry!
sl@0
    56
#define BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(TYPE) \
sl@0
    57
  template <> \
sl@0
    58
  struct property_traits<TYPE*> { \
sl@0
    59
    typedef TYPE value_type; \
sl@0
    60
    typedef value_type& reference; \
sl@0
    61
    typedef std::ptrdiff_t key_type; \
sl@0
    62
    typedef lvalue_property_map_tag   category; \
sl@0
    63
  }; \
sl@0
    64
  template <> \
sl@0
    65
  struct property_traits<const TYPE*> { \
sl@0
    66
    typedef TYPE value_type; \
sl@0
    67
    typedef const value_type& reference; \
sl@0
    68
    typedef std::ptrdiff_t key_type; \
sl@0
    69
    typedef lvalue_property_map_tag   category; \
sl@0
    70
  }
sl@0
    71
sl@0
    72
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(long);
sl@0
    73
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned long);
sl@0
    74
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(int);
sl@0
    75
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned int);
sl@0
    76
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(short);
sl@0
    77
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned short);
sl@0
    78
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(char);
sl@0
    79
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(unsigned char);
sl@0
    80
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(signed char);
sl@0
    81
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(bool);
sl@0
    82
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(float);
sl@0
    83
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(double);
sl@0
    84
  BOOST_SPECIALIZE_PROPERTY_TRAITS_PTR(long double);
sl@0
    85
sl@0
    86
  // This may need to be turned off for some older compilers that don't have
sl@0
    87
  // wchar_t intrinsically.
sl@0
    88
# ifndef BOOST_NO_INTRINSIC_WCHAR_T
sl@0
    89
  template <>
sl@0
    90
  struct property_traits<wchar_t*> {
sl@0
    91
    typedef wchar_t value_type;
sl@0
    92
    typedef value_type& reference;
sl@0
    93
    typedef std::ptrdiff_t key_type;
sl@0
    94
    typedef lvalue_property_map_tag   category;
sl@0
    95
  };
sl@0
    96
  template <>
sl@0
    97
  struct property_traits<const wchar_t*> {
sl@0
    98
    typedef wchar_t value_type;
sl@0
    99
    typedef const value_type& reference;
sl@0
   100
    typedef std::ptrdiff_t key_type;
sl@0
   101
    typedef lvalue_property_map_tag   category;
sl@0
   102
  };
sl@0
   103
# endif
sl@0
   104
sl@0
   105
#else
sl@0
   106
  template <class T>
sl@0
   107
  struct property_traits<T*> {
sl@0
   108
    typedef T value_type;
sl@0
   109
    typedef value_type& reference;
sl@0
   110
    typedef std::ptrdiff_t key_type;
sl@0
   111
    typedef lvalue_property_map_tag category;
sl@0
   112
  };
sl@0
   113
  template <class T>
sl@0
   114
  struct property_traits<const T*> {
sl@0
   115
    typedef T value_type;
sl@0
   116
    typedef const value_type& reference;
sl@0
   117
    typedef std::ptrdiff_t key_type;
sl@0
   118
    typedef lvalue_property_map_tag category;
sl@0
   119
  };
sl@0
   120
#endif
sl@0
   121
sl@0
   122
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
sl@0
   123
  // MSVC doesn't have Koenig lookup, so the user has to
sl@0
   124
  // do boost::get() anyways, and the using clause
sl@0
   125
  // doesn't really work for MSVC.
sl@0
   126
} // namespace boost
sl@0
   127
#endif
sl@0
   128
sl@0
   129
  // These need to go in global namespace because Koenig
sl@0
   130
  // lookup does not apply to T*.
sl@0
   131
sl@0
   132
  // V must be convertible to T
sl@0
   133
  template <class T, class V>
sl@0
   134
  inline void put(T* pa, std::ptrdiff_t k, const V& val) { pa[k] = val;  }
sl@0
   135
sl@0
   136
  template <class T>
sl@0
   137
  inline const T& get(const T* pa, std::ptrdiff_t k) { return pa[k]; }
sl@0
   138
sl@0
   139
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
sl@0
   140
namespace boost {
sl@0
   141
  using ::put;
sl@0
   142
  using ::get;
sl@0
   143
#endif
sl@0
   144
sl@0
   145
  //=========================================================================
sl@0
   146
  // concept checks for property maps
sl@0
   147
sl@0
   148
  template <class PMap, class Key>
sl@0
   149
  struct ReadablePropertyMapConcept
sl@0
   150
  {
sl@0
   151
    typedef typename property_traits<PMap>::key_type key_type;
sl@0
   152
    typedef typename property_traits<PMap>::reference reference;
sl@0
   153
    typedef typename property_traits<PMap>::category Category;
sl@0
   154
    typedef boost::readable_property_map_tag ReadableTag;
sl@0
   155
    void constraints() {
sl@0
   156
      function_requires< ConvertibleConcept<Category, ReadableTag> >();
sl@0
   157
sl@0
   158
      val = get(pmap, k);
sl@0
   159
    }
sl@0
   160
    PMap pmap;
sl@0
   161
    Key k;
sl@0
   162
    typename property_traits<PMap>::value_type val;
sl@0
   163
  };
sl@0
   164
  template <typename KeyArchetype, typename ValueArchetype>
sl@0
   165
  struct readable_property_map_archetype {
sl@0
   166
    typedef KeyArchetype key_type;
sl@0
   167
    typedef ValueArchetype value_type;
sl@0
   168
    typedef convertible_to_archetype<ValueArchetype> reference;
sl@0
   169
    typedef readable_property_map_tag category;
sl@0
   170
  };
sl@0
   171
  template <typename K, typename V>
sl@0
   172
  const typename readable_property_map_archetype<K,V>::reference&
sl@0
   173
  get(const readable_property_map_archetype<K,V>&, 
sl@0
   174
      const typename readable_property_map_archetype<K,V>::key_type&)
sl@0
   175
  {
sl@0
   176
    typedef typename readable_property_map_archetype<K,V>::reference R;
sl@0
   177
    return static_object<R>::get();
sl@0
   178
  }
sl@0
   179
sl@0
   180
sl@0
   181
  template <class PMap, class Key>
sl@0
   182
  struct WritablePropertyMapConcept
sl@0
   183
  {
sl@0
   184
    typedef typename property_traits<PMap>::key_type key_type;
sl@0
   185
    typedef typename property_traits<PMap>::category Category;
sl@0
   186
    typedef boost::writable_property_map_tag WritableTag;
sl@0
   187
    void constraints() {
sl@0
   188
      function_requires< ConvertibleConcept<Category, WritableTag> >();
sl@0
   189
      put(pmap, k, val);
sl@0
   190
    }
sl@0
   191
    PMap pmap;
sl@0
   192
    Key k;
sl@0
   193
    typename property_traits<PMap>::value_type val;
sl@0
   194
  };
sl@0
   195
  template <typename KeyArchetype, typename ValueArchetype>
sl@0
   196
  struct writable_property_map_archetype {
sl@0
   197
    typedef KeyArchetype key_type;
sl@0
   198
    typedef ValueArchetype value_type;
sl@0
   199
    typedef void reference;
sl@0
   200
    typedef writable_property_map_tag category;
sl@0
   201
  };
sl@0
   202
  template <typename K, typename V>
sl@0
   203
  void put(const writable_property_map_archetype<K,V>&, 
sl@0
   204
           const typename writable_property_map_archetype<K,V>::key_type&, 
sl@0
   205
           const typename writable_property_map_archetype<K,V>::value_type&) { }
sl@0
   206
sl@0
   207
sl@0
   208
  template <class PMap, class Key>
sl@0
   209
  struct ReadWritePropertyMapConcept
sl@0
   210
  {
sl@0
   211
    typedef typename property_traits<PMap>::category Category;
sl@0
   212
    typedef boost::read_write_property_map_tag ReadWriteTag;
sl@0
   213
    void constraints() {
sl@0
   214
      function_requires< ReadablePropertyMapConcept<PMap, Key> >();
sl@0
   215
      function_requires< WritablePropertyMapConcept<PMap, Key> >();
sl@0
   216
      function_requires< ConvertibleConcept<Category, ReadWriteTag> >();
sl@0
   217
    }
sl@0
   218
  };
sl@0
   219
  template <typename KeyArchetype, typename ValueArchetype>
sl@0
   220
  struct read_write_property_map_archetype
sl@0
   221
    : public readable_property_map_archetype<KeyArchetype, ValueArchetype>,
sl@0
   222
      public writable_property_map_archetype<KeyArchetype, ValueArchetype>
sl@0
   223
  {
sl@0
   224
    typedef KeyArchetype key_type;
sl@0
   225
    typedef ValueArchetype value_type;
sl@0
   226
    typedef convertible_to_archetype<ValueArchetype> reference;
sl@0
   227
    typedef read_write_property_map_tag category;
sl@0
   228
  };
sl@0
   229
sl@0
   230
sl@0
   231
  template <class PMap, class Key>
sl@0
   232
  struct LvaluePropertyMapConcept
sl@0
   233
  {
sl@0
   234
    typedef typename property_traits<PMap>::category Category;
sl@0
   235
    typedef boost::lvalue_property_map_tag LvalueTag;
sl@0
   236
    typedef typename property_traits<PMap>::reference reference;
sl@0
   237
sl@0
   238
    void constraints() {
sl@0
   239
      function_requires< ReadablePropertyMapConcept<PMap, Key> >();
sl@0
   240
      function_requires< ConvertibleConcept<Category, LvalueTag> >();
sl@0
   241
sl@0
   242
      typedef typename property_traits<PMap>::value_type value_type;
sl@0
   243
      typedef typename require_same<
sl@0
   244
        const value_type&, reference>::type req;
sl@0
   245
sl@0
   246
      reference ref = pmap[k];
sl@0
   247
      ignore_unused_variable_warning(ref);
sl@0
   248
    }
sl@0
   249
    PMap pmap;
sl@0
   250
    Key k;
sl@0
   251
  };
sl@0
   252
  template <typename KeyArchetype, typename ValueArchetype>
sl@0
   253
  struct lvalue_property_map_archetype
sl@0
   254
    : public readable_property_map_archetype<KeyArchetype, ValueArchetype>
sl@0
   255
  {
sl@0
   256
    typedef KeyArchetype key_type;
sl@0
   257
    typedef ValueArchetype value_type;
sl@0
   258
    typedef const ValueArchetype& reference;
sl@0
   259
    typedef lvalue_property_map_tag category;
sl@0
   260
    const value_type& operator[](const key_type&) const {
sl@0
   261
      return static_object<value_type>::get();
sl@0
   262
    }
sl@0
   263
  };
sl@0
   264
sl@0
   265
  template <class PMap, class Key>
sl@0
   266
  struct Mutable_LvaluePropertyMapConcept
sl@0
   267
  {
sl@0
   268
    typedef typename property_traits<PMap>::category Category;
sl@0
   269
    typedef boost::lvalue_property_map_tag LvalueTag;
sl@0
   270
    typedef typename property_traits<PMap>::reference reference;
sl@0
   271
    void constraints() { 
sl@0
   272
      boost::function_requires< ReadWritePropertyMapConcept<PMap, Key> >();
sl@0
   273
      boost::function_requires<ConvertibleConcept<Category, LvalueTag> >();
sl@0
   274
      
sl@0
   275
      typedef typename property_traits<PMap>::value_type value_type;
sl@0
   276
      typedef typename require_same<
sl@0
   277
        value_type&,
sl@0
   278
        reference>::type req;
sl@0
   279
sl@0
   280
      reference ref = pmap[k];
sl@0
   281
      ignore_unused_variable_warning(ref);
sl@0
   282
    }
sl@0
   283
    PMap pmap;
sl@0
   284
    Key k;
sl@0
   285
  };
sl@0
   286
  template <typename KeyArchetype, typename ValueArchetype>
sl@0
   287
  struct mutable_lvalue_property_map_archetype
sl@0
   288
    : public readable_property_map_archetype<KeyArchetype, ValueArchetype>,
sl@0
   289
      public writable_property_map_archetype<KeyArchetype, ValueArchetype>
sl@0
   290
  {
sl@0
   291
    typedef KeyArchetype key_type;
sl@0
   292
    typedef ValueArchetype value_type;
sl@0
   293
    typedef ValueArchetype& reference;
sl@0
   294
    typedef lvalue_property_map_tag category;
sl@0
   295
    value_type& operator[](const key_type&) const { 
sl@0
   296
      return static_object<value_type>::get();
sl@0
   297
    }
sl@0
   298
  };
sl@0
   299
sl@0
   300
  struct identity_property_map;
sl@0
   301
sl@0
   302
  // A helper class for constructing a property map
sl@0
   303
  // from a class that implements operator[]
sl@0
   304
sl@0
   305
  template <class Reference, class LvaluePropertyMap>
sl@0
   306
  struct put_get_helper { };
sl@0
   307
sl@0
   308
  template <class PropertyMap, class Reference, class K>
sl@0
   309
  inline Reference
sl@0
   310
  get(const put_get_helper<Reference, PropertyMap>& pa, const K& k)
sl@0
   311
  {
sl@0
   312
    Reference v = static_cast<const PropertyMap&>(pa)[k];
sl@0
   313
    return v;
sl@0
   314
  }
sl@0
   315
  template <class PropertyMap, class Reference, class K, class V>
sl@0
   316
  inline void
sl@0
   317
  put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v)
sl@0
   318
  {
sl@0
   319
    static_cast<const PropertyMap&>(pa)[k] = v;
sl@0
   320
  }
sl@0
   321
sl@0
   322
  //=========================================================================
sl@0
   323
  // Adapter to turn a RandomAccessIterator into a property map
sl@0
   324
sl@0
   325
  template <class RandomAccessIterator, 
sl@0
   326
    class IndexMap
sl@0
   327
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
sl@0
   328
    , class T, class R
sl@0
   329
#else
sl@0
   330
    , class T = typename std::iterator_traits<RandomAccessIterator>::value_type
sl@0
   331
    , class R = typename std::iterator_traits<RandomAccessIterator>::reference
sl@0
   332
#endif
sl@0
   333
     >
sl@0
   334
  class iterator_property_map
sl@0
   335
    : public boost::put_get_helper< R, 
sl@0
   336
        iterator_property_map<RandomAccessIterator, IndexMap,
sl@0
   337
        T, R> >
sl@0
   338
  {
sl@0
   339
  public:
sl@0
   340
    typedef typename property_traits<IndexMap>::key_type key_type;
sl@0
   341
    typedef T value_type;
sl@0
   342
    typedef R reference;
sl@0
   343
    typedef boost::lvalue_property_map_tag category;
sl@0
   344
sl@0
   345
    inline iterator_property_map(
sl@0
   346
      RandomAccessIterator cc = RandomAccessIterator(), 
sl@0
   347
      const IndexMap& _id = IndexMap() ) 
sl@0
   348
      : iter(cc), index(_id) { }
sl@0
   349
    inline R operator[](key_type v) const { return *(iter + get(index, v)) ; }
sl@0
   350
  protected:
sl@0
   351
    RandomAccessIterator iter;
sl@0
   352
    IndexMap index;
sl@0
   353
  };
sl@0
   354
sl@0
   355
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
sl@0
   356
  template <class RAIter, class ID>
sl@0
   357
  inline iterator_property_map<
sl@0
   358
    RAIter, ID,
sl@0
   359
    typename std::iterator_traits<RAIter>::value_type,
sl@0
   360
    typename std::iterator_traits<RAIter>::reference>
sl@0
   361
  make_iterator_property_map(RAIter iter, ID id) {
sl@0
   362
    function_requires< RandomAccessIteratorConcept<RAIter> >();
sl@0
   363
    typedef iterator_property_map<
sl@0
   364
      RAIter, ID,
sl@0
   365
      typename std::iterator_traits<RAIter>::value_type,
sl@0
   366
      typename std::iterator_traits<RAIter>::reference> PA;
sl@0
   367
    return PA(iter, id);
sl@0
   368
  }
sl@0
   369
#endif
sl@0
   370
  template <class RAIter, class Value, class ID>
sl@0
   371
  inline iterator_property_map<RAIter, ID, Value, Value&>
sl@0
   372
  make_iterator_property_map(RAIter iter, ID id, Value) {
sl@0
   373
    function_requires< RandomAccessIteratorConcept<RAIter> >();
sl@0
   374
    typedef iterator_property_map<RAIter, ID, Value, Value&> PMap;
sl@0
   375
    return PMap(iter, id);
sl@0
   376
  }
sl@0
   377
sl@0
   378
  template <class RandomAccessIterator, 
sl@0
   379
    class IndexMap
sl@0
   380
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
sl@0
   381
    , class T, class R
sl@0
   382
#else
sl@0
   383
    , class T = typename std::iterator_traits<RandomAccessIterator>::value_type
sl@0
   384
    , class R = typename std::iterator_traits<RandomAccessIterator>::reference
sl@0
   385
#endif
sl@0
   386
     >
sl@0
   387
  class safe_iterator_property_map
sl@0
   388
    : public boost::put_get_helper< R, 
sl@0
   389
        safe_iterator_property_map<RandomAccessIterator, IndexMap,
sl@0
   390
        T, R> >
sl@0
   391
  {
sl@0
   392
  public:
sl@0
   393
    typedef typename property_traits<IndexMap>::key_type key_type; 
sl@0
   394
    typedef T value_type;
sl@0
   395
    typedef R reference;
sl@0
   396
    typedef boost::lvalue_property_map_tag category;
sl@0
   397
sl@0
   398
    inline safe_iterator_property_map(
sl@0
   399
      RandomAccessIterator first, 
sl@0
   400
      std::size_t n_ = 0, 
sl@0
   401
      const IndexMap& _id = IndexMap() ) 
sl@0
   402
      : iter(first), n(n_), index(_id) { }
sl@0
   403
    inline safe_iterator_property_map() { }
sl@0
   404
    inline R operator[](key_type v) const {
sl@0
   405
      assert(get(index, v) < n);
sl@0
   406
      return *(iter + get(index, v)) ;
sl@0
   407
    }
sl@0
   408
    typename property_traits<IndexMap>::value_type size() const { return n; }
sl@0
   409
  protected:
sl@0
   410
    RandomAccessIterator iter;
sl@0
   411
    typename property_traits<IndexMap>::value_type n;
sl@0
   412
    IndexMap index;
sl@0
   413
  };
sl@0
   414
sl@0
   415
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
sl@0
   416
  template <class RAIter, class ID>
sl@0
   417
  inline safe_iterator_property_map<
sl@0
   418
    RAIter, ID,
sl@0
   419
    typename boost::detail::iterator_traits<RAIter>::value_type,
sl@0
   420
    typename boost::detail::iterator_traits<RAIter>::reference>
sl@0
   421
  make_safe_iterator_property_map(RAIter iter, std::size_t n, ID id) {
sl@0
   422
    function_requires< RandomAccessIteratorConcept<RAIter> >();
sl@0
   423
    typedef safe_iterator_property_map<
sl@0
   424
      RAIter, ID,
sl@0
   425
      typename boost::detail::iterator_traits<RAIter>::value_type,
sl@0
   426
      typename boost::detail::iterator_traits<RAIter>::reference> PA;
sl@0
   427
    return PA(iter, n, id);
sl@0
   428
  }
sl@0
   429
#endif
sl@0
   430
  template <class RAIter, class Value, class ID>
sl@0
   431
  inline safe_iterator_property_map<RAIter, ID, Value, Value&>
sl@0
   432
  make_safe_iterator_property_map(RAIter iter, std::size_t n, ID id, Value) {
sl@0
   433
    function_requires< RandomAccessIteratorConcept<RAIter> >();
sl@0
   434
    typedef safe_iterator_property_map<RAIter, ID, Value, Value&> PMap;
sl@0
   435
    return PMap(iter, n, id);
sl@0
   436
  }
sl@0
   437
sl@0
   438
  //=========================================================================
sl@0
   439
  // An adaptor to turn a Unique Pair Associative Container like std::map or
sl@0
   440
  // std::hash_map into an Lvalue Property Map.
sl@0
   441
sl@0
   442
  template <typename UniquePairAssociativeContainer>
sl@0
   443
  class associative_property_map
sl@0
   444
    : public boost::put_get_helper<
sl@0
   445
       typename UniquePairAssociativeContainer::value_type::second_type&,
sl@0
   446
       associative_property_map<UniquePairAssociativeContainer> >
sl@0
   447
  {
sl@0
   448
    typedef UniquePairAssociativeContainer C;
sl@0
   449
  public:
sl@0
   450
    typedef typename C::key_type key_type;
sl@0
   451
    typedef typename C::value_type::second_type value_type;
sl@0
   452
    typedef value_type& reference;
sl@0
   453
    typedef lvalue_property_map_tag category;
sl@0
   454
    associative_property_map() : m_c(0) { }
sl@0
   455
    associative_property_map(C& c) : m_c(&c) { }
sl@0
   456
    reference operator[](const key_type& k) const {
sl@0
   457
      return (*m_c)[k];
sl@0
   458
    }
sl@0
   459
  private:
sl@0
   460
    C* m_c;
sl@0
   461
  };
sl@0
   462
sl@0
   463
  template <class UniquePairAssociativeContainer>
sl@0
   464
  associative_property_map<UniquePairAssociativeContainer>
sl@0
   465
  make_assoc_property_map(UniquePairAssociativeContainer& c)
sl@0
   466
  {
sl@0
   467
    return associative_property_map<UniquePairAssociativeContainer>(c);
sl@0
   468
  }
sl@0
   469
sl@0
   470
  template <typename UniquePairAssociativeContainer>
sl@0
   471
  class const_associative_property_map
sl@0
   472
    : public boost::put_get_helper<
sl@0
   473
       const typename UniquePairAssociativeContainer::value_type::second_type&,
sl@0
   474
       const_associative_property_map<UniquePairAssociativeContainer> >
sl@0
   475
  {
sl@0
   476
    typedef UniquePairAssociativeContainer C;
sl@0
   477
  public:
sl@0
   478
    typedef typename C::key_type key_type;
sl@0
   479
    typedef typename C::value_type::second_type value_type;
sl@0
   480
    typedef const value_type& reference;
sl@0
   481
    typedef lvalue_property_map_tag category;
sl@0
   482
    const_associative_property_map() : m_c(0) { }
sl@0
   483
    const_associative_property_map(const C& c) : m_c(&c) { }
sl@0
   484
    reference operator[](const key_type& k) const {
sl@0
   485
      return m_c->find(k)->second;
sl@0
   486
    }
sl@0
   487
  private:
sl@0
   488
    C const* m_c;
sl@0
   489
  };
sl@0
   490
  
sl@0
   491
  template <class UniquePairAssociativeContainer>
sl@0
   492
  const_associative_property_map<UniquePairAssociativeContainer>
sl@0
   493
  make_assoc_property_map(const UniquePairAssociativeContainer& c)
sl@0
   494
  {
sl@0
   495
    return const_associative_property_map<UniquePairAssociativeContainer>(c);
sl@0
   496
  }
sl@0
   497
sl@0
   498
  //=========================================================================
sl@0
   499
  // A property map that applies the identity function to integers
sl@0
   500
  struct identity_property_map
sl@0
   501
    : public boost::put_get_helper<std::size_t, 
sl@0
   502
        identity_property_map>
sl@0
   503
  {
sl@0
   504
    typedef std::size_t key_type;
sl@0
   505
    typedef std::size_t value_type;
sl@0
   506
    typedef std::size_t reference;
sl@0
   507
    typedef boost::readable_property_map_tag category;
sl@0
   508
sl@0
   509
    inline value_type operator[](const key_type& v) const { return v; }
sl@0
   510
  };
sl@0
   511
sl@0
   512
  //=========================================================================
sl@0
   513
  // A property map that does not do anything, for
sl@0
   514
  // when you have to supply a property map, but don't need it.
sl@0
   515
  namespace detail {
sl@0
   516
    struct dummy_pmap_reference {
sl@0
   517
      template <class T>
sl@0
   518
      dummy_pmap_reference& operator=(const T&) { return *this; }
sl@0
   519
      operator int() { return 0; }
sl@0
   520
    };
sl@0
   521
  }
sl@0
   522
  class dummy_property_map 
sl@0
   523
    : public boost::put_get_helper<detail::dummy_pmap_reference,
sl@0
   524
        dummy_property_map  > 
sl@0
   525
  {
sl@0
   526
  public:
sl@0
   527
    typedef void key_type; 
sl@0
   528
    typedef int value_type;
sl@0
   529
    typedef detail::dummy_pmap_reference reference;
sl@0
   530
    typedef boost::read_write_property_map_tag category;
sl@0
   531
    inline dummy_property_map() : c(0) { }
sl@0
   532
    inline dummy_property_map(value_type cc) : c(cc) { }
sl@0
   533
    inline dummy_property_map(const dummy_property_map& x)
sl@0
   534
      : c(x.c) { }
sl@0
   535
    template <class Vertex>
sl@0
   536
    inline reference operator[](Vertex) const { return reference(); }
sl@0
   537
   protected:
sl@0
   538
    value_type c;
sl@0
   539
  };
sl@0
   540
sl@0
   541
sl@0
   542
} // namespace boost
sl@0
   543
sl@0
   544
sl@0
   545
#endif /* BOOST_PROPERTY_MAP_HPP */
sl@0
   546