PageRenderTime 42ms CodeModel.GetById 9ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/graph/properties.hpp

http://hadesmem.googlecode.com/
C++ Header | 512 lines | 399 code | 59 blank | 54 comment | 1 complexity | 2d1e8c25b7cdc92ca22722aad3b89a71 MD5 | raw file
  1//=======================================================================
  2// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4//
  5// Distributed under the Boost Software License, Version 1.0. (See
  6// accompanying file LICENSE_1_0.txt or copy at
  7// http://www.boost.org/LICENSE_1_0.txt)
  8//=======================================================================
  9
 10#ifndef BOOST_GRAPH_PROPERTIES_HPP
 11#define BOOST_GRAPH_PROPERTIES_HPP
 12
 13#include <boost/config.hpp>
 14#include <boost/assert.hpp>
 15#include <boost/pending/property.hpp>
 16#include <boost/detail/workaround.hpp>
 17
 18// Include the property map library and extensions in the BGL.
 19#include <boost/property_map/property_map.hpp>
 20#include <boost/graph/property_maps/constant_property_map.hpp>
 21#include <boost/graph/property_maps/null_property_map.hpp>
 22
 23#include <boost/graph/graph_traits.hpp>
 24#include <boost/type_traits/is_convertible.hpp>
 25#include <boost/limits.hpp>
 26#include <boost/mpl/and.hpp>
 27#include <boost/mpl/not.hpp>
 28#include <boost/mpl/if.hpp>
 29
 30#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 31// Stay out of the way of the concept checking class
 32# define Graph Graph_
 33# define RandomAccessContainer RandomAccessContainer_
 34#endif
 35
 36namespace boost {
 37
 38  enum default_color_type { white_color, gray_color, green_color, red_color, black_color };
 39
 40  template <class ColorValue>
 41  struct color_traits {
 42    static default_color_type white() { return white_color; }
 43    static default_color_type gray() { return gray_color; }
 44    static default_color_type green() { return green_color; }
 45    static default_color_type red() { return red_color; }
 46    static default_color_type black() { return black_color; }
 47  };
 48
 49  // These functions are now obsolete, replaced by color_traits.
 50  inline default_color_type white(default_color_type) { return white_color; }
 51  inline default_color_type gray(default_color_type) { return gray_color; }
 52  inline default_color_type green(default_color_type) { return green_color; }
 53  inline default_color_type red(default_color_type) { return red_color; }
 54  inline default_color_type black(default_color_type) { return black_color; }
 55
 56#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 57  template <>
 58  struct property_traits<default_color_type*> {
 59    typedef default_color_type value_type;
 60    typedef std::ptrdiff_t key_type;
 61    typedef default_color_type& reference;
 62    typedef lvalue_property_map_tag category;
 63  };
 64  // get/put already defined for T*
 65#endif
 66
 67  struct graph_property_tag { };
 68  struct vertex_property_tag { };
 69  struct edge_property_tag { };
 70
 71#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 72  // See examples/edge_property.cpp for how to use this.
 73#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
 74  template <> struct property_kind<KIND##_##NAME##_t> { \
 75    typedef KIND##_property_tag type; \
 76  }
 77#else
 78#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
 79  template <> struct property_kind<KIND##_##NAME##_t> { \
 80    typedef KIND##_property_tag type; \
 81  }
 82#endif
 83
 84#define BOOST_DEF_PROPERTY(KIND, NAME) \
 85  enum KIND##_##NAME##_t { KIND##_##NAME }; \
 86  BOOST_INSTALL_PROPERTY(KIND, NAME)
 87
 88  BOOST_DEF_PROPERTY(vertex, all);
 89  BOOST_DEF_PROPERTY(edge, all);
 90  BOOST_DEF_PROPERTY(graph, all);
 91  BOOST_DEF_PROPERTY(vertex, index);
 92  BOOST_DEF_PROPERTY(vertex, index1);
 93  BOOST_DEF_PROPERTY(vertex, index2);
 94  BOOST_DEF_PROPERTY(vertex, root);
 95  BOOST_DEF_PROPERTY(edge, index);
 96  BOOST_DEF_PROPERTY(edge, name);
 97  BOOST_DEF_PROPERTY(edge, weight);
 98  BOOST_DEF_PROPERTY(edge, weight2);
 99  BOOST_DEF_PROPERTY(edge, color);
100  BOOST_DEF_PROPERTY(vertex, name);
101  BOOST_DEF_PROPERTY(graph, name);
102  BOOST_DEF_PROPERTY(vertex, distance);
103  BOOST_DEF_PROPERTY(vertex, distance2);
104  BOOST_DEF_PROPERTY(vertex, color);
105  BOOST_DEF_PROPERTY(vertex, degree);
106  BOOST_DEF_PROPERTY(vertex, in_degree);
107  BOOST_DEF_PROPERTY(vertex, out_degree);
108  BOOST_DEF_PROPERTY(vertex, current_degree);
109  BOOST_DEF_PROPERTY(vertex, priority);
110  BOOST_DEF_PROPERTY(vertex, discover_time);
111  BOOST_DEF_PROPERTY(vertex, finish_time);
112  BOOST_DEF_PROPERTY(vertex, predecessor);
113  BOOST_DEF_PROPERTY(vertex, rank);
114  BOOST_DEF_PROPERTY(vertex, centrality);
115  BOOST_DEF_PROPERTY(vertex, lowpoint);
116  BOOST_DEF_PROPERTY(vertex, potential);
117  BOOST_DEF_PROPERTY(vertex, update);
118  BOOST_DEF_PROPERTY(edge, reverse);
119  BOOST_DEF_PROPERTY(edge, capacity);
120  BOOST_DEF_PROPERTY(edge, flow);
121  BOOST_DEF_PROPERTY(edge, residual_capacity);
122  BOOST_DEF_PROPERTY(edge, centrality);
123  BOOST_DEF_PROPERTY(edge, discover_time);
124  BOOST_DEF_PROPERTY(edge, update);
125  BOOST_DEF_PROPERTY(edge, finished);
126  BOOST_DEF_PROPERTY(graph, visitor);
127
128  // These tags are used for property bundles
129  // BOOST_DEF_PROPERTY(graph, bundle); -- needed in graph_traits.hpp, so enum is defined there
130  BOOST_INSTALL_PROPERTY(graph, bundle);
131  BOOST_DEF_PROPERTY(vertex, bundle);
132  BOOST_DEF_PROPERTY(edge, bundle);
133
134  // These tags are used to denote the owners and local descriptors
135  // for the vertices and edges of a distributed graph.
136  BOOST_DEF_PROPERTY(vertex, global);
137  BOOST_DEF_PROPERTY(vertex, owner);
138  BOOST_DEF_PROPERTY(vertex, local);
139  BOOST_DEF_PROPERTY(edge, global);
140  BOOST_DEF_PROPERTY(edge, owner);
141  BOOST_DEF_PROPERTY(edge, local);
142  BOOST_DEF_PROPERTY(vertex, local_index);
143  BOOST_DEF_PROPERTY(edge, local_index);
144
145#undef BOOST_DEF_PROPERTY
146
147  namespace detail {
148
149    struct dummy_edge_property_selector {
150      template <class Graph, class Property, class Tag>
151      struct bind_ {
152        typedef identity_property_map type;
153        typedef identity_property_map const_type;
154      };
155    };
156    struct dummy_vertex_property_selector {
157      template <class Graph, class Property, class Tag>
158      struct bind_ {
159        typedef identity_property_map type;
160        typedef identity_property_map const_type;
161      };
162    };
163
164  } // namespace detail
165
166  // Graph classes can either partially specialize property_map
167  // or they can specialize these two selector classes.
168  template <class GraphTag>
169  struct edge_property_selector {
170    typedef detail::dummy_edge_property_selector type;
171  };
172
173  template <class GraphTag>
174  struct vertex_property_selector {
175    typedef detail::dummy_vertex_property_selector type;
176  };
177
178  namespace detail {
179
180    template <typename A> struct return_void {typedef void type;};
181
182    template <typename Graph, typename Enable = void>
183    struct graph_tag_or_void {
184      typedef void type;
185    };
186
187    template <typename Graph>
188    struct graph_tag_or_void<Graph, typename return_void<typename Graph::graph_tag>::type> {
189      typedef typename Graph::graph_tag type;
190    };
191
192    template <class Graph, class PropertyTag>
193    struct edge_property_map {
194      typedef typename edge_property_type<Graph>::type Property;
195      typedef typename graph_tag_or_void<Graph>::type graph_tag;
196      typedef typename edge_property_selector<graph_tag>::type Selector;
197      typedef typename Selector::template bind_<Graph,Property,PropertyTag>
198        Bind;
199      typedef typename Bind::type type;
200      typedef typename Bind::const_type const_type;
201    };
202    template <class Graph, class PropertyTag>
203    class vertex_property_map {
204    public:
205      typedef typename vertex_property_type<Graph>::type Property;
206      typedef typename graph_tag_or_void<Graph>::type graph_tag;
207      typedef typename vertex_property_selector<graph_tag>::type Selector;
208      typedef typename Selector::template bind_<Graph,Property,PropertyTag>
209        Bind;
210    public:
211      typedef typename Bind::type type;
212      typedef typename Bind::const_type const_type;
213    };
214
215    // This selects the kind of property map, whether is maps from
216    // edges or from vertices.
217    //
218    // It is overly complicated because it's a workaround for
219    // partial specialization.
220    struct choose_vertex_property_map {
221      template <class Graph, class Property>
222      struct bind_ {
223        typedef vertex_property_map<Graph, Property> type;
224      };
225    };
226    struct choose_edge_property_map {
227      template <class Graph, class Property>
228      struct bind_ {
229        typedef edge_property_map<Graph, Property> type;
230      };
231    };
232    template <class Kind>
233    struct property_map_kind_selector {
234      // VC++ gets confused if this isn't defined, even though
235      // this never gets used.
236      typedef choose_vertex_property_map type;
237    };
238    template <> struct property_map_kind_selector<vertex_property_tag> {
239      typedef choose_vertex_property_map type;
240    };
241    template <> struct property_map_kind_selector<edge_property_tag> {
242      typedef choose_edge_property_map type;
243    };
244  } // namespace detail
245
246  template <class Graph, class Property>
247  struct property_map {
248  // private:
249    typedef typename property_kind<Property>::type Kind;
250    typedef typename detail::property_map_kind_selector<Kind>::type Selector;
251    typedef typename Selector::template bind_<Graph, Property> Bind;
252    typedef typename Bind::type Map;
253  public:
254    typedef typename Map::type type;
255    typedef typename Map::const_type const_type;
256  };
257
258  // shortcut for accessing the value type of the property map
259  template <class Graph, class Property>
260  class property_map_value {
261    typedef typename property_map<Graph, Property>::const_type PMap;
262  public:
263    typedef typename property_traits<PMap>::value_type type;
264  };
265
266  template <class Graph, class Property>
267  class graph_property {
268  public:
269    typedef typename property_value<
270      typename boost::graph_property_type<Graph>::type, Property
271    >::type type;
272  };
273
274  template <class Graph>
275  class vertex_property {
276  public:
277    typedef typename Graph::vertex_property_type type;
278  };
279  template <class Graph>
280  class edge_property {
281  public:
282    typedef typename Graph::edge_property_type type;
283  };
284
285  template <typename Graph>
286  class degree_property_map
287    : public put_get_helper<typename graph_traits<Graph>::degree_size_type,
288                            degree_property_map<Graph> >
289  {
290  public:
291    typedef typename graph_traits<Graph>::vertex_descriptor key_type;
292    typedef typename graph_traits<Graph>::degree_size_type value_type;
293    typedef value_type reference;
294    typedef readable_property_map_tag category;
295    degree_property_map(const Graph& g) : m_g(g) { }
296    value_type operator[](const key_type& v) const {
297      return degree(v, m_g);
298    }
299  private:
300    const Graph& m_g;
301  };
302  template <typename Graph>
303  inline degree_property_map<Graph>
304  make_degree_map(const Graph& g) {
305    return degree_property_map<Graph>(g);
306  }
307
308  //========================================================================
309  // Iterator Property Map Generating Functions contributed by
310  // Kevin Vanhorn. (see also the property map generating functions
311  // in boost/property_map/property_map.hpp)
312
313#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
314  // A helper function for creating a vertex property map out of a
315  // random access iterator and the internal vertex index map from a
316  // graph.
317  template <class PropertyGraph, class RandomAccessIterator>
318  inline
319  iterator_property_map<
320    RandomAccessIterator,
321    typename property_map<PropertyGraph, vertex_index_t>::type,
322    typename std::iterator_traits<RandomAccessIterator>::value_type,
323    typename std::iterator_traits<RandomAccessIterator>::reference
324  >
325  make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
326  {
327    return make_iterator_property_map(iter, get(vertex_index, g));
328  }
329
330  // Use this next function when vertex_descriptor is known to be an
331  // integer type, with values ranging from 0 to num_vertices(g).
332  //
333  template <class RandomAccessIterator>
334  inline
335  iterator_property_map<
336    RandomAccessIterator,
337    identity_property_map,
338    typename std::iterator_traits<RandomAccessIterator>::value_type,
339    typename std::iterator_traits<RandomAccessIterator>::reference
340  >
341  make_iterator_vertex_map(RandomAccessIterator iter)
342  {
343    return make_iterator_property_map(iter, identity_property_map());
344  }
345#endif
346
347  template <class PropertyGraph, class RandomAccessContainer>
348  inline
349  iterator_property_map<
350    typename RandomAccessContainer::iterator,
351    typename property_map<PropertyGraph, vertex_index_t>::type,
352    typename RandomAccessContainer::value_type,
353    typename RandomAccessContainer::reference
354  >
355  make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
356  {
357    BOOST_ASSERT(c.size() >= num_vertices(g));
358    return make_iterator_vertex_map(c.begin(), g);
359  }
360
361  template <class RandomAccessContainer> inline
362  iterator_property_map<
363    typename RandomAccessContainer::iterator,
364    identity_property_map,
365    typename RandomAccessContainer::value_type,
366    typename RandomAccessContainer::reference
367  >
368  make_container_vertex_map(RandomAccessContainer& c)
369  {
370    return make_iterator_vertex_map(c.begin());
371  }
372
373#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
374#  define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
375#endif
376
377#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) && !defined (BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
378// This compiler cannot define a partial specialization based on a
379// pointer-to-member type, as seen in boost/graph/subgraph.hpp line 985 (as of
380// trunk r53912)
381#  define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
382#endif
383
384#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
385  template<typename Graph, typename Descriptor, typename Bundle, typename T>
386  struct bundle_property_map
387    : put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
388  {
389    typedef Descriptor key_type;
390    typedef typename remove_const<T>::type value_type;
391    typedef T& reference;
392    typedef lvalue_property_map_tag category;
393
394    bundle_property_map() { }
395    bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {}
396
397    reference operator[](key_type k) const { return (*g)[k].*pm; }
398  private:
399    Graph* g;
400    T Bundle::* pm;
401  };
402
403  namespace detail {
404    template<typename VertexBundle, typename EdgeBundle, typename Bundle>
405      struct is_vertex_bundle
406      : mpl::and_<is_convertible<VertexBundle*, Bundle*>,
407                  mpl::and_<mpl::not_<is_void<VertexBundle> >,
408                            mpl::not_<is_same<VertexBundle, no_property> > > >
409      { };
410  }
411
412  // Specialize the property map template to generate bundled property maps.
413  template <typename Graph, typename T, typename Bundle>
414  struct property_map<Graph, T Bundle::*>
415  {
416  private:
417    typedef graph_traits<Graph> traits;
418    typedef typename Graph::vertex_bundled vertex_bundled;
419    typedef typename Graph::edge_bundled edge_bundled;
420    typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
421                       typename traits::vertex_descriptor,
422                       typename traits::edge_descriptor>::type
423      descriptor;
424    typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
425                       vertex_bundled,
426                       edge_bundled>::type
427      actual_bundle;
428
429  public:
430    typedef bundle_property_map<Graph, descriptor, actual_bundle, T> type;
431    typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T>
432      const_type;
433  };
434#endif
435
436// These metafunctions help implement the process of determining the vertex
437// and edge properties of a graph.
438namespace graph_detail {
439    template<typename Retag>
440    struct retagged_property {
441        typedef typename Retag::type type;
442    };
443
444    // Search the normalized PropList (as returned by retagged<>::type) for
445    // the given bundle. Return the type error if no such bundle can be found.
446    template <typename PropList, typename Bundle>
447    struct retagged_bundle {
448      typedef typename property_value<PropList, Bundle>::type Value;
449      typedef typename mpl::if_<
450        is_same<Value, detail::error_property_not_found>, no_bundle, Value
451      >::type type;
452    };
453
454    template<typename Prop, typename Bundle>
455    class normal_property {
456      // Normalize the property into a property list.
457      typedef detail::retag_property_list<Bundle, Prop> List;
458    public:
459      // Extract the normalized property and bundle types.
460      typedef typename retagged_property<List>::type property;
461      typedef typename retagged_bundle<property, Bundle>::type bundle;
462    };
463
464    template<typename Prop>
465    struct graph_prop : normal_property<Prop, graph_bundle_t>
466    { };
467
468    template<typename Prop>
469    struct vertex_prop : normal_property<Prop, vertex_bundle_t>
470    { };
471
472    template<typename Prop>
473    struct edge_prop : normal_property<Prop, edge_bundle_t>
474    { };
475} // namespace graph_detail
476
477// NOTE: These functions are declared, but never defined since they need to
478// be overloaded by graph implementations. However, we need them to be
479// declared for the functions below.
480template<typename Graph, typename Tag>
481typename graph_property<Graph, graph_bundle_t>::type&
482get_property(Graph& g, Tag);
483
484template<typename Graph, typename Tag>
485typename graph_property<Graph, graph_bundle_t>::type const&
486get_property(Graph const& g, Tag);
487
488#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
489// NOTE: This operation is a simple adaptor over the overloaded get_property
490// operations.
491template<typename Graph>
492inline typename graph_property<Graph, graph_bundle_t>::type&
493get_property(Graph& g) {
494  return get_property(g, graph_bundle);
495}
496
497template<typename Graph>
498inline typename graph_property<Graph, graph_bundle_t>::type const&
499get_property(Graph const& g) {
500  return get_property(g, graph_bundle);
501}
502#endif
503
504} // namespace boost
505
506#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
507// Stay out of the way of the concept checking class
508# undef Graph
509# undef RandomAccessIterator
510#endif
511
512#endif /* BOOST_GRAPH_PROPERTIES_HPPA */