diff options
Diffstat (limited to 'boost/pending/property.hpp')
-rw-r--r-- | boost/pending/property.hpp | 105 |
1 files changed, 42 insertions, 63 deletions
diff --git a/boost/pending/property.hpp b/boost/pending/property.hpp index 93ebffbf3b..e63a2d203f 100644 --- a/boost/pending/property.hpp +++ b/boost/pending/property.hpp @@ -11,6 +11,7 @@ #include <boost/mpl/has_xxx.hpp> #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> +#include <boost/static_assert.hpp> namespace boost { @@ -53,8 +54,8 @@ namespace boost { enum graph_bundle_t {graph_bundle}; // Code to look up one property in a property list: - template <typename PList, typename PropName> - struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false);}; + 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) \ @@ -93,8 +94,14 @@ namespace boost { private: \ typedef lookup_one_property_internal<Base, BOOST_JOIN(kind, _bundle_t)> base_type; \ public: \ - static typename base_type::type& lookup(property<Tag, T, Base>& p, BOOST_JOIN(kind, _bundle_t)) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \ - static const typename base_type::type& lookup(const property<Tag, T, Base>& p, BOOST_JOIN(kind, _bundle_t)) {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<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) @@ -122,12 +129,14 @@ namespace boost { typedef lookup_one_property_internal<Base, PropName> base_type; public: template <typename PL> - static typename enable_if<is_same<PL, boost::property<Tag, T, Base> >, typename base_type::type&>::type + 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 enable_if<is_same<PL, boost::property<Tag, T, Base> >, const typename base_type::type&>::type + 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); } @@ -135,12 +144,12 @@ namespace boost { // Pointer-to-member access to bundled properties #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - template <typename T, typename R> - struct lookup_one_property_internal<T, R T::*> { + 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 T::*ptr) {return x.*ptr;} - static const R& lookup(const T& x, R T::*ptr) {return x.*ptr;} + 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 @@ -153,7 +162,8 @@ namespace boost { 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 enable_if<is_same<T, U>, const typename lookup_one_property_internal<T, Tag>::type&>::type + 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); } @@ -199,58 +209,6 @@ namespace boost { : mpl::bool_<is_same<T, no_property>::value> { }; - /** @internal @name Retag Property List - * This metafunction is used internally to normalize a property if it is - * actually modeling a property. Specifically this is used in Boost.Graph - * to map user-provided classes into bundled properties. - */ - //@{ - // One base case of the recursive form (see below). This matches any - // retag request that does not include a property<...> or no_property as - // the FinalType. This is used for generating bundles in Boost.Graph. - template<typename FinalTag, typename FinalType> - struct retag_property_list - { - typedef property<FinalTag, FinalType> type; - typedef FinalType retagged; - }; - - // Recursively retag the nested property list. - template<typename FinalTag, typename Tag, typename T, typename Base> - struct retag_property_list<FinalTag, property<Tag, T, Base> > - { - private: - typedef retag_property_list<FinalTag, Base> next; - - public: - typedef property<Tag, T, typename next::type> type; - typedef typename next::retagged retagged; - }; - - // This base case will correctly deduce the final property type if the - // retagged property is given in property form. This should not hide - // the base case below. - // NOTE: This addresses a problem of layering bundled properties in the BGL - // where multiple retaggings will fail to deduce the correct retagged - // type. - template<typename FinalTag, typename FinalType> - struct retag_property_list<FinalTag, property<FinalTag, FinalType> > - { - public: - typedef property<FinalTag, FinalType> type; - typedef FinalType retagged; - }; - - // A final base case of the retag_property_list, this will terminate a - // properly structured list. - template<typename FinalTag> - struct retag_property_list<FinalTag, no_property> - { - typedef no_property type; - typedef no_property retagged; - }; - //@} - template <typename PList, typename Tag> class lookup_one_property_f; @@ -286,6 +244,27 @@ namespace boost { } // 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 */ |