| [29] | 1 | //  (C) Copyright Jeremy Siek 2004  | 
|---|
 | 2 | //  Distributed under the Boost Software License, Version 1.0. (See | 
|---|
 | 3 | //  accompanying file LICENSE_1_0.txt or copy at | 
|---|
 | 4 | //  http://www.boost.org/LICENSE_1_0.txt) | 
|---|
 | 5 |  | 
|---|
 | 6 | #ifndef BOOST_PROPERTY_HPP | 
|---|
 | 7 | #define BOOST_PROPERTY_HPP | 
|---|
 | 8 |  | 
|---|
 | 9 | #include <boost/pending/ct_if.hpp> | 
|---|
 | 10 |  | 
|---|
 | 11 | namespace boost { | 
|---|
 | 12 |  | 
|---|
 | 13 |   struct no_property {  | 
|---|
 | 14 |     typedef no_property tag_type; | 
|---|
 | 15 |     typedef no_property next_type; | 
|---|
 | 16 |     typedef no_property value_type; | 
|---|
 | 17 |     enum { num = 0 }; | 
|---|
 | 18 |     typedef void kind; | 
|---|
 | 19 |   }; | 
|---|
 | 20 |  | 
|---|
 | 21 |   template <class Tag, class T, class Base = no_property> | 
|---|
 | 22 |   struct property : public Base { | 
|---|
 | 23 |     typedef Base next_type; | 
|---|
 | 24 |     typedef Tag tag_type; | 
|---|
 | 25 |     typedef T value_type; | 
|---|
 | 26 | #if BOOST_WORKAROUND (__GNUC__, < 3) | 
|---|
 | 27 |     property() { } | 
|---|
 | 28 | #else | 
|---|
 | 29 |     property() : m_value() { } | 
|---|
 | 30 | #endif | 
|---|
 | 31 |     property(const T& v) : m_value(v) { } | 
|---|
 | 32 |     property(const T& v, const Base& b) : Base(b), m_value(v) { } | 
|---|
 | 33 |     // copy constructor and assignment operator will be generated by compiler | 
|---|
 | 34 |  | 
|---|
 | 35 |     T m_value; | 
|---|
 | 36 |   }; | 
|---|
 | 37 |  | 
|---|
 | 38 |   // The BGL properties specialize property_kind and | 
|---|
 | 39 |   // property_num, and use enum's for the Property type (see | 
|---|
 | 40 |   // graph/properties.hpp), but the user may want to use a class | 
|---|
 | 41 |   // instead with a nested kind type and num.  Also, we may want to | 
|---|
 | 42 |   // switch BGL back to using class types for properties at some point. | 
|---|
 | 43 |  | 
|---|
 | 44 |   template <class PropertyTag> | 
|---|
 | 45 |   struct property_kind { | 
|---|
 | 46 |     typedef typename PropertyTag::kind type; | 
|---|
 | 47 |   }; | 
|---|
 | 48 |  | 
|---|
 | 49 |   template <class P> | 
|---|
 | 50 |   struct has_property {  | 
|---|
 | 51 |     BOOST_STATIC_CONSTANT(bool, value = true); | 
|---|
 | 52 |     typedef true_type type; | 
|---|
 | 53 |   }; | 
|---|
 | 54 |   template <> | 
|---|
 | 55 |   struct has_property<no_property> {  | 
|---|
 | 56 |     BOOST_STATIC_CONSTANT(bool, value = false);  | 
|---|
 | 57 |     typedef false_type type;  | 
|---|
 | 58 |   }; | 
|---|
 | 59 |  | 
|---|
 | 60 | } // namespace boost | 
|---|
 | 61 |  | 
|---|
 | 62 | #include <boost/pending/detail/property.hpp> | 
|---|
 | 63 |  | 
|---|
 | 64 | namespace boost { | 
|---|
 | 65 |  | 
|---|
 | 66 |   template <class PropertyList, class Tag> | 
|---|
 | 67 |   struct property_value { | 
|---|
 | 68 | #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | 
|---|
 | 69 |     typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList; | 
|---|
 | 70 |     typedef typename detail::extract_value<AList,Tag>::type type; | 
|---|
 | 71 | #else | 
|---|
 | 72 |     typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList; | 
|---|
 | 73 |     typedef typename detail::ev_selector<AList>::type Extractor; | 
|---|
 | 74 |     typedef typename Extractor::template bind_<AList,Tag>::type type; | 
|---|
 | 75 | #endif   | 
|---|
 | 76 |   }; | 
|---|
 | 77 |  | 
|---|
 | 78 |   template <class Tag1, class Tag2, class T1, class Base> | 
|---|
 | 79 |   inline typename property_value<property<Tag1,T1,Base>, Tag2>::type&  | 
|---|
 | 80 |   get_property_value(property<Tag1,T1,Base>& p, Tag2 tag2) { | 
|---|
 | 81 |     BOOST_STATIC_CONSTANT(bool,  | 
|---|
 | 82 |                           match = (detail::same_property<Tag1,Tag2>::value)); | 
|---|
 | 83 |     typedef property<Tag1,T1,Base> Prop; | 
|---|
 | 84 |     typedef typename property_value<Prop, Tag2>::type T2; | 
|---|
 | 85 |     T2* t2 = 0; | 
|---|
 | 86 |     typedef detail::property_value_dispatch<match> Dispatcher; | 
|---|
 | 87 |     return Dispatcher::get_value(p, t2, tag2); | 
|---|
 | 88 |   } | 
|---|
 | 89 |   template <class Tag1, class Tag2, class T1, class Base> | 
|---|
 | 90 |   inline | 
|---|
 | 91 |   const typename property_value<property<Tag1,T1,Base>, Tag2>::type&  | 
|---|
 | 92 |   get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) { | 
|---|
 | 93 |     BOOST_STATIC_CONSTANT(bool,  | 
|---|
 | 94 |                           match = (detail::same_property<Tag1,Tag2>::value)); | 
|---|
 | 95 |     typedef property<Tag1,T1,Base> Prop; | 
|---|
 | 96 |     typedef typename property_value<Prop, Tag2>::type T2; | 
|---|
 | 97 |     T2* t2 = 0; | 
|---|
 | 98 |     typedef detail::property_value_dispatch<match> Dispatcher; | 
|---|
 | 99 |     return Dispatcher::const_get_value(p, t2, tag2); | 
|---|
 | 100 |   } | 
|---|
 | 101 |  | 
|---|
 | 102 |  namespace detail { | 
|---|
 | 103 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | 
|---|
 | 104 |    template<typename FinalTag, typename FinalType> | 
|---|
 | 105 |    struct retag_property_list | 
|---|
 | 106 |    { | 
|---|
 | 107 |      typedef property<FinalTag, FinalType> type; | 
|---|
 | 108 |      typedef FinalType retagged; | 
|---|
 | 109 |    }; | 
|---|
 | 110 |  | 
|---|
 | 111 |    template<typename FinalTag, typename Tag, typename T, typename Base> | 
|---|
 | 112 |    struct retag_property_list<FinalTag, property<Tag, T, Base> > | 
|---|
 | 113 |    { | 
|---|
 | 114 |    private: | 
|---|
 | 115 |      typedef retag_property_list<FinalTag, Base> next; | 
|---|
 | 116 |  | 
|---|
 | 117 |    public: | 
|---|
 | 118 |      typedef property<Tag, T, typename next::type> type; | 
|---|
 | 119 |      typedef typename next::retagged retagged; | 
|---|
 | 120 |    }; | 
|---|
 | 121 |  | 
|---|
 | 122 |    template<typename FinalTag> | 
|---|
 | 123 |    struct retag_property_list<FinalTag, no_property> | 
|---|
 | 124 |    { | 
|---|
 | 125 |      typedef no_property type; | 
|---|
 | 126 |      typedef no_property retagged; | 
|---|
 | 127 |    }; | 
|---|
 | 128 | #endif | 
|---|
 | 129 |   } | 
|---|
 | 130 | } // namesapce boost | 
|---|
 | 131 |  | 
|---|
 | 132 | #endif /* BOOST_PROPERTY_HPP */ | 
|---|