williamr@2: // (C) Copyright Jeremy Siek 2004 williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: williamr@2: #ifndef BOOST_PROPERTY_HPP williamr@2: #define BOOST_PROPERTY_HPP williamr@2: williamr@2: #include williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: struct no_property { williamr@2: typedef no_property tag_type; williamr@2: typedef no_property next_type; williamr@2: typedef no_property value_type; williamr@2: enum { num = 0 }; williamr@2: typedef void kind; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct property : public Base { williamr@2: typedef Base next_type; williamr@2: typedef Tag tag_type; williamr@2: typedef T value_type; williamr@2: #if BOOST_WORKAROUND (__GNUC__, < 3) williamr@2: property() { } williamr@2: #else williamr@2: property() : m_value() { } williamr@2: #endif williamr@2: property(const T& v) : m_value(v) { } williamr@2: property(const T& v, const Base& b) : Base(b), m_value(v) { } williamr@2: // copy constructor and assignment operator will be generated by compiler williamr@2: williamr@2: T m_value; williamr@2: }; williamr@2: williamr@2: // The BGL properties specialize property_kind and williamr@2: // property_num, and use enum's for the Property type (see williamr@2: // graph/properties.hpp), but the user may want to use a class williamr@2: // instead with a nested kind type and num. Also, we may want to williamr@2: // switch BGL back to using class types for properties at some point. williamr@2: williamr@2: template williamr@2: struct property_kind { williamr@2: typedef typename PropertyTag::kind type; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct has_property { williamr@2: BOOST_STATIC_CONSTANT(bool, value = true); williamr@2: typedef true_type type; williamr@2: }; williamr@2: template <> williamr@2: struct has_property { williamr@2: BOOST_STATIC_CONSTANT(bool, value = false); williamr@2: typedef false_type type; williamr@2: }; williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #include williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: template williamr@2: struct property_value { williamr@2: #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION williamr@2: typedef typename detail::build_property_tag_value_alist::type AList; williamr@2: typedef typename detail::extract_value::type type; williamr@2: #else williamr@2: typedef typename detail::build_property_tag_value_alist::type AList; williamr@2: typedef typename detail::ev_selector::type Extractor; williamr@2: typedef typename Extractor::template bind_::type type; williamr@2: #endif williamr@2: }; williamr@2: williamr@2: template williamr@2: inline typename property_value, Tag2>::type& williamr@2: get_property_value(property& p, Tag2 tag2) { williamr@2: BOOST_STATIC_CONSTANT(bool, williamr@2: match = (detail::same_property::value)); williamr@2: typedef property Prop; williamr@2: typedef typename property_value::type T2; williamr@2: T2* t2 = 0; williamr@2: typedef detail::property_value_dispatch Dispatcher; williamr@2: return Dispatcher::get_value(p, t2, tag2); williamr@2: } williamr@2: template williamr@2: inline williamr@2: const typename property_value, Tag2>::type& williamr@2: get_property_value(const property& p, Tag2 tag2) { williamr@2: BOOST_STATIC_CONSTANT(bool, williamr@2: match = (detail::same_property::value)); williamr@2: typedef property Prop; williamr@2: typedef typename property_value::type T2; williamr@2: T2* t2 = 0; williamr@2: typedef detail::property_value_dispatch Dispatcher; williamr@2: return Dispatcher::const_get_value(p, t2, tag2); williamr@2: } williamr@2: williamr@2: namespace detail { williamr@2: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) williamr@2: template williamr@2: struct retag_property_list williamr@2: { williamr@2: typedef property type; williamr@2: typedef FinalType retagged; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct retag_property_list > williamr@2: { williamr@2: private: williamr@2: typedef retag_property_list next; williamr@2: williamr@2: public: williamr@2: typedef property type; williamr@2: typedef typename next::retagged retagged; williamr@2: }; williamr@2: williamr@2: template williamr@2: struct retag_property_list williamr@2: { williamr@2: typedef no_property type; williamr@2: typedef no_property retagged; williamr@2: }; williamr@2: #endif williamr@2: } williamr@2: } // namesapce boost williamr@2: williamr@2: #endif /* BOOST_PROPERTY_HPP */