]> git.lyx.org Git - lyx.git/blob - boost/boost/property_map.hpp
Upgrade to boost 1.33.1
[lyx.git] / boost / boost / property_map.hpp
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