fix doc example typo
[boost.git] / boost / pending / property.hpp
blob448a71911d5eeef29a910b46684b80910d3b83fe
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)
6 #ifndef BOOST_PROPERTY_HPP
7 #define BOOST_PROPERTY_HPP
9 #include <boost/pending/ct_if.hpp>
11 namespace boost {
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;
21 template <class Tag, class T, class Base = no_property>
22 struct property : public Base {
23 typedef Base next_type;
24 typedef Tag tag_type;
25 typedef T value_type;
26 #if BOOST_WORKAROUND (__GNUC__, < 3)
27 property() { }
28 #else
29 property() : m_value() { }
30 #endif
31 property(const T& v) : m_value(v) { }
32 property(const T& v, const Base& b) : Base(b), m_value(v) { }
33 // copy constructor and assignment operator will be generated by compiler
35 T m_value;
38 // The BGL properties specialize property_kind and
39 // property_num, and use enum's for the Property type (see
40 // graph/properties.hpp), but the user may want to use a class
41 // instead with a nested kind type and num. Also, we may want to
42 // switch BGL back to using class types for properties at some point.
44 template <class PropertyTag>
45 struct property_kind {
46 typedef typename PropertyTag::kind type;
49 template <class P>
50 struct has_property {
51 BOOST_STATIC_CONSTANT(bool, value = true);
52 typedef true_type type;
54 template <>
55 struct has_property<no_property> {
56 BOOST_STATIC_CONSTANT(bool, value = false);
57 typedef false_type type;
60 } // namespace boost
62 #include <boost/pending/detail/property.hpp>
64 namespace boost {
66 template <class PropertyList, class Tag>
67 struct property_value {
68 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
69 typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
70 typedef typename detail::extract_value<AList,Tag>::type type;
71 #else
72 typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
73 typedef typename detail::ev_selector<AList>::type Extractor;
74 typedef typename Extractor::template bind_<AList,Tag>::type type;
75 #endif
78 template <class Tag2>
79 inline detail::error_property_not_found
80 get_property_value(const no_property& p, Tag2) {
81 return detail::error_property_not_found();
84 template <class Tag1, class Tag2, class T1, class Base>
85 inline typename property_value<property<Tag1,T1,Base>, Tag2>::type&
86 get_property_value(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::get_value(p, t2, tag2);
95 template <class Tag1, class Tag2, class T1, class Base>
96 inline
97 const typename property_value<property<Tag1,T1,Base>, Tag2>::type&
98 get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) {
99 BOOST_STATIC_CONSTANT(bool,
100 match = (detail::same_property<Tag1,Tag2>::value));
101 typedef property<Tag1,T1,Base> Prop;
102 typedef typename property_value<Prop, Tag2>::type T2;
103 T2* t2 = 0;
104 typedef detail::property_value_dispatch<match> Dispatcher;
105 return Dispatcher::const_get_value(p, t2, tag2);
108 namespace detail {
110 /** This trait returns true if T is no_property. */
111 template <typename T>
112 struct is_no_property
113 : mpl::bool_<is_same<T, no_property>::value>
114 { };
116 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
117 /** @internal @name Retag Property List
118 * This metafunction is used internally to normalize a property if it is
119 * actually modeling a property. Specifically this is used in Boost.Graph
120 * to map user-provided classes into bundled properties.
122 //@{
123 // One base case of the recursive form (see below). This matches any
124 // retag request that does not include a property<...> or no_property as
125 // the FinalType. This is used for generating bundles in Boost.Graph.
126 template<typename FinalTag, typename FinalType>
127 struct retag_property_list
129 typedef property<FinalTag, FinalType> type;
130 typedef FinalType retagged;
133 // Recursively retag the nested property list.
134 template<typename FinalTag, typename Tag, typename T, typename Base>
135 struct retag_property_list<FinalTag, property<Tag, T, Base> >
137 private:
138 typedef retag_property_list<FinalTag, Base> next;
140 public:
141 typedef property<Tag, T, typename next::type> type;
142 typedef typename next::retagged retagged;
145 // This base case will correctly deduce the final property type if the
146 // retagged property is given in property form. This should not hide
147 // the base case below.
148 // NOTE: This addresses a problem of layering bundled properties in the BGL
149 // where multiple retaggings will fail to deduce the correct retagged
150 // type.
151 template<typename FinalTag, typename FinalType>
152 struct retag_property_list<FinalTag, property<FinalTag, FinalType> >
154 public:
155 typedef property<FinalTag, FinalType> type;
156 typedef FinalType retagged;
159 // A final base case of the retag_propert_list, this will terminate a
160 // properly structured list.
161 template<typename FinalTag>
162 struct retag_property_list<FinalTag, no_property>
164 typedef no_property type;
165 typedef no_property retagged;
167 //@}
168 #endif
169 } // namespace detail
171 } // namesapce boost
173 #endif /* BOOST_PROPERTY_HPP */