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