annotate DEPENDENCIES/generic/include/boost/pending/property.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright Jeremy Siek 2004
Chris@16 2 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 3 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef BOOST_PROPERTY_HPP
Chris@16 7 #define BOOST_PROPERTY_HPP
Chris@16 8
Chris@16 9 #include <boost/mpl/bool.hpp>
Chris@16 10 #include <boost/mpl/if.hpp>
Chris@16 11 #include <boost/mpl/has_xxx.hpp>
Chris@16 12 #include <boost/utility/enable_if.hpp>
Chris@16 13 #include <boost/type_traits.hpp>
Chris@16 14 #include <boost/static_assert.hpp>
Chris@16 15
Chris@16 16 namespace boost {
Chris@16 17
Chris@16 18 struct no_property {};
Chris@16 19
Chris@16 20 template <class Tag, class T, class Base = no_property>
Chris@16 21 struct property {
Chris@16 22 typedef Base next_type;
Chris@16 23 typedef Tag tag_type;
Chris@16 24 typedef T value_type;
Chris@16 25 property(const T& v = T()) : m_value(v) { }
Chris@16 26 property(const T& v, const Base& b) : m_value(v), m_base(b) { }
Chris@16 27 // copy constructor and assignment operator will be generated by compiler
Chris@16 28
Chris@16 29 T m_value;
Chris@16 30 Base m_base;
Chris@16 31 };
Chris@16 32
Chris@16 33 // Kinds of properties
Chris@16 34 namespace graph_introspect_detail {
Chris@16 35 BOOST_MPL_HAS_XXX_TRAIT_DEF(kind)
Chris@16 36 template <typename T, bool Cond> struct get_kind {typedef void type;};
Chris@16 37 template <typename T> struct get_kind<T, true> {typedef typename T::kind type;};
Chris@16 38 }
Chris@16 39
Chris@16 40 // Having a default is to make this trait work for any type, not just valid
Chris@16 41 // properties, to work around VC++ <= 10 bugs related to SFINAE in
Chris@16 42 // compressed_sparse_row_graph's get functions and similar
Chris@16 43 template <class PropertyTag>
Chris@16 44 struct property_kind:
Chris@16 45 graph_introspect_detail::get_kind<PropertyTag, graph_introspect_detail::has_kind<PropertyTag>::value>
Chris@16 46 {};
Chris@16 47
Chris@16 48 // Some standard properties defined independently of Boost.Graph:
Chris@16 49 enum vertex_all_t {vertex_all};
Chris@16 50 enum edge_all_t {edge_all};
Chris@16 51 enum graph_all_t {graph_all};
Chris@16 52 enum vertex_bundle_t {vertex_bundle};
Chris@16 53 enum edge_bundle_t {edge_bundle};
Chris@16 54 enum graph_bundle_t {graph_bundle};
Chris@16 55
Chris@16 56 // Code to look up one property in a property list:
Chris@16 57 template <typename PList, typename PropName, typename Enable = void>
Chris@16 58 struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false); typedef void type;};
Chris@16 59
Chris@16 60 // Special-case properties (vertex_all, edge_all, graph_all)
Chris@16 61 #define BGL_ALL_PROP(tag) \
Chris@16 62 template <typename T> \
Chris@16 63 struct lookup_one_property_internal<T, tag> { \
Chris@16 64 BOOST_STATIC_CONSTANT(bool, found = true); \
Chris@16 65 typedef T type; \
Chris@16 66 static T& lookup(T& x, tag) {return x;} \
Chris@16 67 static const T& lookup(const T& x, tag) {return x;} \
Chris@16 68 }; \
Chris@16 69 template <typename Tag, typename T, typename Base> \
Chris@16 70 struct lookup_one_property_internal<property<Tag, T, Base>, tag> { /* Avoid ambiguity */ \
Chris@16 71 BOOST_STATIC_CONSTANT(bool, found = true); \
Chris@16 72 typedef property<Tag, T, Base> type; \
Chris@16 73 static type& lookup(type& x, tag) {return x;} \
Chris@16 74 static const type& lookup(const type& x, tag) {return x;} \
Chris@16 75 };
Chris@16 76
Chris@16 77 BGL_ALL_PROP(vertex_all_t)
Chris@16 78 BGL_ALL_PROP(edge_all_t)
Chris@16 79 BGL_ALL_PROP(graph_all_t)
Chris@16 80 #undef BGL_ALL_PROP
Chris@16 81
Chris@16 82 // *_bundled; these need to be macros rather than inheritance to resolve ambiguities
Chris@16 83 #define BGL_DO_ONE_BUNDLE_TYPE(kind) \
Chris@16 84 template <typename T> \
Chris@16 85 struct lookup_one_property_internal<T, BOOST_JOIN(kind, _bundle_t)> { \
Chris@16 86 BOOST_STATIC_CONSTANT(bool, found = true); \
Chris@16 87 typedef T type; \
Chris@16 88 static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \
Chris@16 89 static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \
Chris@16 90 }; \
Chris@16 91 \
Chris@16 92 template <typename Tag, typename T, typename Base> \
Chris@16 93 struct lookup_one_property_internal<property<Tag, T, Base>, BOOST_JOIN(kind, _bundle_t)>: lookup_one_property_internal<Base, BOOST_JOIN(kind, _bundle_t)> { \
Chris@16 94 private: \
Chris@16 95 typedef lookup_one_property_internal<Base, BOOST_JOIN(kind, _bundle_t)> base_type; \
Chris@16 96 public: \
Chris@16 97 template <typename BundleTag> \
Chris@16 98 static typename lazy_enable_if_c<(base_type::found && (is_same<BundleTag, BOOST_JOIN(kind, _bundle_t)>::value)), \
Chris@16 99 add_reference<typename base_type::type> >::type \
Chris@16 100 lookup(property<Tag, T, Base>& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \
Chris@16 101 template <typename BundleTag> \
Chris@16 102 static typename lazy_enable_if_c<(base_type::found && (is_same<BundleTag, BOOST_JOIN(kind, _bundle_t)>::value)), \
Chris@16 103 add_reference<const typename base_type::type> >::type \
Chris@16 104 lookup(const property<Tag, T, Base>& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \
Chris@16 105 }; \
Chris@16 106
Chris@16 107 BGL_DO_ONE_BUNDLE_TYPE(vertex)
Chris@16 108 BGL_DO_ONE_BUNDLE_TYPE(edge)
Chris@16 109 BGL_DO_ONE_BUNDLE_TYPE(graph)
Chris@16 110 #undef BGL_DO_ONE_BUNDLE_TYPE
Chris@16 111
Chris@16 112 // Normal old-style properties; second case also handles chaining of bundled property accesses
Chris@16 113 template <typename Tag, typename T, typename Base>
Chris@16 114 struct lookup_one_property_internal<boost::property<Tag, T, Base>, Tag> {
Chris@16 115 BOOST_STATIC_CONSTANT(bool, found = true);
Chris@16 116 typedef property<Tag, T, Base> prop;
Chris@16 117 typedef T type;
Chris@16 118 template <typename U>
Chris@16 119 static typename enable_if<is_same<prop, U>, T&>::type
Chris@16 120 lookup(U& prop, const Tag&) {return prop.m_value;}
Chris@16 121 template <typename U>
Chris@16 122 static typename enable_if<is_same<prop, U>, const T&>::type
Chris@16 123 lookup(const U& prop, const Tag&) {return prop.m_value;}
Chris@16 124 };
Chris@16 125
Chris@16 126 template <typename Tag, typename T, typename Base, typename PropName>
Chris@16 127 struct lookup_one_property_internal<boost::property<Tag, T, Base>, PropName>: lookup_one_property_internal<Base, PropName> {
Chris@16 128 private:
Chris@16 129 typedef lookup_one_property_internal<Base, PropName> base_type;
Chris@16 130 public:
Chris@16 131 template <typename PL>
Chris@16 132 static typename lazy_enable_if<is_same<PL, boost::property<Tag, T, Base> >,
Chris@16 133 add_reference<typename base_type::type> >::type
Chris@16 134 lookup(PL& prop, const PropName& tag) {
Chris@16 135 return base_type::lookup(prop.m_base, tag);
Chris@16 136 }
Chris@16 137 template <typename PL>
Chris@16 138 static typename lazy_enable_if<is_same<PL, boost::property<Tag, T, Base> >,
Chris@16 139 add_reference<const typename base_type::type> >::type
Chris@16 140 lookup(const PL& prop, const PropName& tag) {
Chris@16 141 return base_type::lookup(prop.m_base, tag);
Chris@16 142 }
Chris@16 143 };
Chris@16 144
Chris@16 145 // Pointer-to-member access to bundled properties
Chris@16 146 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
Chris@16 147 template <typename T, typename TMaybeBase, typename R>
Chris@16 148 struct lookup_one_property_internal<T, R TMaybeBase::*, typename enable_if<is_base_of<TMaybeBase, T> >::type> {
Chris@16 149 BOOST_STATIC_CONSTANT(bool, found = true);
Chris@16 150 typedef R type;
Chris@16 151 static R& lookup(T& x, R TMaybeBase::*ptr) {return x.*ptr;}
Chris@16 152 static const R& lookup(const T& x, R TMaybeBase::*ptr) {return x.*ptr;}
Chris@16 153 };
Chris@16 154 #endif
Chris@16 155
Chris@16 156 // Version of above handling const property lists properly
Chris@16 157 template <typename T, typename Tag>
Chris@16 158 struct lookup_one_property: lookup_one_property_internal<T, Tag> {};
Chris@16 159
Chris@16 160 template <typename T, typename Tag>
Chris@16 161 struct lookup_one_property<const T, Tag> {
Chris@16 162 BOOST_STATIC_CONSTANT(bool, found = (lookup_one_property_internal<T, Tag>::found));
Chris@16 163 typedef const typename lookup_one_property_internal<T, Tag>::type type;
Chris@16 164 template <typename U>
Chris@16 165 static typename lazy_enable_if<is_same<T, U>,
Chris@16 166 add_reference<const typename lookup_one_property_internal<T, Tag>::type> >::type
Chris@16 167 lookup(const U& p, Tag tag) {
Chris@16 168 return lookup_one_property_internal<T, Tag>::lookup(p, tag);
Chris@16 169 }
Chris@16 170 };
Chris@16 171
Chris@16 172 // The BGL properties specialize property_kind and
Chris@16 173 // property_num, and use enum's for the Property type (see
Chris@16 174 // graph/properties.hpp), but the user may want to use a class
Chris@16 175 // instead with a nested kind type and num. Also, we may want to
Chris@16 176 // switch BGL back to using class types for properties at some point.
Chris@16 177
Chris@16 178 template <class P>
Chris@16 179 struct has_property : boost::mpl::true_ {};
Chris@16 180 template <>
Chris@16 181 struct has_property<no_property> : boost::mpl::false_ {};
Chris@16 182
Chris@16 183 } // namespace boost
Chris@16 184
Chris@16 185 #include <boost/pending/detail/property.hpp>
Chris@16 186
Chris@16 187 namespace boost {
Chris@16 188
Chris@16 189 template <class PropertyList, class Tag>
Chris@16 190 struct property_value: lookup_one_property<PropertyList, Tag> {};
Chris@16 191
Chris@16 192 template <class PropertyList, class Tag>
Chris@16 193 inline typename lookup_one_property<PropertyList, Tag>::type&
Chris@16 194 get_property_value(PropertyList& p, Tag tag) {
Chris@16 195 return lookup_one_property<PropertyList, Tag>::lookup(p, tag);
Chris@16 196 }
Chris@16 197
Chris@16 198 template <class PropertyList, class Tag>
Chris@16 199 inline const typename lookup_one_property<PropertyList, Tag>::type&
Chris@16 200 get_property_value(const PropertyList& p, Tag tag) {
Chris@16 201 return lookup_one_property<PropertyList, Tag>::lookup(p, tag);
Chris@16 202 }
Chris@16 203
Chris@16 204 namespace detail {
Chris@16 205
Chris@16 206 /** This trait returns true if T is no_property. */
Chris@16 207 template <typename T>
Chris@16 208 struct is_no_property
Chris@16 209 : mpl::bool_<is_same<T, no_property>::value>
Chris@16 210 { };
Chris@16 211
Chris@16 212 template <typename PList, typename Tag>
Chris@16 213 class lookup_one_property_f;
Chris@16 214
Chris@16 215 template <typename PList, typename Tag, typename F> struct lookup_one_property_f_result;
Chris@16 216
Chris@16 217 template <typename PList, typename Tag>
Chris@16 218 struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(PList)> {
Chris@16 219 typedef typename lookup_one_property<PList, Tag>::type type;
Chris@16 220 };
Chris@16 221
Chris@16 222 template <typename PList, typename Tag>
Chris@16 223 struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(PList&)> {
Chris@16 224 typedef typename lookup_one_property<PList, Tag>::type& type;
Chris@16 225 };
Chris@16 226
Chris@16 227 template <typename PList, typename Tag>
Chris@16 228 struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(const PList&)> {
Chris@16 229 typedef const typename lookup_one_property<PList, Tag>::type& type;
Chris@16 230 };
Chris@16 231
Chris@16 232 template <typename PList, typename Tag>
Chris@16 233 class lookup_one_property_f {
Chris@16 234 Tag tag;
Chris@16 235 public:
Chris@16 236 lookup_one_property_f(Tag tag): tag(tag) {}
Chris@16 237 template <typename F> struct result: lookup_one_property_f_result<PList, Tag, F> {};
Chris@16 238
Chris@16 239 typename lookup_one_property_f_result<PList, Tag, const lookup_one_property_f(PList&)>::type
Chris@16 240 operator()(PList& pl) const {
Chris@16 241 return lookup_one_property<PList, Tag>::lookup(pl, tag);
Chris@16 242 }
Chris@16 243 };
Chris@16 244
Chris@16 245 } // namespace detail
Chris@16 246
Chris@16 247 namespace detail {
Chris@16 248 // Stuff for directed_graph and undirected_graph to skip over their first
Chris@16 249 // vertex_index and edge_index properties when providing vertex_all and
Chris@16 250 // edge_all; make sure you know the exact structure of your properties if you
Chris@16 251 // use there.
Chris@16 252 struct remove_first_property {
Chris@16 253 template <typename F>
Chris@16 254 struct result {
Chris@16 255 typedef typename boost::function_traits<F>::arg1_type a1;
Chris@16 256 typedef typename boost::remove_reference<a1>::type non_ref;
Chris@16 257 typedef typename non_ref::next_type nx;
Chris@16 258 typedef typename boost::mpl::if_<boost::is_const<non_ref>, boost::add_const<nx>, nx>::type with_const;
Chris@16 259 typedef typename boost::add_reference<with_const>::type type;
Chris@16 260 };
Chris@16 261 template <typename Prop>
Chris@16 262 typename Prop::next_type& operator()(Prop& p) const {return p.m_base;}
Chris@16 263 template <typename Prop>
Chris@16 264 const typename Prop::next_type& operator()(const Prop& p) const {return p.m_base;}
Chris@16 265 };
Chris@16 266 }
Chris@16 267
Chris@16 268 } // namesapce boost
Chris@16 269
Chris@16 270 #endif /* BOOST_PROPERTY_HPP */