PageRenderTime 44ms CodeModel.GetById 13ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

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

http://hadesmem.googlecode.com/
C++ Header | 367 lines | 256 code | 51 blank | 60 comment | 1 complexity | 8ea29af7ae2dddd82430005d1254e67a 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_TRAITS_HPP
 11#define BOOST_GRAPH_TRAITS_HPP
 12
 13#include <boost/config.hpp>
 14#include <iterator>
 15#include <utility> /* Primarily for std::pair */
 16#include <boost/tuple/tuple.hpp>
 17#include <boost/mpl/if.hpp>
 18#include <boost/mpl/bool.hpp>
 19#include <boost/mpl/not.hpp>
 20#include <boost/type_traits/is_same.hpp>
 21#include <boost/iterator/iterator_categories.hpp>
 22#include <boost/iterator/iterator_adaptor.hpp>
 23#include <boost/pending/property.hpp>
 24#include <boost/detail/workaround.hpp>
 25
 26namespace boost {
 27
 28    template <typename G>
 29    struct graph_traits {
 30        typedef typename G::vertex_descriptor      vertex_descriptor;
 31        typedef typename G::edge_descriptor        edge_descriptor;
 32        typedef typename G::adjacency_iterator     adjacency_iterator;
 33        typedef typename G::out_edge_iterator      out_edge_iterator;
 34        typedef typename G::in_edge_iterator       in_edge_iterator;
 35        typedef typename G::vertex_iterator        vertex_iterator;
 36        typedef typename G::edge_iterator          edge_iterator;
 37
 38        typedef typename G::directed_category      directed_category;
 39        typedef typename G::edge_parallel_category edge_parallel_category;
 40        typedef typename G::traversal_category     traversal_category;
 41
 42        typedef typename G::vertices_size_type     vertices_size_type;
 43        typedef typename G::edges_size_type        edges_size_type;
 44        typedef typename G::degree_size_type       degree_size_type;
 45
 46        static inline vertex_descriptor null_vertex();
 47    };
 48
 49    template <typename G>
 50    inline typename graph_traits<G>::vertex_descriptor
 51    graph_traits<G>::null_vertex()
 52    { return G::null_vertex(); }
 53
 54    // directed_category tags
 55    struct directed_tag { };
 56    struct undirected_tag { };
 57    struct bidirectional_tag : public directed_tag { };
 58
 59    namespace detail {
 60        inline bool is_directed(directed_tag) { return true; }
 61        inline bool is_directed(undirected_tag) { return false; }
 62    }
 63
 64    /** Return true if the given graph is directed. */
 65    template <typename Graph>
 66    bool is_directed(const Graph&) {
 67        typedef typename graph_traits<Graph>::directed_category Cat;
 68        return detail::is_directed(Cat());
 69    }
 70
 71    /** Return true if the given graph is undirected. */
 72    template <typename Graph>
 73    bool is_undirected(const Graph& g) {
 74        return !is_directed(g);
 75    }
 76
 77    /** @name Directed/Undirected Graph Traits */
 78    //@{
 79    namespace graph_detail {
 80        template <typename Tag>
 81        struct is_directed_tag
 82            : mpl::bool_<is_convertible<Tag, directed_tag>::value>
 83        { };
 84    } // namespace graph_detail
 85
 86    template <typename Graph>
 87    struct is_directed_graph
 88        : graph_detail::is_directed_tag<
 89            typename graph_traits<Graph>::directed_category
 90        >
 91    { };
 92
 93    template <typename Graph>
 94    struct is_undirected_graph
 95        : mpl::not_< is_directed_graph<Graph> >
 96    { };
 97    //@}
 98
 99    // edge_parallel_category tags
100    struct allow_parallel_edge_tag { };
101    struct disallow_parallel_edge_tag { };
102
103    namespace detail {
104        inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
105        inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
106    }
107
108    template <typename Graph>
109    bool allows_parallel_edges(const Graph&) {
110        typedef typename graph_traits<Graph>::edge_parallel_category Cat;
111        return detail::allows_parallel(Cat());
112    }
113
114    /** @name Parallel Edges Traits */
115    //@{
116    /**
117     * The is_multigraph metafunction returns true if the graph allows
118     * parallel edges. Technically, a multigraph is a simple graph that
119     * allows parallel edges, but since there are no traits for the allowance
120     * or disallowance of loops, this is a moot point.
121     */
122    template <typename Graph>
123    struct is_multigraph
124        : mpl::bool_<
125            is_same<
126                typename graph_traits<Graph>::edge_parallel_category,
127                allow_parallel_edge_tag
128            >::value
129        >
130    { };
131    //@}
132
133    // traversal_category tags
134    struct incidence_graph_tag { };
135    struct adjacency_graph_tag { };
136    struct bidirectional_graph_tag : virtual incidence_graph_tag { };
137    struct vertex_list_graph_tag { };
138    struct edge_list_graph_tag { };
139    struct adjacency_matrix_tag { };
140
141    /** @name Taversal Category Traits
142     * These traits classify graph types by their supported methods of
143     * vertex and edge traversal.
144     */
145    //@{
146    template <typename Graph>
147    struct is_incidence_graph
148        : mpl::bool_<
149            is_convertible<
150                typename graph_traits<Graph>::traversal_category,
151                incidence_graph_tag
152            >::value
153        >
154    { };
155
156    template <typename Graph>
157    struct is_bidirectional_graph
158        : mpl::bool_<
159            is_convertible<
160                typename graph_traits<Graph>::traversal_category,
161                bidirectional_graph_tag
162            >::value
163        >
164    { };
165
166    template <typename Graph>
167    struct is_vertex_list_graph
168        : mpl::bool_<
169            is_convertible<
170                typename graph_traits<Graph>::traversal_category,
171                vertex_list_graph_tag
172            >::value
173        >
174    { };
175
176    template <typename Graph>
177    struct is_edge_list_graph
178        : mpl::bool_<
179            is_convertible<
180                typename graph_traits<Graph>::traversal_category,
181                edge_list_graph_tag
182            >::value
183        >
184    { };
185
186    template <typename Graph>
187    struct is_adjacency_matrix
188        : mpl::bool_<
189            is_convertible<
190                typename graph_traits<Graph>::traversal_category,
191                adjacency_matrix_tag
192            >::value
193        >
194    { };
195    //@}
196
197    /** @name Directed Graph Traits
198     * These metafunctions are used to fully classify directed vs. undirected
199     * graphs. Recall that an undirected graph is also bidirectional, but it
200     * cannot be both undirected and directed at the same time.
201     */
202    //@{
203    template <typename Graph>
204    struct is_directed_unidirectional_graph
205        : mpl::and_<
206            is_directed_graph<Graph>, mpl::not_< is_bidirectional_graph<Graph> >
207        >
208    { };
209
210    template <typename Graph>
211    struct is_directed_bidirectional_graph
212        : mpl::and_<
213            is_directed_graph<Graph>, is_bidirectional_graph<Graph>
214        >
215    { };
216    //@}
217
218    //?? not the right place ?? Lee
219    typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
220
221    // Forward declare graph_bundle_t property name (from
222    // boost/graph/properties.hpp, which includes this file) for
223    // bundled_result.
224    enum graph_bundle_t {graph_bundle};
225
226    template <typename G>
227    struct graph_property_type {
228      typedef typename G::graph_property_type type;
229    };
230    template <typename G>
231    struct edge_property_type {
232      typedef typename G::edge_property_type type;
233    };
234    template <typename G>
235    struct vertex_property_type {
236      typedef typename G::vertex_property_type type;
237    };
238
239    struct no_bundle { };
240    struct no_graph_bundle : no_bundle { };
241    struct no_vertex_bundle : no_bundle { };
242    struct no_edge_bundle : no_bundle { };
243
244    template<typename G>
245    struct graph_bundle_type {
246      typedef typename G::graph_bundled type;
247    };
248
249    template<typename G>
250    struct vertex_bundle_type {
251      typedef typename G::vertex_bundled type;
252    };
253
254    template<typename G>
255    struct edge_bundle_type {
256      typedef typename G::edge_bundled type;
257    };
258
259    namespace graph { namespace detail {
260        template<typename Graph, typename Descriptor>
261        class bundled_result {
262            typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
263            typedef typename mpl::if_c<(is_same<Descriptor, Vertex>::value),
264                                        vertex_bundle_type<Graph>,
265                                        edge_bundle_type<Graph> >::type bundler;
266        public:
267            typedef typename bundler::type type;
268        };
269
270        template<typename Graph>
271        class bundled_result<Graph, graph_bundle_t> {
272            typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
273            typedef graph_bundle_type<Graph> bundler;
274        public:
275            typedef typename bundler::type type;
276        };
277
278    } } // namespace graph::detail
279
280    namespace graph_detail {
281      // A helper metafunction for determining whether or not a type is
282      // bundled.
283      template <typename T>
284      struct is_no_bundle : mpl::bool_<is_convertible<T, no_bundle>::value>
285      { };
286    } // namespace graph_detail
287
288    /** @name Graph Property Traits
289     * These metafunctions (along with those above), can be used to access the
290     * vertex and edge properties (bundled or otherwise) of vertices and
291     * edges.
292     */
293    //@{
294    template<typename Graph>
295    struct has_graph_property
296      : mpl::not_<
297        typename detail::is_no_property<
298          typename graph_property_type<Graph>::type
299        >::type
300      >::type
301    { };
302
303    template<typename Graph>
304    struct has_bundled_graph_property
305      : mpl::not_<
306        graph_detail::is_no_bundle<typename graph_bundle_type<Graph>::type>
307      >
308    { };
309
310    template <typename Graph>
311    struct has_vertex_property
312        : mpl::not_<
313            typename detail::is_no_property<typename vertex_property_type<Graph>::type>
314        >::type
315    { };
316
317    template <typename Graph>
318    struct has_bundled_vertex_property
319        : mpl::not_<
320            graph_detail::is_no_bundle<typename vertex_bundle_type<Graph>::type>
321        >
322    { };
323
324    template <typename Graph>
325    struct has_edge_property
326        : mpl::not_<
327            typename detail::is_no_property<typename edge_property_type<Graph>::type>
328        >::type
329    { };
330
331    template <typename Graph>
332    struct has_bundled_edge_property
333        : mpl::not_<
334            graph_detail::is_no_bundle<typename edge_bundle_type<Graph>::type>
335        >
336    { };
337    //@}
338
339} // namespace boost
340
341// Since pair is in namespace std, Koenig lookup will find source and
342// target if they are also defined in namespace std.  This is illegal,
343// but the alternative is to put source and target in the global
344// namespace which causes name conflicts with other libraries (like
345// SUIF).
346namespace std {
347
348  /* Some helper functions for dealing with pairs as edges */
349  template <class T, class G>
350  T source(pair<T,T> p, const G&) { return p.first; }
351
352  template <class T, class G>
353  T target(pair<T,T> p, const G&) { return p.second; }
354
355}
356
357#if defined(__GNUC__) && defined(__SGI_STL_PORT)
358// For some reason g++ with STLport does not see the above definition
359// of source() and target() unless we bring them into the boost
360// namespace.
361namespace boost {
362  using std::source;
363  using std::target;
364}
365#endif
366
367#endif // BOOST_GRAPH_TRAITS_HPP