GraphLibrary  0.0.1
A simple library that implements various graph algorithms.
 All Classes Namespaces Files Functions Variables Typedefs Macros
YAMLReader.hpp
Go to the documentation of this file.
1 #ifndef GL_YAML_READER_HPP
2 #define GL_YAML_READER_HPP
3 
4 #include "../structures/Graph.hpp"
5 #include "../gl_base.hpp"
6 #include <fstream>
7 #include <variant>
8 #include <sstream>
9 
10 namespace gl {
11 namespace io {
12 
16 #define IO_GRAPH (*arg)
17 
23 #define IO_CALL_ON_GRAPH(g, func) std::visit([&](auto arg) { func; }, g)
24 
29 {
30 public:
34  using graph_variant_type = std::variant<graphMdu *, graphMdd *, graphLdu *, graphLdd *,
35  graphMfu *, graphMfd *, graphLfu *, graphLfd *,
36  graphMiu *, graphMid *, graphLiu *, graphLid *>;
44  YAMLReader(const char *filename);
45 
50  void setFilename(const char *filename);
51 
56  graph_variant_type get() { return graph_; }
57 
62  void read();
63 
64 private:
65  std::fstream stream_;
67 };
68 
69 YAMLReader::YAMLReader(const char *filename)
70 {
71  stream_ = std::fstream(filename);
72  graph_ = graph_variant_type(); // set to default
73  GL_ASSERT(stream_.is_open(), "File could not be opened");
74  read();
75 }
76 
77 void YAMLReader::setFilename(const char *filename)
78 {
79  stream_ = std::fstream(filename);
80  GL_ASSERT(stream_.is_open(), "File could not be opened");
81 }
82 
84 {
85 
86  using idx_t = gl::index_type; // use idx_t from a graph
87 
88  struct NodeType
89  {
90  idx_t index;
91  double cap;
92  gl::Color col;
93  std::string label;
94  NodeType(idx_t index, double cap, gl::Color col, std::string label) : index(index),
95  cap(cap),
96  col(col),
97  label(label) {}
98  };
99  struct EdgeType
100  {
101  idx_t from;
102  idx_t to;
103  double weight;
104  gl::Color col;
105  EdgeType(idx_t from, idx_t to, double weight, gl::Color col) : from(from),
106  to(to),
107  weight(weight),
108  col(col) {}
109  };
110  struct PositionType
111  {
112  idx_t id;
113  std::pair<float, float> pos;
114  PositionType(idx_t id, std::pair<float, float> pos) : id(id), pos(pos) {}
115  };
116 
117  // temp variables to store data while reading
118  std::string value_type, storage_type, direction_type, graph_label;
119  idx_t number_of_nodes;
120 
121  std::vector<EdgeType> edges;
122  std::vector<NodeType> nodes;
123  std::vector<PositionType> positions;
124 
125  std::string line;
126  while (getline(stream_, line))
127  {
128  // comments on lines
129  if (line[0] == '#' || line.empty())
130  continue;
131  std::size_t delimiterPos = line.find(":");
132  std::string name = line.substr(0, delimiterPos);
133  std::string value = line.substr(delimiterPos + 1);
134  // trim spaces
135  value.erase(value.begin(), std::find_if(value.begin(), value.end(),
136  std::not1(std::ptr_fun<int, int>(std::isspace))));
137  if (name == "value_type")
138  {
139  value_type = value;
140  }
141  else if (name == "direction_type")
142  {
143  direction_type = value;
144  }
145  else if (name == "storage_type")
146  {
147  storage_type = value;
148  }
149  else if (name == "number_nodes")
150  {
151  number_of_nodes = std::stoi(value);
152  }
153  else if (name == "label")
154  {
155  graph_label = value;
156  }
157  else if (name == "edge")
158  {
159  std::stringstream ss(value);
160  idx_t a, b;
161  double weight = 1;
162  ss >> a >> b;
163  // if ss not empty, read weight
164  if (!ss.eof())
165  {
166  ss >> weight;
167  }
168  gl::Color c(0, 0, 0);
169  unsigned int hex;
170  if (!ss.eof())
171  {
172  ss >> std::hex >> hex;
173  c.hex(hex);
174  }
175  edges.push_back(EdgeType(a, b, weight, c));
176  }
177  else if (name == "node")
178  {
179  idx_t node;
180  double cap = 1.0;
181  std::stringstream ss(value);
182  ss >> node >> cap;
183  gl::Color col(0, 0, 0);
184  if (!ss.eof())
185  {
186  unsigned int hex;
187  ss >> std::hex >> hex;
188  col.hex(hex);
189  }
190  std::string label;
191  getline(ss, label);
192  nodes.push_back(NodeType(node, cap, col, label));
193  }
194  else if (name == "position")
195  {
196  idx_t node;
197  float x, y;
198  std::stringstream ss(value);
199  ss >> node >> x >> y;
200  std::pair<float, float> pos(x, y);
201  positions.push_back(PositionType(node, pos));
202  }
203  else
204  {
205  GL_ASSERT(false, "Unrecognized option: " + line);
206  }
207  }
208 
209  // switch graph_ on current state from reading
210  if (value_type == "double" && storage_type == "Matrix" && direction_type == "Undirected")
211  {
212  graph_ = new graphMdu(number_of_nodes, graph_label);
213  }
214  else if (value_type == "double" && storage_type == "Matrix" && direction_type == "Directed")
215  {
216  graph_ = new graphMdd(number_of_nodes, graph_label);
217  }
218  else if (value_type == "double" && storage_type == "List" && direction_type == "Undirected")
219  {
220  graph_ = new graphLdu(number_of_nodes, graph_label);
221  }
222  else if (value_type == "double" && storage_type == "List" && direction_type == "Directed")
223  {
224  graph_ = new graphLdd(number_of_nodes, graph_label);
225  }
226  else if (value_type == "float" && storage_type == "Matrix" && direction_type == "Undirected")
227  {
228  graph_ = new graphMfu(number_of_nodes, graph_label);
229  }
230  else if (value_type == "float" && storage_type == "Matrix" && direction_type == "Directed")
231  {
232  graph_ = new graphMfd(number_of_nodes, graph_label);
233  }
234  else if (value_type == "float" && storage_type == "List" && direction_type == "Undirected")
235  {
236  graph_ = new graphLfu(number_of_nodes, graph_label);
237  }
238  else if (value_type == "float" && storage_type == "List" && direction_type == "Directed")
239  {
240  graph_ = new graphLfd(number_of_nodes, graph_label);
241  }
242  else if (value_type == "int" && storage_type == "Matrix" && direction_type == "Undirected")
243  {
244  graph_ = new graphMiu(number_of_nodes, graph_label);
245  }
246  else if (value_type == "int" && storage_type == "Matrix" && direction_type == "Directed")
247  {
248  graph_ = new graphMid(number_of_nodes, graph_label);
249  }
250  else if (value_type == "int" && storage_type == "List" && direction_type == "Undirected")
251  {
252  graph_ = new graphLiu(number_of_nodes, graph_label);
253  }
254  else if (value_type == "int" && storage_type == "List" && direction_type == "Directed")
255  {
256  graph_ = new graphLid(number_of_nodes, graph_label);
257  }
258  else
259  {
260  GL_ASSERT(false, "Please enter valid data into config.");
261  }
262 
263  // add all edges to the graph
264  for (EdgeType &e : edges)
265  {
266  IO_CALL_ON_GRAPH(graph_, IO_GRAPH.setEdge(e.from, e.to, e.weight, e.col));
267  }
268  for (NodeType &n : nodes)
269  {
270  IO_CALL_ON_GRAPH(graph_, IO_GRAPH.updateNode(n.index, n.label, n.cap, n.col));
271  }
272  for(PositionType& p : positions) {
273  IO_CALL_ON_GRAPH(graph_, IO_GRAPH.updateNode(p.id, p.pos));
274  }
275 }
276 
277 } // namespace io
278 } // namespace gl
279 
280 #endif // GL_YAML_READER_HPP
void setFilename(const char *filename)
Set the Filename to use.
Definition: YAMLReader.hpp:77
std::variant< graphMdu *, graphMdd *, graphLdu *, graphLdd *, graphMfu *, graphMfd *, graphLfu *, graphLfd *, graphMiu *, graphMid *, graphLiu *, graphLid * > graph_variant_type
All possible variants of graphs.
Definition: YAMLReader.hpp:36
std::fstream stream_
the filestream to use
Definition: YAMLReader.hpp:65
Stores an RGBA Color.
Definition: Color.hpp:21
YAMLReader()
Default constructor.
Definition: YAMLReader.hpp:40
#define IO_GRAPH
Template object to use with IO_CALL_ON_GRAPH.
Definition: YAMLReader.hpp:16
int hex() const
Gets the hexadecimal value of the RGBA color.
Definition: Color.hpp:160
#define IO_CALL_ON_GRAPH(g, func)
Custom function on parsed graphs.
Definition: YAMLReader.hpp:23
#define GL_ASSERT(EXPR, ERROR_MSG)
Custom assert that supports attaching a message.
Definition: gl_assert.hpp:14
Class to Read from a YAML file.
Definition: YAMLReader.hpp:28
std::size_t index_type
Definition: gl_base.hpp:18
void read()
Reads the file, generates graph This is automatically done in YAMLReader(const char *filename) ...
Definition: YAMLReader.hpp:83
graph_variant_type graph_
the graph variant
Definition: YAMLReader.hpp:66