| 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 propertiesnamespace 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 similartemplate < 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 accessestemplate < 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_PROPERTIEStemplate < 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 properlytemplate < 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 detailnamespace 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 */
 |