| 1 | #ifndef BOOST_SUPPLEMENT_GRAPH_READ_LGL_HPP_INCLUDED |
|---|
| 2 | #define BOOST_SUPPLEMENT_GRAPH_READ_LGL_HPP_INCLUDED 1 |
|---|
| 3 | |
|---|
| 4 | #include <boost/graph/graph_traits.hpp> |
|---|
| 5 | #include <boost/graph/properties.hpp> |
|---|
| 6 | #include <boost/property_map.hpp> |
|---|
| 7 | #include <boost/tokenizer.hpp> |
|---|
| 8 | |
|---|
| 9 | #include <boost_supplement/graph/detail/line_input_iterator.hpp> |
|---|
| 10 | |
|---|
| 11 | #include <map> |
|---|
| 12 | |
|---|
| 13 | namespace boost_supplement { |
|---|
| 14 | namespace detail { |
|---|
| 15 | |
|---|
| 16 | template<class Graph, class VertexNameMap, class EdgeWeightMap> |
|---|
| 17 | class lgl_reader |
|---|
| 18 | { |
|---|
| 19 | private: |
|---|
| 20 | typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; |
|---|
| 21 | typedef std::map<std::string, Vertex> NameVertexMap; |
|---|
| 22 | typedef boost::tokenizer< boost::char_separator<char> > tokenizer; |
|---|
| 23 | |
|---|
| 24 | const boost::char_separator<char> SEP; |
|---|
| 25 | Graph* m_graph; |
|---|
| 26 | VertexNameMap m_vnm; |
|---|
| 27 | EdgeWeightMap m_ewm; |
|---|
| 28 | NameVertexMap m_nvm; |
|---|
| 29 | std::string m_base; |
|---|
| 30 | |
|---|
| 31 | Vertex name_to_vertex(std::string const& n) |
|---|
| 32 | { |
|---|
| 33 | typename NameVertexMap::iterator i = m_nvm.find(n); |
|---|
| 34 | if (i == m_nvm.end()) { |
|---|
| 35 | Vertex u = add_vertex(*m_graph); |
|---|
| 36 | m_vnm[u] = n; |
|---|
| 37 | m_nvm[n] = u; |
|---|
| 38 | return u; |
|---|
| 39 | } |
|---|
| 40 | return i->second; |
|---|
| 41 | } |
|---|
| 42 | |
|---|
| 43 | void process_line(std::string const& line) |
|---|
| 44 | { |
|---|
| 45 | using namespace std; |
|---|
| 46 | using namespace boost; |
|---|
| 47 | |
|---|
| 48 | tokenizer tokens(line, SEP); |
|---|
| 49 | tokenizer::iterator tok_iter = tokens.begin(); |
|---|
| 50 | |
|---|
| 51 | string tok1(*tok_iter++); |
|---|
| 52 | if ("#" == tok1) { |
|---|
| 53 | if (tok_iter == tokens.end()) { |
|---|
| 54 | // TODO: Syntax error |
|---|
| 55 | return; |
|---|
| 56 | } |
|---|
| 57 | m_base = *tok_iter; |
|---|
| 58 | } |
|---|
| 59 | else { |
|---|
| 60 | Vertex u = name_to_vertex(m_base); |
|---|
| 61 | Vertex v = name_to_vertex(tok1); |
|---|
| 62 | if (tok_iter == tokens.end()) { |
|---|
| 63 | add_edge(u, v, *m_graph); |
|---|
| 64 | } |
|---|
| 65 | else { |
|---|
| 66 | string tok2(*tok_iter); |
|---|
| 67 | double w = atof(tok2.c_str()); |
|---|
| 68 | // if (has_w && w > cutoff) continue; |
|---|
| 69 | add_edge(u, v, *m_graph); |
|---|
| 70 | m_ewm[edge(u, v, *m_graph).first] = w; |
|---|
| 71 | } |
|---|
| 72 | } |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | public: |
|---|
| 76 | lgl_reader(Graph& g, VertexNameMap n, EdgeWeightMap w) |
|---|
| 77 | : SEP(" "), |
|---|
| 78 | m_graph(&g), |
|---|
| 79 | m_vnm(n), |
|---|
| 80 | m_ewm(w), |
|---|
| 81 | m_base("") |
|---|
| 82 | {} |
|---|
| 83 | |
|---|
| 84 | template<class InputStream> |
|---|
| 85 | bool read(InputStream& is) |
|---|
| 86 | { |
|---|
| 87 | m_graph->clear(); |
|---|
| 88 | for (line_input_iterator<InputStream> line_iter(is); |
|---|
| 89 | line_iter != line_input_iterator<InputStream>(); |
|---|
| 90 | ++line_iter) { |
|---|
| 91 | process_line(*line_iter); |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | return true; |
|---|
| 95 | } |
|---|
| 96 | }; |
|---|
| 97 | |
|---|
| 98 | } // detail |
|---|
| 99 | |
|---|
| 100 | template<class InputStream, class Graph, |
|---|
| 101 | class VertexNameMap, class EdgeWeightMap> |
|---|
| 102 | bool read_lgl(InputStream& is, Graph& g, |
|---|
| 103 | VertexNameMap& vnm, EdgeWeightMap& ewm) |
|---|
| 104 | { |
|---|
| 105 | detail::lgl_reader<Graph, VertexNameMap, EdgeWeightMap> |
|---|
| 106 | reader(g, vnm, ewm); |
|---|
| 107 | return reader.read(is); |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | template<class InputStream, class Graph> |
|---|
| 111 | bool read_lgl(InputStream& is, Graph& g) |
|---|
| 112 | { |
|---|
| 113 | using namespace boost; |
|---|
| 114 | typedef typename property_map<Graph, vertex_name_t>::type VNM; |
|---|
| 115 | typedef typename property_map<Graph, edge_weight_t>::type EWM; |
|---|
| 116 | |
|---|
| 117 | VNM n = get(vertex_name, g); |
|---|
| 118 | EWM w = get(edge_weight, g); |
|---|
| 119 | return read_lgl(is, g, n, w); |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | } // boost_supplement |
|---|
| 123 | |
|---|
| 124 | #endif // ifndef BOOST_SUPPLEMENT_GRAPH_READ_LGL_HPP_INCLUDED |
|---|