1 //=======================================================================
2 // Copyright 2001 University of Notre Dame.
3 // Copyright 2003 Jeremy Siek
4 // Authors: Lie-Quan Lee, Jeremy Siek, and Douglas Gregor
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //=======================================================================
10 #ifndef BOOST_GRAPHVIZ_HPP
11 #define BOOST_GRAPHVIZ_HPP
13 #include <boost/config.hpp>
18 #include <stdio.h> // for FILE
19 #include <boost/property_map/property_map.hpp>
20 #include <boost/tuple/tuple.hpp>
21 #include <boost/graph/graph_traits.hpp>
22 #include <boost/graph/properties.hpp>
23 #include <boost/graph/subgraph.hpp>
24 #include <boost/graph/adjacency_list.hpp>
25 #include <boost/property_map/dynamic_property_map.hpp>
26 #include <boost/graph/overloading.hpp>
28 #ifdef BOOST_HAS_DECLSPEC
29 # if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_GRAPH_DYN_LINK)
30 # ifdef BOOST_GRAPH_SOURCE
31 # define BOOST_GRAPH_DECL __declspec(dllexport)
33 # define BOOST_GRAPH_DECL __declspec(dllimport)
34 # endif // BOOST_GRAPH_SOURCE
36 #endif // BOOST_HAS_DECLSPEC
38 #ifndef BOOST_GRAPH_DECL
39 # define BOOST_GRAPH_DECL
44 template <typename directed_category
>
45 struct graphviz_io_traits
{
46 static std::string
name() {
49 static std::string
delimiter() {
54 struct graphviz_io_traits
<undirected_tag
> {
55 static std::string
name() {
58 static std::string
delimiter() {
63 struct default_writer
{
64 void operator()(std::ostream
&) const {
67 void operator()(std::ostream
&, const VorE
&) const {
74 label_writer(Name _name
) : name(_name
) {}
75 template <class VertexOrEdge
>
76 void operator()(std::ostream
& out
, const VertexOrEdge
& v
) const {
77 out
<< "[label=\"" << get(name
, v
) << "\"]";
83 inline label_writer
<Name
>
84 make_label_writer(Name n
) {
85 return label_writer
<Name
>(n
);
88 enum edge_attribute_t
{ edge_attribute
= 1111 };
89 enum vertex_attribute_t
{ vertex_attribute
= 2222 };
90 enum graph_graph_attribute_t
{ graph_graph_attribute
= 3333 };
91 enum graph_vertex_attribute_t
{ graph_vertex_attribute
= 4444 };
92 enum graph_edge_attribute_t
{ graph_edge_attribute
= 5555 };
94 BOOST_INSTALL_PROPERTY(edge
, attribute
);
95 BOOST_INSTALL_PROPERTY(vertex
, attribute
);
96 BOOST_INSTALL_PROPERTY(graph
, graph_attribute
);
97 BOOST_INSTALL_PROPERTY(graph
, vertex_attribute
);
98 BOOST_INSTALL_PROPERTY(graph
, edge_attribute
);
101 template <class Attribute
>
102 inline void write_attributes(const Attribute
& attr
, std::ostream
& out
) {
103 typename
Attribute::const_iterator i
, iend
;
107 while ( i
!= iend
) {
108 out
<< i
->first
<< "=\"" << i
->second
<< "\"";
115 template<typename Attributes
>
116 inline void write_all_attributes(Attributes attributes
,
117 const std::string
& name
,
120 typename
Attributes::const_iterator i
= attributes
.begin(),
121 end
= attributes
.end();
123 out
<< name
<< " [\n";
124 write_attributes(attributes
, out
);
129 inline void write_all_attributes(detail::error_property_not_found
,
133 // Do nothing - no attributes exist
139 template <typename GraphGraphAttributes
,
140 typename GraphNodeAttributes
,
141 typename GraphEdgeAttributes
>
142 struct graph_attributes_writer
144 graph_attributes_writer(GraphGraphAttributes gg
,
145 GraphNodeAttributes gn
,
146 GraphEdgeAttributes ge
)
147 : g_attributes(gg
), n_attributes(gn
), e_attributes(ge
) { }
149 void operator()(std::ostream
& out
) const {
150 write_all_attributes(g_attributes
, "graph", out
);
151 write_all_attributes(n_attributes
, "node", out
);
152 write_all_attributes(e_attributes
, "edge", out
);
154 GraphGraphAttributes g_attributes
;
155 GraphNodeAttributes n_attributes
;
156 GraphEdgeAttributes e_attributes
;
159 template <typename GAttrMap
, typename NAttrMap
, typename EAttrMap
>
160 graph_attributes_writer
<GAttrMap
, NAttrMap
, EAttrMap
>
161 make_graph_attributes_writer(const GAttrMap
& g_attr
, const NAttrMap
& n_attr
,
162 const EAttrMap
& e_attr
) {
163 return graph_attributes_writer
<GAttrMap
, NAttrMap
, EAttrMap
>
164 (g_attr
, n_attr
, e_attr
);
168 template <typename Graph
>
169 graph_attributes_writer
170 <typename graph_property
<Graph
, graph_graph_attribute_t
>::type
,
171 typename graph_property
<Graph
, graph_vertex_attribute_t
>::type
,
172 typename graph_property
<Graph
, graph_edge_attribute_t
>::type
>
173 make_graph_attributes_writer(const Graph
& g
)
175 typedef typename graph_property
<Graph
, graph_graph_attribute_t
>::type
177 typedef typename graph_property
<Graph
, graph_vertex_attribute_t
>::type
179 typedef typename graph_property
<Graph
, graph_edge_attribute_t
>::type
181 GAttrMap gam
= get_property(g
, graph_graph_attribute
);
182 NAttrMap nam
= get_property(g
, graph_vertex_attribute
);
183 EAttrMap eam
= get_property(g
, graph_edge_attribute
);
184 graph_attributes_writer
<GAttrMap
, NAttrMap
, EAttrMap
> writer(gam
, nam
, eam
);
188 template <typename AttributeMap
>
189 struct attributes_writer
{
190 attributes_writer(AttributeMap attr
)
191 : attributes(attr
) { }
193 template <class VorE
>
194 void operator()(std::ostream
& out
, const VorE
& e
) const {
195 this->write_attribute(out
, attributes
[e
]);
199 template<typename AttributeSequence
>
200 void write_attribute(std::ostream
& out
,
201 const AttributeSequence
& seq
) const
205 write_attributes(seq
, out
);
210 void write_attribute(std::ostream
&,
211 detail::error_property_not_found
) const
214 AttributeMap attributes
;
217 template <typename Graph
>
219 <typename property_map
<Graph
, edge_attribute_t
>::const_type
>
220 make_edge_attributes_writer(const Graph
& g
)
222 typedef typename property_map
<Graph
, edge_attribute_t
>::const_type
224 return attributes_writer
<EdgeAttributeMap
>(get(edge_attribute
, g
));
227 template <typename Graph
>
229 <typename property_map
<Graph
, vertex_attribute_t
>::const_type
>
230 make_vertex_attributes_writer(const Graph
& g
)
232 typedef typename property_map
<Graph
, vertex_attribute_t
>::const_type
234 return attributes_writer
<VertexAttributeMap
>(get(vertex_attribute
, g
));
237 template <typename Graph
, typename VertexPropertiesWriter
,
238 typename EdgePropertiesWriter
, typename GraphPropertiesWriter
,
242 (std::ostream
& out
, const Graph
& g
,
243 VertexPropertiesWriter vpw
,
244 EdgePropertiesWriter epw
,
245 GraphPropertiesWriter gpw
,
247 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
249 typedef typename graph_traits
<Graph
>::directed_category cat_type
;
250 typedef graphviz_io_traits
<cat_type
> Traits
;
251 std::string name
= "G";
252 out
<< Traits::name() << " " << name
<< " {" << std::endl
;
254 gpw(out
); //print graph properties
256 typename graph_traits
<Graph
>::vertex_iterator i
, end
;
258 for(tie(i
,end
) = vertices(g
); i
!= end
; ++i
) {
259 out
<< get(vertex_id
, *i
);
260 vpw(out
, *i
); //print vertex attributes
261 out
<< ";" << std::endl
;
263 typename graph_traits
<Graph
>::edge_iterator ei
, edge_end
;
264 for(tie(ei
, edge_end
) = edges(g
); ei
!= edge_end
; ++ei
) {
265 out
<< get(vertex_id
, source(*ei
, g
)) << Traits::delimiter() << get(vertex_id
, target(*ei
, g
)) << " ";
266 epw(out
, *ei
); //print edge attributes
267 out
<< ";" << std::endl
;
269 out
<< "}" << std::endl
;
272 template <typename Graph
, typename VertexPropertiesWriter
,
273 typename EdgePropertiesWriter
, typename GraphPropertiesWriter
>
275 write_graphviz(std::ostream
& out
, const Graph
& g
,
276 VertexPropertiesWriter vpw
,
277 EdgePropertiesWriter epw
,
278 GraphPropertiesWriter gpw
279 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
280 { write_graphviz(out
, g
, vpw
, epw
, gpw
, get(vertex_index
, g
)); }
282 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
283 // ambiguous overload problem with VC++
284 template <typename Graph
>
286 write_graphviz(std::ostream
& out
, const Graph
& g
287 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
291 write_graphviz(out
, g
, dw
, dw
, gw
);
295 template <typename Graph
, typename VertexWriter
>
297 write_graphviz(std::ostream
& out
, const Graph
& g
, VertexWriter vw
298 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
302 write_graphviz(out
, g
, vw
, dw
, gw
);
305 template <typename Graph
, typename VertexWriter
, typename EdgeWriter
>
307 write_graphviz(std::ostream
& out
, const Graph
& g
,
308 VertexWriter vw
, EdgeWriter ew
309 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
312 write_graphviz(out
, g
, vw
, ew
, gw
);
317 template <class Graph_
, class RandomAccessIterator
, class VertexID
>
318 void write_graphviz_subgraph (std::ostream
& out
,
319 const subgraph
<Graph_
>& g
,
320 RandomAccessIterator vertex_marker
,
321 RandomAccessIterator edge_marker
,
324 typedef subgraph
<Graph_
> Graph
;
325 typedef typename graph_traits
<Graph
>::vertex_descriptor Vertex
;
326 typedef typename graph_traits
<Graph
>::directed_category cat_type
;
327 typedef graphviz_io_traits
<cat_type
> Traits
;
329 typedef typename graph_property
<Graph
, graph_name_t
>::type NameType
;
330 const NameType
& g_name
= get_property(g
, graph_name
);
333 out
<< Traits::name() ;
337 out
<< " " << g_name
<< " {" << std::endl
;
339 typename
Graph::const_children_iterator i_child
, j_child
;
341 //print graph/node/edge attributes
342 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
343 typedef typename graph_property
<Graph
, graph_graph_attribute_t
>::type
345 typedef typename graph_property
<Graph
, graph_vertex_attribute_t
>::type
347 typedef typename graph_property
<Graph
, graph_edge_attribute_t
>::type
349 GAttrMap gam
= get_property(g
, graph_graph_attribute
);
350 NAttrMap nam
= get_property(g
, graph_vertex_attribute
);
351 EAttrMap eam
= get_property(g
, graph_edge_attribute
);
352 graph_attributes_writer
<GAttrMap
, NAttrMap
, EAttrMap
> writer(gam
, nam
, eam
);
355 make_graph_attributes_writer(g
)(out
);
359 for ( tie(i_child
,j_child
) = g
.children();
360 i_child
!= j_child
; ++i_child
)
361 write_graphviz_subgraph(out
, *i_child
, vertex_marker
, edge_marker
,
364 // Print out vertices and edges not in the subgraphs.
366 typename graph_traits
<Graph
>::vertex_iterator i
, end
;
367 typename graph_traits
<Graph
>::edge_iterator ei
, edge_end
;
369 for(tie(i
,end
) = vertices(g
); i
!= end
; ++i
) {
370 Vertex v
= g
.local_to_global(*i
);
371 int pos
= get(vertex_id
, v
);
372 if ( vertex_marker
[pos
] ) {
373 vertex_marker
[pos
] = false;
375 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
376 typedef typename property_map
<Graph
, vertex_attribute_t
>::const_type
378 attributes_writer
<VertexAttributeMap
> vawriter(get(vertex_attribute
,
382 make_vertex_attributes_writer(g
.root())(out
, v
);
384 out
<< ";" << std::endl
;
388 for (tie(ei
, edge_end
) = edges(g
); ei
!= edge_end
; ++ei
) {
389 Vertex u
= g
.local_to_global(source(*ei
,g
)),
390 v
= g
.local_to_global(target(*ei
, g
));
391 int pos
= get(get(edge_index
, g
.root()), g
.local_to_global(*ei
));
392 if ( edge_marker
[pos
] ) {
393 edge_marker
[pos
] = false;
394 out
<< get(vertex_id
, u
) << " " << Traits::delimiter()
395 << " " << get(vertex_id
, v
);
396 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
397 typedef typename property_map
<Graph
, edge_attribute_t
>::const_type
399 attributes_writer
<EdgeAttributeMap
> eawriter(get(edge_attribute
, g
));
402 make_edge_attributes_writer(g
)(out
, *ei
); //print edge properties
404 out
<< ";" << std::endl
;
407 out
<< "}" << std::endl
;
409 } // namespace detail
411 // requires graph_name graph property
412 template <typename Graph
>
413 void write_graphviz(std::ostream
& out
, const subgraph
<Graph
>& g
) {
414 std::vector
<bool> edge_marker(num_edges(g
), true);
415 std::vector
<bool> vertex_marker(num_vertices(g
), true);
417 detail::write_graphviz_subgraph(out
, g
,
418 vertex_marker
.begin(),
420 get(vertex_index
, g
));
423 template <typename Graph
>
424 void write_graphviz(const std::string
& filename
, const subgraph
<Graph
>& g
) {
425 std::ofstream
out(filename
.c_str());
426 std::vector
<bool> edge_marker(num_edges(g
), true);
427 std::vector
<bool> vertex_marker(num_vertices(g
), true);
429 detail::write_graphviz_subgraph(out
, g
,
430 vertex_marker
.begin(),
432 get(vertex_index
, g
));
435 template <typename Graph
, typename VertexID
>
436 void write_graphviz(std::ostream
& out
, const subgraph
<Graph
>& g
,
439 std::vector
<bool> edge_marker(num_edges(g
), true);
440 std::vector
<bool> vertex_marker(num_vertices(g
), true);
442 detail::write_graphviz_subgraph(out
, g
,
443 vertex_marker
.begin(),
448 template <typename Graph
, typename VertexID
>
449 void write_graphviz(const std::string
& filename
, const subgraph
<Graph
>& g
,
452 std::ofstream
out(filename
.c_str());
453 std::vector
<bool> edge_marker(num_edges(g
), true);
454 std::vector
<bool> vertex_marker(num_vertices(g
), true);
456 detail::write_graphviz_subgraph(out
, g
,
457 vertex_marker
.begin(),
462 typedef std::map
<std::string
, std::string
> GraphvizAttrList
;
464 typedef property
<vertex_attribute_t
, GraphvizAttrList
>
465 GraphvizVertexProperty
;
467 typedef property
<edge_attribute_t
, GraphvizAttrList
,
468 property
<edge_index_t
, int> >
469 GraphvizEdgeProperty
;
471 typedef property
<graph_graph_attribute_t
, GraphvizAttrList
,
472 property
<graph_vertex_attribute_t
, GraphvizAttrList
,
473 property
<graph_edge_attribute_t
, GraphvizAttrList
,
474 property
<graph_name_t
, std::string
> > > >
475 GraphvizGraphProperty
;
477 typedef subgraph
<adjacency_list
<vecS
,
479 GraphvizVertexProperty
,
480 GraphvizEdgeProperty
,
481 GraphvizGraphProperty
> >
484 typedef subgraph
<adjacency_list
<vecS
,
486 GraphvizVertexProperty
,
487 GraphvizEdgeProperty
,
488 GraphvizGraphProperty
> >
492 // These four require linking the BGL-Graphviz library: libbgl-viz.a
493 // from the /src directory.
494 extern void read_graphviz(const std::string
& file
, GraphvizDigraph
& g
);
495 extern void read_graphviz(FILE* file
, GraphvizDigraph
& g
);
497 extern void read_graphviz(const std::string
& file
, GraphvizGraph
& g
);
498 extern void read_graphviz(FILE* file
, GraphvizGraph
& g
);
500 class dynamic_properties_writer
503 dynamic_properties_writer(const dynamic_properties
& dp
) : dp(&dp
) { }
505 template<typename Descriptor
>
506 void operator()(std::ostream
& out
, Descriptor key
) const
509 for (dynamic_properties::const_iterator i
= dp
->begin();
510 i
!= dp
->end(); ++i
) {
511 if (typeid(key
) == i
->second
->key()) {
512 if (first
) out
<< " [";
516 out
<< i
->first
<< "=\"" << i
->second
->get_string(key
) << "\"";
520 if (!first
) out
<< "]";
524 const dynamic_properties
* dp
;
527 class dynamic_vertex_properties_writer
530 dynamic_vertex_properties_writer(const dynamic_properties
& dp
,
531 const std::string
& node_id
)
532 : dp(&dp
), node_id(&node_id
) { }
534 template<typename Descriptor
>
535 void operator()(std::ostream
& out
, Descriptor key
) const
538 for (dynamic_properties::const_iterator i
= dp
->begin();
539 i
!= dp
->end(); ++i
) {
540 if (typeid(key
) == i
->second
->key()
541 && i
->first
!= *node_id
) {
542 if (first
) out
<< " [";
546 out
<< i
->first
<< "=\"" << i
->second
->get_string(key
) << "\"";
550 if (!first
) out
<< "]";
554 const dynamic_properties
* dp
;
555 const std::string
* node_id
;
558 namespace graph
{ namespace detail
{
560 template<typename Vertex
>
561 struct node_id_property_map
563 typedef std::string value_type
;
564 typedef value_type reference
;
565 typedef Vertex key_type
;
566 typedef readable_property_map_tag category
;
568 node_id_property_map() {}
570 node_id_property_map(const dynamic_properties
& dp
,
571 const std::string
& node_id
)
572 : dp(&dp
), node_id(&node_id
) { }
574 const dynamic_properties
* dp
;
575 const std::string
* node_id
;
578 template<typename Vertex
>
580 get(node_id_property_map
<Vertex
> pm
,
581 typename node_id_property_map
<Vertex
>::key_type v
)
582 { return get(*pm
.node_id
, *pm
.dp
, v
); }
584 } } // end namespace graph::detail
586 template<typename Graph
>
588 write_graphviz(std::ostream
& out
, const Graph
& g
,
589 const dynamic_properties
& dp
,
590 const std::string
& node_id
= "node_id"
591 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
593 typedef typename graph_traits
<Graph
>::vertex_descriptor Vertex
;
594 write_graphviz(out
, g
, dp
, node_id
,
595 graph::detail::node_id_property_map
<Vertex
>(dp
, node_id
));
598 template<typename Graph
, typename VertexID
>
600 write_graphviz(std::ostream
& out
, const Graph
& g
,
601 const dynamic_properties
& dp
, const std::string
& node_id
,
603 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph
,vertex_list_graph_tag
))
607 /*vertex_writer=*/dynamic_vertex_properties_writer(dp
, node_id
),
608 /*edge_writer=*/dynamic_properties_writer(dp
),
609 /*graph_writer=*/default_writer(),
613 /////////////////////////////////////////////////////////////////////////////
614 // Graph reader exceptions
615 /////////////////////////////////////////////////////////////////////////////
616 struct graph_exception
: public std::exception
{
617 virtual ~graph_exception() throw() {}
618 virtual const char* what() const throw() = 0;
621 struct bad_parallel_edge
: public graph_exception
{
624 mutable std::string statement
;
625 bad_parallel_edge(const std::string
& i
, const std::string
& j
) :
628 virtual ~bad_parallel_edge() throw() {}
629 const char* what() const throw() {
630 if(statement
.empty())
632 std::string("Failed to add parallel edge: (")
633 + from
+ "," + to
+ ")\n";
635 return statement
.c_str();
639 struct directed_graph_error
: public graph_exception
{
640 virtual ~directed_graph_error() throw() {}
641 virtual const char* what() const throw() {
644 "Tried to read a directed graph into an undirected graph.";
648 struct undirected_graph_error
: public graph_exception
{
649 virtual ~undirected_graph_error() throw() {}
650 virtual const char* what() const throw() {
653 "Tried to read an undirected graph into a directed graph.";
657 namespace detail
{ namespace graph
{
659 typedef std::string id_t
;
662 // edges are not uniquely determined by adjacent nodes
665 explicit edge_t(int i
) : idx_(i
) {}
667 static edge_t
new_edge() {
669 return edge_t(idx
++);
672 bool operator==(const edge_t
& rhs
) const {
673 return idx_
== rhs
.idx_
;
675 bool operator<(const edge_t
& rhs
) const {
676 return idx_
< rhs
.idx_
;
683 virtual ~mutate_graph() {}
684 virtual bool is_directed() const = 0;
685 virtual void do_add_vertex(const node_t
& node
) = 0;
688 do_add_edge(const edge_t
& edge
, const node_t
& source
, const node_t
& target
)
692 set_node_property(const id_t
& key
, const node_t
& node
, const id_t
& value
) = 0;
695 set_edge_property(const id_t
& key
, const edge_t
& edge
, const id_t
& value
) = 0;
697 virtual void // RG: need new second parameter to support BGL subgraphs
698 set_graph_property(const id_t
& key
, const id_t
& value
) = 0;
701 template<typename MutableGraph
>
702 class mutate_graph_impl
: public mutate_graph
704 typedef typename graph_traits
<MutableGraph
>::vertex_descriptor bgl_vertex_t
;
705 typedef typename graph_traits
<MutableGraph
>::edge_descriptor bgl_edge_t
;
708 mutate_graph_impl(MutableGraph
& graph
, dynamic_properties
& dp
,
709 std::string node_id_prop
)
710 : graph_(graph
), dp_(dp
), node_id_prop_(node_id_prop
) { }
712 ~mutate_graph_impl() {}
714 bool is_directed() const
717 boost::is_convertible
<
718 typename
boost::graph_traits
<MutableGraph
>::directed_category
,
719 boost::directed_tag
>::value
;
722 virtual void do_add_vertex(const node_t
& node
)
724 // Add the node to the graph.
725 bgl_vertex_t v
= add_vertex(graph_
);
727 // Set up a mapping from name to BGL vertex.
728 bgl_nodes
.insert(std::make_pair(node
, v
));
730 // node_id_prop_ allows the caller to see the real id names for nodes.
731 put(node_id_prop_
, dp_
, v
, node
);
735 do_add_edge(const edge_t
& edge
, const node_t
& source
, const node_t
& target
)
737 std::pair
<bgl_edge_t
, bool> result
=
738 add_edge(bgl_nodes
[source
], bgl_nodes
[target
], graph_
);
741 // In the case of no parallel edges allowed
742 boost::throw_exception(bad_parallel_edge(source
, target
));
744 bgl_edges
.insert(std::make_pair(edge
, result
.first
));
749 set_node_property(const id_t
& key
, const node_t
& node
, const id_t
& value
)
751 put(key
, dp_
, bgl_nodes
[node
], value
);
755 set_edge_property(const id_t
& key
, const edge_t
& edge
, const id_t
& value
)
757 put(key
, dp_
, bgl_edges
[edge
], value
);
761 set_graph_property(const id_t
& key
, const id_t
& value
)
763 /* RG: pointer to graph prevents copying */
764 put(key
, dp_
, &graph_
, value
);
769 MutableGraph
& graph_
;
770 dynamic_properties
& dp_
;
771 std::string node_id_prop_
;
772 std::map
<node_t
, bgl_vertex_t
> bgl_nodes
;
773 std::map
<edge_t
, bgl_edge_t
> bgl_edges
;
777 bool read_graphviz(std::istream
& in
, mutate_graph
& graph
);
779 } } // end namespace detail::graph
781 // Parse the passed stream as a GraphViz dot file.
782 template <typename MutableGraph
>
783 bool read_graphviz(std::istream
& in
, MutableGraph
& graph
,
784 dynamic_properties
& dp
,
785 std::string
const& node_id
= "node_id")
787 detail::graph::mutate_graph_impl
<MutableGraph
> m_graph(graph
, dp
, node_id
);
788 return detail::graph::read_graphviz(in
, m_graph
);
793 #ifdef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
794 # include <boost/graph/detail/read_graphviz_spirit.hpp>
795 #endif // BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
797 #ifdef BOOST_GRAPH_USE_MPI
798 # include <boost/graph/distributed/graphviz.hpp>
801 #endif // BOOST_GRAPHVIZ_HPP