Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:32

0001 //  (C) Copyright Jeremy Siek 2004
0002 //  Distributed under the Boost Software License, Version 1.0. (See
0003 //  accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
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     // copy constructor and assignment operator will be generated by compiler
0031 
0032     T m_value;
0033     Base m_base;
0034 };
0035 
0036 // Kinds of properties
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 // Having a default is to make this trait work for any type, not just valid
0051 // properties, to work around VC++ <= 10 bugs related to SFINAE in
0052 // compressed_sparse_row_graph's get functions and similar
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 // Some standard properties defined independently of Boost.Graph:
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 // Code to look up one property in a property list:
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 // Special-case properties (vertex_all, edge_all, graph_all)
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     { /* Avoid ambiguity */                                               \
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 // *_bundled; these need to be macros rather than inheritance to resolve
0118 // ambiguities
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 // Normal old-style properties; second case also handles chaining of bundled
0171 // property accesses
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 // Pointer-to-member access to bundled properties
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 // Version of above handling const property lists properly
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 // The BGL properties specialize property_kind and
0253 // property_num, and use enum's for the Property type (see
0254 // graph/properties.hpp), but the user may want to use a class
0255 // instead with a nested kind type and num.  Also, we may want to
0256 // switch BGL back to using class types for properties at some point.
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 } // namespace boost
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     /** This trait returns true if T is no_property. */
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 } // namespace detail
0346 
0347 namespace detail
0348 {
0349     // Stuff for directed_graph and undirected_graph to skip over their first
0350     // vertex_index and edge_index properties when providing vertex_all and
0351     // edge_all; make sure you know the exact structure of your properties if
0352     // you use there.
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 } // namesapce boost
0378 
0379 #endif /* BOOST_PROPERTY_HPP */