123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- // (C) Copyright Jeremy Siek 2004
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_PROPERTY_HPP
- #define BOOST_PROPERTY_HPP
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/has_xxx.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <boost/type_traits.hpp>
- #include <boost/static_assert.hpp>
- namespace boost
- {
- struct no_property
- {
- };
- template < class Tag, class T, class Base = no_property > struct property
- {
- typedef Base next_type;
- typedef Tag tag_type;
- typedef T value_type;
- property(const T& v = T()) : m_value(v) {}
- property(const T& v, const Base& b) : m_value(v), m_base(b) {}
- // copy constructor and assignment operator will be generated by compiler
- T m_value;
- Base m_base;
- };
- // Kinds of properties
- namespace graph_introspect_detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kind)
- template < typename T, bool Cond > struct get_kind
- {
- typedef void type;
- };
- template < typename T > struct get_kind< T, true >
- {
- typedef typename T::kind type;
- };
- }
- // Having a default is to make this trait work for any type, not just valid
- // properties, to work around VC++ <= 10 bugs related to SFINAE in
- // compressed_sparse_row_graph's get functions and similar
- template < class PropertyTag >
- struct property_kind
- : graph_introspect_detail::get_kind< PropertyTag,
- graph_introspect_detail::has_kind< PropertyTag >::value >
- {
- };
- // Some standard properties defined independently of Boost.Graph:
- enum vertex_all_t
- {
- vertex_all
- };
- enum edge_all_t
- {
- edge_all
- };
- enum graph_all_t
- {
- graph_all
- };
- enum vertex_bundle_t
- {
- vertex_bundle
- };
- enum edge_bundle_t
- {
- edge_bundle
- };
- enum graph_bundle_t
- {
- graph_bundle
- };
- // Code to look up one property in a property list:
- template < typename PList, typename PropName, typename Enable = void >
- struct lookup_one_property_internal
- {
- BOOST_STATIC_CONSTANT(bool, found = false);
- typedef void type;
- };
- // Special-case properties (vertex_all, edge_all, graph_all)
- #define BGL_ALL_PROP(tag) \
- template < typename T > struct lookup_one_property_internal< T, tag > \
- { \
- BOOST_STATIC_CONSTANT(bool, found = true); \
- typedef T type; \
- static T& lookup(T& x, tag) { return x; } \
- static const T& lookup(const T& x, tag) { return x; } \
- }; \
- template < typename Tag, typename T, typename Base > \
- struct lookup_one_property_internal< property< Tag, T, Base >, tag > \
- { /* Avoid ambiguity */ \
- BOOST_STATIC_CONSTANT(bool, found = true); \
- typedef property< Tag, T, Base > type; \
- static type& lookup(type& x, tag) { return x; } \
- static const type& lookup(const type& x, tag) { return x; } \
- };
- BGL_ALL_PROP(vertex_all_t)
- BGL_ALL_PROP(edge_all_t)
- BGL_ALL_PROP(graph_all_t)
- #undef BGL_ALL_PROP
- // *_bundled; these need to be macros rather than inheritance to resolve
- // ambiguities
- #define BGL_DO_ONE_BUNDLE_TYPE(kind) \
- template < typename T > \
- struct lookup_one_property_internal< T, BOOST_JOIN(kind, _bundle_t) > \
- { \
- BOOST_STATIC_CONSTANT(bool, found = true); \
- typedef T type; \
- static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) { return x; } \
- static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) \
- { \
- return x; \
- } \
- }; \
- \
- template < typename Tag, typename T, typename Base > \
- struct lookup_one_property_internal< property< Tag, T, Base >, \
- BOOST_JOIN(kind, _bundle_t) > \
- : lookup_one_property_internal< Base, BOOST_JOIN(kind, _bundle_t) > \
- { \
- private: \
- typedef lookup_one_property_internal< Base, \
- BOOST_JOIN(kind, _bundle_t) > \
- base_type; \
- \
- public: \
- template < typename BundleTag > \
- static typename lazy_enable_if_c< \
- (base_type::found \
- && (is_same< BundleTag, \
- BOOST_JOIN(kind, _bundle_t) >::value)), \
- add_reference< typename base_type::type > >::type \
- lookup(property< Tag, T, Base >& p, BundleTag) \
- { \
- return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
- } \
- template < typename BundleTag > \
- static typename lazy_enable_if_c< \
- (base_type::found \
- && (is_same< BundleTag, \
- BOOST_JOIN(kind, _bundle_t) >::value)), \
- add_reference< const typename base_type::type > >::type \
- lookup(const property< Tag, T, Base >& p, BundleTag) \
- { \
- return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
- } \
- };
- BGL_DO_ONE_BUNDLE_TYPE(vertex)
- BGL_DO_ONE_BUNDLE_TYPE(edge)
- BGL_DO_ONE_BUNDLE_TYPE(graph)
- #undef BGL_DO_ONE_BUNDLE_TYPE
- // Normal old-style properties; second case also handles chaining of bundled
- // property accesses
- template < typename Tag, typename T, typename Base >
- struct lookup_one_property_internal< boost::property< Tag, T, Base >, Tag >
- {
- BOOST_STATIC_CONSTANT(bool, found = true);
- typedef property< Tag, T, Base > prop;
- typedef T type;
- template < typename U >
- static typename enable_if< is_same< prop, U >, T& >::type lookup(
- U& prop, const Tag&)
- {
- return prop.m_value;
- }
- template < typename U >
- static typename enable_if< is_same< prop, U >, const T& >::type lookup(
- const U& prop, const Tag&)
- {
- return prop.m_value;
- }
- };
- template < typename Tag, typename T, typename Base, typename PropName >
- struct lookup_one_property_internal< boost::property< Tag, T, Base >, PropName >
- : lookup_one_property_internal< Base, PropName >
- {
- private:
- typedef lookup_one_property_internal< Base, PropName > base_type;
- public:
- template < typename PL >
- static
- typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
- add_reference< typename base_type::type > >::type
- lookup(PL& prop, const PropName& tag)
- {
- return base_type::lookup(prop.m_base, tag);
- }
- template < typename PL >
- static
- typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
- add_reference< const typename base_type::type > >::type
- lookup(const PL& prop, const PropName& tag)
- {
- return base_type::lookup(prop.m_base, tag);
- }
- };
- // Pointer-to-member access to bundled properties
- #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
- template < typename T, typename TMaybeBase, typename R >
- struct lookup_one_property_internal< T, R TMaybeBase::*,
- typename enable_if< is_base_of< TMaybeBase, T > >::type >
- {
- BOOST_STATIC_CONSTANT(bool, found = true);
- typedef R type;
- static R& lookup(T& x, R TMaybeBase::*ptr) { return x.*ptr; }
- static const R& lookup(const T& x, R TMaybeBase::*ptr) { return x.*ptr; }
- };
- #endif
- // Version of above handling const property lists properly
- template < typename T, typename Tag >
- struct lookup_one_property : lookup_one_property_internal< T, Tag >
- {
- };
- template < typename T, typename Tag > struct lookup_one_property< const T, Tag >
- {
- BOOST_STATIC_CONSTANT(
- bool, found = (lookup_one_property_internal< T, Tag >::found));
- typedef const typename lookup_one_property_internal< T, Tag >::type type;
- template < typename U >
- static typename lazy_enable_if< is_same< T, U >,
- add_reference< const typename lookup_one_property_internal< T,
- Tag >::type > >::type
- lookup(const U& p, Tag tag)
- {
- return lookup_one_property_internal< T, Tag >::lookup(p, tag);
- }
- };
- // The BGL properties specialize property_kind and
- // property_num, and use enum's for the Property type (see
- // graph/properties.hpp), but the user may want to use a class
- // instead with a nested kind type and num. Also, we may want to
- // switch BGL back to using class types for properties at some point.
- template < class P > struct has_property : boost::mpl::true_
- {
- };
- template <> struct has_property< no_property > : boost::mpl::false_
- {
- };
- } // namespace boost
- #include <boost/pending/detail/property.hpp>
- namespace boost
- {
- template < class PropertyList, class Tag >
- struct property_value : lookup_one_property< PropertyList, Tag >
- {
- };
- template < class PropertyList, class Tag >
- inline typename lookup_one_property< PropertyList, Tag >::type&
- get_property_value(PropertyList& p, Tag tag)
- {
- return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
- }
- template < class PropertyList, class Tag >
- inline const typename lookup_one_property< PropertyList, Tag >::type&
- get_property_value(const PropertyList& p, Tag tag)
- {
- return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
- }
- namespace detail
- {
- /** This trait returns true if T is no_property. */
- template < typename T >
- struct is_no_property : mpl::bool_< is_same< T, no_property >::value >
- {
- };
- template < typename PList, typename Tag > class lookup_one_property_f;
- template < typename PList, typename Tag, typename F >
- struct lookup_one_property_f_result;
- template < typename PList, typename Tag >
- struct lookup_one_property_f_result< PList, Tag,
- const lookup_one_property_f< PList, Tag >(PList) >
- {
- typedef typename lookup_one_property< PList, Tag >::type type;
- };
- template < typename PList, typename Tag >
- struct lookup_one_property_f_result< PList, Tag,
- const lookup_one_property_f< PList, Tag >(PList&) >
- {
- typedef typename lookup_one_property< PList, Tag >::type& type;
- };
- template < typename PList, typename Tag >
- struct lookup_one_property_f_result< PList, Tag,
- const lookup_one_property_f< PList, Tag >(const PList&) >
- {
- typedef const typename lookup_one_property< PList, Tag >::type& type;
- };
- template < typename PList, typename Tag > class lookup_one_property_f
- {
- Tag tag;
- public:
- lookup_one_property_f(Tag tag) : tag(tag) {}
- template < typename F >
- struct result : lookup_one_property_f_result< PList, Tag, F >
- {
- };
- typename lookup_one_property_f_result< PList, Tag,
- const lookup_one_property_f(PList&) >::type
- operator()(PList& pl) const
- {
- return lookup_one_property< PList, Tag >::lookup(pl, tag);
- }
- };
- } // namespace detail
- namespace detail
- {
- // Stuff for directed_graph and undirected_graph to skip over their first
- // vertex_index and edge_index properties when providing vertex_all and
- // edge_all; make sure you know the exact structure of your properties if
- // you use there.
- struct remove_first_property
- {
- template < typename F > struct result
- {
- typedef typename boost::function_traits< F >::arg1_type a1;
- typedef typename boost::remove_reference< a1 >::type non_ref;
- typedef typename non_ref::next_type nx;
- typedef typename boost::mpl::if_< boost::is_const< non_ref >,
- boost::add_const< nx >, nx >::type with_const;
- typedef typename boost::add_reference< with_const >::type type;
- };
- template < typename Prop >
- typename Prop::next_type& operator()(Prop& p) const
- {
- return p.m_base;
- }
- template < typename Prop >
- const typename Prop::next_type& operator()(const Prop& p) const
- {
- return p.m_base;
- }
- };
- }
- } // namesapce boost
- #endif /* BOOST_PROPERTY_HPP */
|