You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
154 lines
4.6 KiB
154 lines
4.6 KiB
// |
|
//======================================================================= |
|
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. |
|
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek |
|
// |
|
// Distributed under the Boost Software License, Version 1.0. (See |
|
// accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
//======================================================================= |
|
// |
|
#ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP |
|
#define BOOST_GRAPH_GRAPH_AS_TREE_HPP |
|
|
|
#include <vector> |
|
#include <boost/config.hpp> |
|
#include <boost/property_map/property_map.hpp> |
|
#include <boost/graph/tree_traits.hpp> |
|
#include <boost/graph/graph_traits.hpp> |
|
#include <boost/graph/breadth_first_search.hpp> |
|
#include <boost/graph/visitors.hpp> |
|
|
|
namespace boost { |
|
|
|
template <class Graph, class Node, class ChIt, class Derived> |
|
class graph_as_tree_base |
|
{ |
|
typedef Derived Tree; |
|
public: |
|
typedef Node node_descriptor; |
|
typedef ChIt children_iterator; |
|
|
|
graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { } |
|
|
|
friend Node root(const Tree& t) { return t._root; } |
|
|
|
template <class N> |
|
friend std::pair<ChIt,ChIt> |
|
children(N n, const Tree& t) { return adjacent_vertices(n, t._g); } |
|
|
|
template<class N> |
|
friend Node parent(N n, const Tree& t) { |
|
return boost::get(t.parent_pa(), n); |
|
} |
|
|
|
Graph& _g; |
|
Node _root; |
|
}; |
|
|
|
struct graph_as_tree_tag { }; |
|
|
|
template <class Graph, class ParentMap |
|
, class Node |
|
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
= typename graph_traits<Graph>::vertex_descriptor |
|
#endif |
|
, class ChIt |
|
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
= typename graph_traits<Graph>::adjacency_iterator |
|
#endif |
|
> |
|
class graph_as_tree |
|
: public graph_as_tree_base<Graph, Node, ChIt, |
|
graph_as_tree<Graph,ParentMap,Node,ChIt> > |
|
{ |
|
typedef graph_as_tree self; |
|
typedef graph_as_tree_base<Graph, Node, ChIt, self> super; |
|
public: |
|
graph_as_tree(Graph& g, Node root) : super(g, root) { } |
|
|
|
graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) { |
|
breadth_first_search(g, root, |
|
visitor(make_bfs_visitor |
|
(record_predecessors(p, boost::on_tree_edge())))); |
|
} |
|
ParentMap parent_pa() const { return _p; } |
|
typedef graph_as_tree_tag graph_tag; // for property_map |
|
protected: |
|
ParentMap _p; |
|
}; |
|
|
|
|
|
namespace detail { |
|
|
|
struct graph_as_tree_vertex_property_selector { |
|
template <typename GraphAsTree, typename Property, typename Tag> |
|
struct bind_ { |
|
typedef typename GraphAsTree::base_type Graph; |
|
typedef property_map<Graph, Tag> PMap; |
|
typedef typename PMap::type type; |
|
typedef typename PMap::const_type const_type; |
|
}; |
|
}; |
|
|
|
struct graph_as_tree_edge_property_selector { |
|
template <typename GraphAsTree, typename Property, typename Tag> |
|
struct bind_ { |
|
typedef typename GraphAsTree::base_type Graph; |
|
typedef property_map<Graph, Tag> PMap; |
|
typedef typename PMap::type type; |
|
typedef typename PMap::const_type const_type; |
|
}; |
|
}; |
|
|
|
} // namespace detail |
|
|
|
template <> |
|
struct vertex_property_selector<graph_as_tree_tag> { |
|
typedef detail::graph_as_tree_vertex_property_selector type; |
|
}; |
|
|
|
template <> |
|
struct edge_property_selector<graph_as_tree_tag> { |
|
typedef detail::graph_as_tree_edge_property_selector type; |
|
}; |
|
|
|
template <typename Graph, typename P, typename N, typename C, |
|
typename Property> |
|
typename property_map<Graph, Property>::type |
|
get(Property p, graph_as_tree<Graph,P,N,C>& g) |
|
{ |
|
return get(p, g._g); |
|
} |
|
|
|
template <typename Graph, typename P, typename N, typename C, |
|
typename Property> |
|
typename property_map<Graph, Property>::const_type |
|
get(Property p, const graph_as_tree<Graph,P,N,C>& g) |
|
{ |
|
const Graph& gref = g._g; // in case GRef is non-const |
|
return get(p, gref); |
|
} |
|
|
|
template <typename Graph, typename P, typename N, typename C, |
|
typename Property, typename Key> |
|
typename property_traits< |
|
typename property_map<Graph, Property>::const_type |
|
>::value_type |
|
get(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k) |
|
{ |
|
return get(p, g._g, k); |
|
} |
|
|
|
template <typename Graph, typename P, typename N, typename C, |
|
typename Property, typename Key, typename Value> |
|
void |
|
put(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k, |
|
const Value& val) |
|
{ |
|
put(p, g._g, k, val); |
|
} |
|
|
|
} // namespace boost |
|
|
|
#endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP
|
|
|