File indexing completed on 2025-07-05 08:40:45
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PROPERTY_HPP
0007 #define BOOST_PROPERTY_HPP
0008
0009 #include <boost/config.hpp>
0010 #include <boost/mpl/bool.hpp>
0011 #include <boost/mpl/if.hpp>
0012 #include <boost/mpl/has_xxx.hpp>
0013 #include <boost/utility/enable_if.hpp>
0014 #include <boost/type_traits.hpp>
0015 #include <boost/static_assert.hpp>
0016
0017 namespace boost
0018 {
0019
0020 struct no_property
0021 {
0022 };
0023
0024 template < class Tag, class T, class Base = no_property > struct property
0025 {
0026 typedef Base next_type;
0027 typedef Tag tag_type;
0028 typedef T value_type;
0029 property(const T& v = T()) : m_value(v) {}
0030 property(const T& v, const Base& b) : m_value(v), m_base(b) {}
0031
0032
0033 T m_value;
0034 BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS Base m_base;
0035 };
0036
0037
0038 namespace graph_introspect_detail
0039 {
0040 BOOST_MPL_HAS_XXX_TRAIT_DEF(kind)
0041 template < typename T, bool Cond > struct get_kind
0042 {
0043 typedef void type;
0044 };
0045 template < typename T > struct get_kind< T, true >
0046 {
0047 typedef typename T::kind type;
0048 };
0049 }
0050
0051
0052
0053
0054 template < class PropertyTag >
0055 struct property_kind
0056 : graph_introspect_detail::get_kind< PropertyTag,
0057 graph_introspect_detail::has_kind< PropertyTag >::value >
0058 {
0059 };
0060
0061
0062 enum vertex_all_t
0063 {
0064 vertex_all
0065 };
0066 enum edge_all_t
0067 {
0068 edge_all
0069 };
0070 enum graph_all_t
0071 {
0072 graph_all
0073 };
0074 enum vertex_bundle_t
0075 {
0076 vertex_bundle
0077 };
0078 enum edge_bundle_t
0079 {
0080 edge_bundle
0081 };
0082 enum graph_bundle_t
0083 {
0084 graph_bundle
0085 };
0086
0087
0088 template < typename PList, typename PropName, typename Enable = void >
0089 struct lookup_one_property_internal
0090 {
0091 BOOST_STATIC_CONSTANT(bool, found = false);
0092 typedef void type;
0093 };
0094
0095
0096 #define BGL_ALL_PROP(tag) \
0097 template < typename T > struct lookup_one_property_internal< T, tag > \
0098 { \
0099 BOOST_STATIC_CONSTANT(bool, found = true); \
0100 typedef T type; \
0101 static T& lookup(T& x, tag) { return x; } \
0102 static const T& lookup(const T& x, tag) { return x; } \
0103 }; \
0104 template < typename Tag, typename T, typename Base > \
0105 struct lookup_one_property_internal< property< Tag, T, Base >, tag > \
0106 { \
0107 BOOST_STATIC_CONSTANT(bool, found = true); \
0108 typedef property< Tag, T, Base > type; \
0109 static type& lookup(type& x, tag) { return x; } \
0110 static const type& lookup(const type& x, tag) { return x; } \
0111 };
0112
0113 BGL_ALL_PROP(vertex_all_t)
0114 BGL_ALL_PROP(edge_all_t)
0115 BGL_ALL_PROP(graph_all_t)
0116 #undef BGL_ALL_PROP
0117
0118
0119
0120 #define BGL_DO_ONE_BUNDLE_TYPE(kind) \
0121 template < typename T > \
0122 struct lookup_one_property_internal< T, BOOST_JOIN(kind, _bundle_t) > \
0123 { \
0124 BOOST_STATIC_CONSTANT(bool, found = true); \
0125 typedef T type; \
0126 static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) { return x; } \
0127 static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) \
0128 { \
0129 return x; \
0130 } \
0131 }; \
0132 \
0133 template < typename Tag, typename T, typename Base > \
0134 struct lookup_one_property_internal< property< Tag, T, Base >, \
0135 BOOST_JOIN(kind, _bundle_t) > \
0136 : lookup_one_property_internal< Base, BOOST_JOIN(kind, _bundle_t) > \
0137 { \
0138 private: \
0139 typedef lookup_one_property_internal< Base, \
0140 BOOST_JOIN(kind, _bundle_t) > \
0141 base_type; \
0142 \
0143 public: \
0144 template < typename BundleTag > \
0145 static typename lazy_enable_if_c< \
0146 (base_type::found \
0147 && (is_same< BundleTag, \
0148 BOOST_JOIN(kind, _bundle_t) >::value)), \
0149 add_reference< typename base_type::type > >::type \
0150 lookup(property< Tag, T, Base >& p, BundleTag) \
0151 { \
0152 return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
0153 } \
0154 template < typename BundleTag > \
0155 static typename lazy_enable_if_c< \
0156 (base_type::found \
0157 && (is_same< BundleTag, \
0158 BOOST_JOIN(kind, _bundle_t) >::value)), \
0159 add_reference< const typename base_type::type > >::type \
0160 lookup(const property< Tag, T, Base >& p, BundleTag) \
0161 { \
0162 return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
0163 } \
0164 };
0165
0166 BGL_DO_ONE_BUNDLE_TYPE(vertex)
0167 BGL_DO_ONE_BUNDLE_TYPE(edge)
0168 BGL_DO_ONE_BUNDLE_TYPE(graph)
0169 #undef BGL_DO_ONE_BUNDLE_TYPE
0170
0171
0172
0173 template < typename Tag, typename T, typename Base >
0174 struct lookup_one_property_internal< boost::property< Tag, T, Base >, Tag >
0175 {
0176 BOOST_STATIC_CONSTANT(bool, found = true);
0177 typedef property< Tag, T, Base > prop;
0178 typedef T type;
0179 template < typename U >
0180 static typename enable_if< is_same< prop, U >, T& >::type lookup(
0181 U& prop, const Tag&)
0182 {
0183 return prop.m_value;
0184 }
0185 template < typename U >
0186 static typename enable_if< is_same< prop, U >, const T& >::type lookup(
0187 const U& prop, const Tag&)
0188 {
0189 return prop.m_value;
0190 }
0191 };
0192
0193 template < typename Tag, typename T, typename Base, typename PropName >
0194 struct lookup_one_property_internal< boost::property< Tag, T, Base >, PropName >
0195 : lookup_one_property_internal< Base, PropName >
0196 {
0197 private:
0198 typedef lookup_one_property_internal< Base, PropName > base_type;
0199
0200 public:
0201 template < typename PL >
0202 static
0203 typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
0204 add_reference< typename base_type::type > >::type
0205 lookup(PL& prop, const PropName& tag)
0206 {
0207 return base_type::lookup(prop.m_base, tag);
0208 }
0209 template < typename PL >
0210 static
0211 typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
0212 add_reference< const typename base_type::type > >::type
0213 lookup(const PL& prop, const PropName& tag)
0214 {
0215 return base_type::lookup(prop.m_base, tag);
0216 }
0217 };
0218
0219
0220 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
0221 template < typename T, typename TMaybeBase, typename R >
0222 struct lookup_one_property_internal< T, R TMaybeBase::*,
0223 typename enable_if< is_base_of< TMaybeBase, T > >::type >
0224 {
0225 BOOST_STATIC_CONSTANT(bool, found = true);
0226 typedef R type;
0227 static R& lookup(T& x, R TMaybeBase::*ptr) { return x.*ptr; }
0228 static const R& lookup(const T& x, R TMaybeBase::*ptr) { return x.*ptr; }
0229 };
0230 #endif
0231
0232
0233 template < typename T, typename Tag >
0234 struct lookup_one_property : lookup_one_property_internal< T, Tag >
0235 {
0236 };
0237
0238 template < typename T, typename Tag > struct lookup_one_property< const T, Tag >
0239 {
0240 BOOST_STATIC_CONSTANT(
0241 bool, found = (lookup_one_property_internal< T, Tag >::found));
0242 typedef const typename lookup_one_property_internal< T, Tag >::type type;
0243 template < typename U >
0244 static typename lazy_enable_if< is_same< T, U >,
0245 add_reference< const typename lookup_one_property_internal< T,
0246 Tag >::type > >::type
0247 lookup(const U& p, Tag tag)
0248 {
0249 return lookup_one_property_internal< T, Tag >::lookup(p, tag);
0250 }
0251 };
0252
0253
0254
0255
0256
0257
0258
0259 template < class P > struct has_property : boost::mpl::true_
0260 {
0261 };
0262 template <> struct has_property< no_property > : boost::mpl::false_
0263 {
0264 };
0265
0266 }
0267
0268 #include <boost/pending/detail/property.hpp>
0269
0270 namespace boost
0271 {
0272
0273 template < class PropertyList, class Tag >
0274 struct property_value : lookup_one_property< PropertyList, Tag >
0275 {
0276 };
0277
0278 template < class PropertyList, class Tag >
0279 inline typename lookup_one_property< PropertyList, Tag >::type&
0280 get_property_value(PropertyList& p, Tag tag)
0281 {
0282 return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
0283 }
0284
0285 template < class PropertyList, class Tag >
0286 inline const typename lookup_one_property< PropertyList, Tag >::type&
0287 get_property_value(const PropertyList& p, Tag tag)
0288 {
0289 return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
0290 }
0291
0292 namespace detail
0293 {
0294
0295
0296 template < typename T >
0297 struct is_no_property : mpl::bool_< is_same< T, no_property >::value >
0298 {
0299 };
0300
0301 template < typename PList, typename Tag > class lookup_one_property_f;
0302
0303 template < typename PList, typename Tag, typename F >
0304 struct lookup_one_property_f_result;
0305
0306 template < typename PList, typename Tag >
0307 struct lookup_one_property_f_result< PList, Tag,
0308 const lookup_one_property_f< PList, Tag >(PList) >
0309 {
0310 typedef typename lookup_one_property< PList, Tag >::type type;
0311 };
0312
0313 template < typename PList, typename Tag >
0314 struct lookup_one_property_f_result< PList, Tag,
0315 const lookup_one_property_f< PList, Tag >(PList&) >
0316 {
0317 typedef typename lookup_one_property< PList, Tag >::type& type;
0318 };
0319
0320 template < typename PList, typename Tag >
0321 struct lookup_one_property_f_result< PList, Tag,
0322 const lookup_one_property_f< PList, Tag >(const PList&) >
0323 {
0324 typedef const typename lookup_one_property< PList, Tag >::type& type;
0325 };
0326
0327 template < typename PList, typename Tag > class lookup_one_property_f
0328 {
0329 Tag tag;
0330
0331 public:
0332 lookup_one_property_f(Tag tag) : tag(tag) {}
0333 template < typename F >
0334 struct result : lookup_one_property_f_result< PList, Tag, F >
0335 {
0336 };
0337
0338 typename lookup_one_property_f_result< PList, Tag,
0339 const lookup_one_property_f(PList&) >::type
0340 operator()(PList& pl) const
0341 {
0342 return lookup_one_property< PList, Tag >::lookup(pl, tag);
0343 }
0344 };
0345
0346 }
0347
0348 namespace detail
0349 {
0350
0351
0352
0353
0354 struct remove_first_property
0355 {
0356 template < typename F > struct result
0357 {
0358 typedef typename boost::function_traits< F >::arg1_type a1;
0359 typedef typename boost::remove_reference< a1 >::type non_ref;
0360 typedef typename non_ref::next_type nx;
0361 typedef typename boost::mpl::if_< boost::is_const< non_ref >,
0362 boost::add_const< nx >, nx >::type with_const;
0363 typedef typename boost::add_reference< with_const >::type type;
0364 };
0365 template < typename Prop >
0366 typename Prop::next_type& operator()(Prop& p) const
0367 {
0368 return p.m_base;
0369 }
0370 template < typename Prop >
0371 const typename Prop::next_type& operator()(const Prop& p) const
0372 {
0373 return p.m_base;
0374 }
0375 };
0376 }
0377
0378 }
0379
0380 #endif