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 |
|
---|