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