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