Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/graph/graphviz.hpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 24.1 KB
RevLine 
[29]1//=======================================================================
2// Copyright 2001 University of Notre Dame.
3// Copyright 2003 Jeremy Siek
4// Authors: Lie-Quan Lee and Jeremy Siek
5//
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
12
13#include <boost/config.hpp>
14#include <string>
15#include <map>
16#include <iostream>
17#include <fstream>
18#include <stdio.h> // for FILE
19#include <boost/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/dynamic_property_map.hpp>
26
27#ifdef BOOST_HAS_DECLSPEC
28#  if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_GRAPH_DYN_LINK)
29#    ifdef BOOST_GRAPH_SOURCE
30#      define BOOST_GRAPH_DECL __declspec(dllexport)
31#    else
32#      define BOOST_GRAPH_DECL __declspec(dllimport)
33#    endif  // BOOST_GRAPH_SOURCE
34#  endif  // DYN_LINK
35#endif  // BOOST_HAS_DECLSPEC
36
37#ifndef BOOST_GRAPH_DECL
38#  define BOOST_GRAPH_DECL
39#endif
40
41namespace boost {
42
43  template <typename directed_category>
44  struct graphviz_io_traits {
45    static std::string name() {
46      return "digraph";
47    }
48    static std::string delimiter() {
49      return "->";
50    }  };
51
52  template <>
53  struct graphviz_io_traits <undirected_tag> {
54    static std::string name() {
55      return "graph";
56    }
57    static std::string delimiter() {
58      return "--";
59    }
60  };
61
62  struct default_writer {
63    void operator()(std::ostream&) const {
64    }
65    template <class VorE>
66    void operator()(std::ostream&, const VorE&) const {
67    }
68  };
69
70  template <class Name>
71  class label_writer {
72  public:
73    label_writer(Name _name) : name(_name) {}
74    template <class VertexOrEdge>
75    void operator()(std::ostream& out, const VertexOrEdge& v) const {
76      out << "[label=\"" << get(name, v) << "\"]";
77    }
78  private:
79    Name name;
80  };
81  template <class Name>
82  inline label_writer<Name>
83  make_label_writer(Name n) {
84    return label_writer<Name>(n);
85  }
86
87  enum edge_attribute_t        { edge_attribute        = 1111 };
88  enum vertex_attribute_t      { vertex_attribute      = 2222 };
89  enum graph_graph_attribute_t { graph_graph_attribute = 3333 };
90  enum graph_vertex_attribute_t  { graph_vertex_attribute  = 4444 };
91  enum graph_edge_attribute_t  { graph_edge_attribute  = 5555 };
92
93  BOOST_INSTALL_PROPERTY(edge, attribute);
94  BOOST_INSTALL_PROPERTY(vertex, attribute);
95  BOOST_INSTALL_PROPERTY(graph, graph_attribute);
96  BOOST_INSTALL_PROPERTY(graph, vertex_attribute);
97  BOOST_INSTALL_PROPERTY(graph, edge_attribute);
98
99
100  template <class Attribute>
101  inline void write_attributes(const Attribute& attr, std::ostream& out) {
102    typename Attribute::const_iterator i, iend;
103    i    = attr.begin();
104    iend = attr.end();
105
106    while ( i != iend ) {
107      out << i->first << "=\"" << i->second << "\"";
108      ++i;
109      if ( i != iend )
110        out << ", ";
111    }
112  }
113
114  template<typename Attributes>
115  inline void write_all_attributes(Attributes attributes,
116                                   const std::string& name,
117                                   std::ostream& out)
118  {
119    typename Attributes::const_iterator i = attributes.begin(),
120                                        end = attributes.end();
121    if (i != end) {
122      out << name << " [\n";
123      write_attributes(attributes, out);
124      out << "];\n";
125    }
126  }
127
128  inline void write_all_attributes(detail::error_property_not_found,
129                                   const std::string&,
130                                   std::ostream&)
131  {
132    // Do nothing - no attributes exist
133  }
134
135
136
137
138  template <typename GraphGraphAttributes,
139            typename GraphNodeAttributes,
140            typename GraphEdgeAttributes>
141  struct graph_attributes_writer
142  {
143    graph_attributes_writer(GraphGraphAttributes gg,
144                            GraphNodeAttributes gn,
145                            GraphEdgeAttributes ge)
146      : g_attributes(gg), n_attributes(gn), e_attributes(ge) { }
147
148    void operator()(std::ostream& out) const {
149      write_all_attributes(g_attributes, "graph", out);
150      write_all_attributes(n_attributes, "node", out);
151      write_all_attributes(e_attributes, "edge", out);
152    }
153    GraphGraphAttributes g_attributes;
154    GraphNodeAttributes n_attributes;
155    GraphEdgeAttributes e_attributes;
156  };
157
158  template <typename GAttrMap, typename NAttrMap, typename EAttrMap>
159  graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
160  make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr,
161                              const EAttrMap& e_attr) {
162    return graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
163      (g_attr, n_attr, e_attr);
164  }
165
166
167  template <typename Graph>
168  graph_attributes_writer
169    <typename graph_property<Graph, graph_graph_attribute_t>::type,
170     typename graph_property<Graph, graph_vertex_attribute_t>::type,
171     typename graph_property<Graph, graph_edge_attribute_t>::type>
172  make_graph_attributes_writer(const Graph& g)
173  {
174    typedef typename graph_property<Graph, graph_graph_attribute_t>::type
175      GAttrMap;
176    typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
177      NAttrMap;
178    typedef typename graph_property<Graph, graph_edge_attribute_t>::type
179      EAttrMap;
180    GAttrMap gam = get_property(g, graph_graph_attribute);
181    NAttrMap nam = get_property(g, graph_vertex_attribute);
182    EAttrMap eam = get_property(g, graph_edge_attribute);
183    graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
184    return writer;
185  }
186
187  template <typename AttributeMap>
188  struct attributes_writer {
189    attributes_writer(AttributeMap attr)
190      : attributes(attr) { }
191
192    template <class VorE>
193    void operator()(std::ostream& out, const VorE& e) const {
194      this->write_attribute(out, attributes[e]);
195    }
196
197    private:
198      template<typename AttributeSequence>
199      void write_attribute(std::ostream& out,
200                           const AttributeSequence& seq) const
201      {
202        if (!seq.empty()) {
203          out << "[";
204          write_attributes(seq, out);
205          out << "]";
206        }
207      }
208
209      void write_attribute(std::ostream&,
210                           detail::error_property_not_found) const
211      {
212      }
213    AttributeMap attributes;
214  };
215
216  template <typename Graph>
217  attributes_writer
218    <typename property_map<Graph, edge_attribute_t>::const_type>
219  make_edge_attributes_writer(const Graph& g)
220  {
221    typedef typename property_map<Graph, edge_attribute_t>::const_type
222      EdgeAttributeMap;
223    return attributes_writer<EdgeAttributeMap>(get(edge_attribute, g));
224  }
225
226  template <typename Graph>
227  attributes_writer
228    <typename property_map<Graph, vertex_attribute_t>::const_type>
229  make_vertex_attributes_writer(const Graph& g)
230  {
231    typedef typename property_map<Graph, vertex_attribute_t>::const_type
232      VertexAttributeMap;
233    return attributes_writer<VertexAttributeMap>(get(vertex_attribute, g));
234  }
235
236  template <typename Graph, typename VertexPropertiesWriter,
237            typename EdgePropertiesWriter, typename GraphPropertiesWriter,
238            typename VertexID>
239  inline void write_graphviz(std::ostream& out, const Graph& g,
240                             VertexPropertiesWriter vpw,
241                             EdgePropertiesWriter epw,
242                             GraphPropertiesWriter gpw,
243                             VertexID vertex_id)
244  {
245    typedef typename graph_traits<Graph>::directed_category cat_type;
246    typedef graphviz_io_traits<cat_type> Traits;
247    std::string name = "G";
248    out << Traits::name() << " " << name << " {" << std::endl;
249
250    gpw(out); //print graph properties
251
252    typename graph_traits<Graph>::vertex_iterator i, end;
253
254    for(tie(i,end) = vertices(g); i != end; ++i) {
255      out << get(vertex_id, *i);
256      vpw(out, *i); //print vertex attributes
257      out << ";" << std::endl;
258    }
259    typename graph_traits<Graph>::edge_iterator ei, edge_end;
260    for(tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
261      out << get(vertex_id, source(*ei, g)) << Traits::delimiter() << get(vertex_id, target(*ei, g)) << " ";
262      epw(out, *ei); //print edge attributes
263      out << ";" << std::endl;
264    }
265    out << "}" << std::endl;
266  }
267
268  template <typename Graph, typename VertexPropertiesWriter,
269            typename EdgePropertiesWriter, typename GraphPropertiesWriter>
270  inline void write_graphviz(std::ostream& out, const Graph& g,
271                             VertexPropertiesWriter vpw,
272                             EdgePropertiesWriter epw,
273                             GraphPropertiesWriter gpw)
274  { write_graphviz(out, g, vpw, epw, gpw, get(vertex_index, g)); }
275
276#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
277  // ambiguous overload problem with VC++
278  template <typename Graph>
279  inline void
280  write_graphviz(std::ostream& out, const Graph& g) {
281    default_writer dw;
282    default_writer gw;
283    write_graphviz(out, g, dw, dw, gw);
284  }
285#endif
286
287  template <typename Graph, typename VertexWriter>
288  inline void
289  write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw) {
290    default_writer dw;
291    default_writer gw;
292    write_graphviz(out, g, vw, dw, gw);
293  }
294
295  template <typename Graph, typename VertexWriter, typename EdgeWriter>
296  inline void
297  write_graphviz(std::ostream& out, const Graph& g,
298                 VertexWriter vw, EdgeWriter ew) {
299    default_writer gw;
300    write_graphviz(out, g, vw, ew, gw);
301  }
302
303  namespace detail {
304
305    template <class Graph_, class RandomAccessIterator, class VertexID>
306    void write_graphviz_subgraph (std::ostream& out,
307                                  const subgraph<Graph_>& g,
308                                  RandomAccessIterator vertex_marker,
309                                  RandomAccessIterator edge_marker,
310                                  VertexID vertex_id)
311    {
312      typedef subgraph<Graph_> Graph;
313      typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
314      typedef typename graph_traits<Graph>::directed_category cat_type;
315      typedef graphviz_io_traits<cat_type> Traits;
316
317      typedef typename graph_property<Graph, graph_name_t>::type NameType;
318      const NameType& g_name = get_property(g, graph_name);
319
320      if ( g.is_root() )
321        out << Traits::name() ;
322      else
323        out << "subgraph";
324
325      out << " " << g_name << " {" << std::endl;
326
327      typename Graph::const_children_iterator i_child, j_child;
328
329      //print graph/node/edge attributes
330#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
331      typedef typename graph_property<Graph, graph_graph_attribute_t>::type
332        GAttrMap;
333      typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
334        NAttrMap;
335      typedef typename graph_property<Graph, graph_edge_attribute_t>::type
336        EAttrMap;
337      GAttrMap gam = get_property(g, graph_graph_attribute);
338      NAttrMap nam = get_property(g, graph_vertex_attribute);
339      EAttrMap eam = get_property(g, graph_edge_attribute);
340      graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
341      writer(out);
342#else
343      make_graph_attributes_writer(g)(out);
344#endif
345
346      //print subgraph
347      for ( tie(i_child,j_child) = g.children();
348            i_child != j_child; ++i_child )
349        write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker,
350                                vertex_id);
351
352      // Print out vertices and edges not in the subgraphs.
353
354      typename graph_traits<Graph>::vertex_iterator i, end;
355      typename graph_traits<Graph>::edge_iterator ei, edge_end;
356
357      for(tie(i,end) = vertices(g); i != end; ++i) {
358        Vertex v = g.local_to_global(*i);
359        int pos = get(vertex_id, v);
360        if ( vertex_marker[pos] ) {
361          vertex_marker[pos] = false;
362          out << pos;
363#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
364          typedef typename property_map<Graph, vertex_attribute_t>::const_type
365            VertexAttributeMap;
366          attributes_writer<VertexAttributeMap> vawriter(get(vertex_attribute,
367                                                             g.root()));
368          vawriter(out, v);
369#else
370          make_vertex_attributes_writer(g.root())(out, v);
371#endif
372          out << ";" << std::endl;
373        }
374      }
375
376      for (tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
377        Vertex u = g.local_to_global(source(*ei,g)),
378          v = g.local_to_global(target(*ei, g));
379        int pos = get(get(edge_index, g.root()), g.local_to_global(*ei));
380        if ( edge_marker[pos] ) {
381          edge_marker[pos] = false;
382          out << get(vertex_id, u) << " " << Traits::delimiter()
383              << " " << get(vertex_id, v);
384#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
385          typedef typename property_map<Graph, edge_attribute_t>::const_type
386            EdgeAttributeMap;
387          attributes_writer<EdgeAttributeMap> eawriter(get(edge_attribute, g));
388          eawriter(out, *ei);
389#else
390          make_edge_attributes_writer(g)(out, *ei); //print edge properties
391#endif
392          out << ";" << std::endl;
393        }
394      }
395      out << "}" << std::endl;
396    }
397  } // namespace detail
398
399  // requires graph_name graph property
400  template <typename Graph>
401  void write_graphviz(std::ostream& out, const subgraph<Graph>& g) {
402    std::vector<bool> edge_marker(num_edges(g), true);
403    std::vector<bool> vertex_marker(num_vertices(g), true);
404
405    detail::write_graphviz_subgraph(out, g,
406                                    vertex_marker.begin(),
407                                    edge_marker.begin(), 
408                                    get(vertex_index, g));
409  }
410
411  template <typename Graph>
412  void write_graphviz(const std::string& filename, const subgraph<Graph>& g) {
413    std::ofstream out(filename.c_str());
414    std::vector<bool> edge_marker(num_edges(g), true);
415    std::vector<bool> vertex_marker(num_vertices(g), true);
416
417    detail::write_graphviz_subgraph(out, g,
418                                    vertex_marker.begin(),
419                                    edge_marker.begin(),
420                                    get(vertex_index, g));
421  }
422
423  template <typename Graph, typename VertexID>
424  void write_graphviz(std::ostream& out, const subgraph<Graph>& g,
425                      VertexID vertex_id) 
426  {
427    std::vector<bool> edge_marker(num_edges(g), true);
428    std::vector<bool> vertex_marker(num_vertices(g), true);
429
430    detail::write_graphviz_subgraph(out, g,
431                                    vertex_marker.begin(),
432                                    edge_marker.begin(), 
433                                    vertex_id);
434  }
435
436  template <typename Graph, typename VertexID>
437  void write_graphviz(const std::string& filename, const subgraph<Graph>& g,
438                      VertexID vertex_id) 
439  {
440    std::ofstream out(filename.c_str());
441    std::vector<bool> edge_marker(num_edges(g), true);
442    std::vector<bool> vertex_marker(num_vertices(g), true);
443
444    detail::write_graphviz_subgraph(out, g,
445                                    vertex_marker.begin(),
446                                    edge_marker.begin(),
447                                    vertex_id);
448  }
449
450  typedef std::map<std::string, std::string> GraphvizAttrList;
451
452  typedef property<vertex_attribute_t, GraphvizAttrList>
453          GraphvizVertexProperty;
454
455  typedef property<edge_attribute_t, GraphvizAttrList,
456                   property<edge_index_t, int> >
457          GraphvizEdgeProperty;
458
459  typedef property<graph_graph_attribute_t, GraphvizAttrList,
460                   property<graph_vertex_attribute_t, GraphvizAttrList,
461                   property<graph_edge_attribute_t, GraphvizAttrList,
462                   property<graph_name_t, std::string> > > >
463          GraphvizGraphProperty;
464
465  typedef subgraph<adjacency_list<vecS,
466                   vecS, directedS,
467                   GraphvizVertexProperty,
468                   GraphvizEdgeProperty,
469                   GraphvizGraphProperty> >
470          GraphvizDigraph;
471
472  typedef subgraph<adjacency_list<vecS,
473                   vecS, undirectedS,
474                   GraphvizVertexProperty,
475                   GraphvizEdgeProperty,
476                   GraphvizGraphProperty> >
477          GraphvizGraph;
478
479
480  // These four require linking the BGL-Graphviz library: libbgl-viz.a
481  // from the /src directory.
482  extern void read_graphviz(const std::string& file, GraphvizDigraph& g);
483  extern void read_graphviz(FILE* file, GraphvizDigraph& g);
484
485  extern void read_graphviz(const std::string& file, GraphvizGraph& g);
486  extern void read_graphviz(FILE* file, GraphvizGraph& g);
487
488  class dynamic_properties_writer
489  {
490  public:
491    dynamic_properties_writer(const dynamic_properties& dp) : dp(&dp) { }
492
493    template<typename Descriptor>
494    void operator()(std::ostream& out, Descriptor key) const
495    {
496      bool first = true;
497      for (dynamic_properties::const_iterator i = dp->begin(); 
498           i != dp->end(); ++i) {
499        if (typeid(key) == i->second->key()) {
500          if (first) out << " [";
501          else out << ", ";
502          first = false;
503
504          out << i->first << "=\"" << i->second->get_string(key) << "\"";
505        }
506      }
507
508      if (!first) out << "]";
509    }
510
511  private:
512    const dynamic_properties* dp;
513  };
514
515  class dynamic_vertex_properties_writer
516  {
517  public:
518    dynamic_vertex_properties_writer(const dynamic_properties& dp,
519                                     const std::string& node_id) 
520      : dp(&dp), node_id(&node_id) { }
521
522    template<typename Descriptor>
523    void operator()(std::ostream& out, Descriptor key) const
524    {
525      bool first = true;
526      for (dynamic_properties::const_iterator i = dp->begin(); 
527           i != dp->end(); ++i) {
528        if (typeid(key) == i->second->key()
529            && i->first != *node_id) {
530          if (first) out << " [";
531          else out << ", ";
532          first = false;
533
534          out << i->first << "=\"" << i->second->get_string(key) << "\"";
535        }
536      }
537
538      if (!first) out << "]";
539    }
540
541  private:
542    const dynamic_properties* dp;
543    const std::string* node_id;
544  };
545
546  namespace graph { namespace detail {
547
548    template<typename Vertex>
549    struct node_id_property_map
550    {
551      typedef std::string value_type;
552      typedef value_type reference;
553      typedef Vertex key_type;
554      typedef readable_property_map_tag category;
555
556      node_id_property_map() {}
557
558      node_id_property_map(const dynamic_properties& dp,
559                           const std::string& node_id)
560        : dp(&dp), node_id(&node_id) { }
561
562      const dynamic_properties* dp;
563      const std::string* node_id;
564    };
565
566    template<typename Vertex>
567    inline std::string
568    get(node_id_property_map<Vertex> pm, 
569        typename node_id_property_map<Vertex>::key_type v)
570    { return get(*pm.node_id, *pm.dp, v); }
571
572  } } // end namespace graph::detail
573
574  template<typename Graph>
575  inline void
576  write_graphviz(std::ostream& out, const Graph& g,
577                 const dynamic_properties& dp, 
578                 const std::string& node_id = "node_id")
579  {
580    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
581    write_graphviz(out, g, dp, node_id,
582                   graph::detail::node_id_property_map<Vertex>(dp, node_id));
583  }
584
585  template<typename Graph, typename VertexID>
586  void
587  write_graphviz(std::ostream& out, const Graph& g,
588                 const dynamic_properties& dp, const std::string& node_id,
589                 VertexID id)
590  {
591    write_graphviz
592      (out, g,
593       /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
594       /*edge_writer=*/dynamic_properties_writer(dp),
595       /*graph_writer=*/default_writer(),
596       id);
597  }
598
599/////////////////////////////////////////////////////////////////////////////
600// Graph reader exceptions
601/////////////////////////////////////////////////////////////////////////////
602struct graph_exception : public std::exception {
603  virtual ~graph_exception() throw() {}
604  virtual const char* what() const throw() = 0;
605};
606
607struct bad_parallel_edge : public graph_exception {
608  std::string from;
609  std::string to;
610  mutable std::string statement;
611  bad_parallel_edge(const std::string& i, const std::string& j) :
612    from(i), to(j) {}
613
614  virtual ~bad_parallel_edge() throw() {}
615  const char* what() const throw() {
616    if(statement.empty())
617      statement =
618        std::string("Failed to add parallel edge: (")
619        + from +  "," + to + ")\n";
620
621    return statement.c_str();
622  }
623};
624
625struct directed_graph_error : public graph_exception {
626  virtual ~directed_graph_error() throw() {}
627  virtual const char* what() const throw() {
628    return
629      "read_graphviz: "
630      "Tried to read a directed graph into an undirected graph.";
631  }
632};
633
634struct undirected_graph_error : public graph_exception {
635  virtual ~undirected_graph_error() throw() {}
636  virtual const char* what() const throw() {
637    return
638      "read_graphviz: "
639      "Tried to read an undirected graph into a directed graph.";
640  }
641};
642
643namespace detail { namespace graph {
644
645typedef std::string id_t;
646typedef id_t node_t;
647
648// edges are not uniquely determined by adjacent nodes
649class edge_t {
650  int idx_;
651  explicit edge_t(int i) : idx_(i) {}
652public:
653  static edge_t new_edge() {
654    static int idx = 0;
655    return edge_t(idx++);
656  };
657 
658  bool operator==(const edge_t& rhs) const {
659    return idx_ == rhs.idx_;
660  }
661  bool operator<(const edge_t& rhs) const {
662    return idx_ < rhs.idx_;
663  }
664};
665
666class mutate_graph
667{
668 public:
669  virtual ~mutate_graph() {}
670  virtual bool is_directed() const = 0;
671  virtual void do_add_vertex(const node_t& node) = 0;
672
673  virtual void 
674  do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
675    = 0;
676
677  virtual void 
678  set_node_property(const id_t& key, const node_t& node, const id_t& value) = 0;
679
680  virtual void 
681  set_edge_property(const id_t& key, const edge_t& edge, const id_t& value) = 0;
682};
683
684template<typename MutableGraph>
685class mutate_graph_impl : public mutate_graph
686{
687  typedef typename graph_traits<MutableGraph>::vertex_descriptor bgl_vertex_t;
688  typedef typename graph_traits<MutableGraph>::edge_descriptor   bgl_edge_t;
689
690 public:
691  mutate_graph_impl(MutableGraph& graph, dynamic_properties& dp,
692                    std::string node_id_prop)
693    : graph_(graph), dp_(dp), node_id_prop_(node_id_prop) { }
694
695  ~mutate_graph_impl() {}
696
697  bool is_directed() const
698  {
699    return 
700      boost::is_convertible<
701        typename boost::graph_traits<MutableGraph>::directed_category,
702        boost::directed_tag>::value;
703  }
704
705  virtual void do_add_vertex(const node_t& node)
706  {
707    // Add the node to the graph.
708    bgl_vertex_t v = add_vertex(graph_);
709
710    // Set up a mapping from name to BGL vertex.
711    bgl_nodes.insert(std::make_pair(node, v));
712   
713    // node_id_prop_ allows the caller to see the real id names for nodes.
714    put(node_id_prop_, dp_, v, node);
715  }
716
717  void 
718  do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
719  {
720    std::pair<bgl_edge_t, bool> result =
721     add_edge(bgl_nodes[source], bgl_nodes[target], graph_);
722   
723    if(!result.second) {
724      // In the case of no parallel edges allowed
725      throw bad_parallel_edge(source, target);
726    } else {
727      bgl_edges.insert(std::make_pair(edge, result.first));
728    }
729  }
730
731  void
732  set_node_property(const id_t& key, const node_t& node, const id_t& value)
733  {
734    put(key, dp_, bgl_nodes[node], value);
735  }
736
737  void
738  set_edge_property(const id_t& key, const edge_t& edge, const id_t& value)
739  {
740    put(key, dp_, bgl_edges[edge], value);
741  }
742
743 protected:
744  MutableGraph& graph_;
745  dynamic_properties& dp_;
746  std::string node_id_prop_;
747  std::map<node_t, bgl_vertex_t> bgl_nodes;
748  std::map<edge_t, bgl_edge_t> bgl_edges;
749};
750
751BOOST_GRAPH_DECL
752bool read_graphviz(std::istream& in, mutate_graph& graph);
753
754} } // end namespace detail::graph
755
756// Parse the passed stream as a GraphViz dot file.
757template <typename MutableGraph>
758bool read_graphviz(std::istream& in, MutableGraph& graph,
759                   dynamic_properties& dp,
760                   std::string const& node_id = "node_id") 
761{
762  detail::graph::mutate_graph_impl<MutableGraph> m_graph(graph, dp, node_id);
763  return detail::graph::read_graphviz(in, m_graph);
764}
765
766} // namespace boost
767
768#ifdef BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
769#  include <boost/graph/detail/read_graphviz_spirit.hpp>
770#endif // BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
771
772#endif // BOOST_GRAPHVIZ_HPP
Note: See TracBrowser for help on using the repository browser.