source: NonGTP/Boost/boost/pending/property.hpp @ 857

Revision 857, 4.1 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Jeremy Siek 2004
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#ifndef BOOST_PROPERTY_HPP
7#define BOOST_PROPERTY_HPP
8
9#include <boost/pending/ct_if.hpp>
10
11namespace boost {
12
13  struct no_property {
14    typedef no_property tag_type;
15    typedef no_property next_type;
16    typedef no_property value_type;
17    enum { num = 0 };
18    typedef void kind;
19  };
20  template <class Tag, class T, class Base = no_property>
21  struct property : public Base {
22    typedef Base next_type;
23    typedef Tag tag_type;
24    typedef T value_type;
25    property() { }
26    property(const T& v) : m_value(v) { }
27    property(const T& v, const Base& b) : Base(b), m_value(v) { }
28    // copy constructor and assignment operator will be generated by compiler
29    T m_value;
30  };
31
32  // The BGL properties specialize property_kind and
33  // property_num, and use enum's for the Property type (see
34  // graph/properties.hpp), but the user may want to use a class
35  // instead with a nested kind type and num.  Also, we may want to
36  // switch BGL back to using class types for properties at some point.
37
38  template <class PropertyTag>
39  struct property_kind {
40    typedef typename PropertyTag::kind type;
41  };
42
43  template <class P>
44  struct has_property {
45    BOOST_STATIC_CONSTANT(bool, value = true);
46    typedef true_type type;
47  };
48  template <>
49  struct has_property<no_property> {
50    BOOST_STATIC_CONSTANT(bool, value = false);
51    typedef false_type type;
52  };
53
54} // namespace boost
55
56#include <boost/pending/detail/property.hpp>
57
58namespace boost {
59
60  template <class PropertyList, class Tag>
61  struct property_value {
62#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
63    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
64    typedef typename detail::extract_value<AList,Tag>::type type;
65#else
66    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
67    typedef typename detail::ev_selector<AList>::type Extractor;
68    typedef typename Extractor::template bind_<AList,Tag>::type type;
69#endif 
70  };
71
72  template <class Tag1, class Tag2, class T1, class Base>
73  inline typename property_value<property<Tag1,T1,Base>, Tag2>::type&
74  get_property_value(property<Tag1,T1,Base>& p, Tag2 tag2) {
75    BOOST_STATIC_CONSTANT(bool,
76                          match = (detail::same_property<Tag1,Tag2>::value));
77    typedef property<Tag1,T1,Base> Prop;
78    typedef typename property_value<Prop, Tag2>::type T2;
79    T2* t2 = 0;
80    typedef detail::property_value_dispatch<match> Dispatcher;
81    return Dispatcher::get_value(p, t2, tag2);
82  }
83  template <class Tag1, class Tag2, class T1, class Base>
84  inline
85  const typename property_value<property<Tag1,T1,Base>, Tag2>::type&
86  get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) {
87    BOOST_STATIC_CONSTANT(bool,
88                          match = (detail::same_property<Tag1,Tag2>::value));
89    typedef property<Tag1,T1,Base> Prop;
90    typedef typename property_value<Prop, Tag2>::type T2;
91    T2* t2 = 0;
92    typedef detail::property_value_dispatch<match> Dispatcher;
93    return Dispatcher::const_get_value(p, t2, tag2);
94  }
95
96 namespace detail {
97#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
98   template<typename FinalTag, typename FinalType>
99   struct retag_property_list
100   {
101     typedef property<FinalTag, FinalType> type;
102     typedef FinalType retagged;
103   };
104
105   template<typename FinalTag, typename Tag, typename T, typename Base>
106   struct retag_property_list<FinalTag, property<Tag, T, Base> >
107   {
108   private:
109     typedef retag_property_list<FinalTag, Base> next;
110
111   public:
112     typedef property<Tag, T, typename next::type> type;
113     typedef typename next::retagged retagged;
114   };
115
116   template<typename FinalTag>
117   struct retag_property_list<FinalTag, no_property>
118   {
119     typedef no_property type;
120     typedef no_property retagged;
121   };
122#endif
123  }
124} // namesapce boost
125
126#endif /* BOOST_PROPERTY_HPP */
Note: See TracBrowser for help on using the repository browser.