Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
xml_graph.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
43# ifndef XML_GRAPH_H
44# define XML_GRAPH_H
45
46# include <tpl_dynArray.H>
47# include <tpl_graph.H>
48# include <ah-graph-concepts.H>
49# include <tpl_dynMapTree.H>
50# include <ah-errors.H>
51# include <optional>
52# include <type_traits>
53# include <utility>
54
55# include <libxml++/libxml++.h>
56# include <libxml++/parsers/textreader.h>
57# include <libxml++/nodes/node.h>
58# include <libxml++/document.h>
59
60using namespace Aleph;
61
62namespace Aleph
63{
64 struct Attr
65 {
66 std::string name;
67 std::string value;
68 };
69
70 template <class GT>
72 {
73 void operator () (GT &, typename GT::Node *, DynArray <Attr> &)
74 {
75 // Empty
76 }
77 };
78
79 template <class GT>
81 {
82 void operator () (GT &, typename GT::Node *, DynArray <Attr> &)
83 {
84 // Empty
85 }
86 };
87
88 template <class GT>
90 {
91 void operator () (GT &, typename GT::Arc *, DynArray <Attr> &)
92 {
93 // Empty
94 }
95 };
96
97 template <class GT>
99 {
100 void operator () (GT &, typename GT::Arc *, DynArray <Attr> &)
101 {
102 // Empty
103 }
104 };
105
106 /* TODO: still owe an explanation of the details of each of the
107 reader and writer classes
108 */
109
119 template <AlephGraph GT,
124 >
126 {
127 std::string graph_name;
128
129 std::string node_name;
130
131 std::string arc_name;
132
133 // Functors received as rvalues (including the defaults) are owned here, so
134 // the references below never outlive them. Functors received as lvalues
135 // are not copied: the references share them with the caller.
136 std::optional<Node_Reader> own_node_reader;
137 std::optional<Arc_Reader> own_arc_reader;
138 std::optional<Node_Writer> own_node_writer;
139 std::optional<Arc_Writer> own_arc_writer;
140
142
144
146
148
149 GT read_graph(xmlpp::TextReader & reader)
150 {
151 GT g;
153
154 size_t num_nodes = 0;
155
156 while(reader.read())
157 {
158 if (reader.get_name() == node_name)
159 {
160 typename GT::Node * p = g.insert_node();
161 map.insert(num_nodes++, p);
162
163 if (not reader.has_attributes())
164 continue;
165
166 reader.move_to_first_attribute();
167
168 DynArray <Attr> attrs;
169
170 do
171 {
172 Attr & attr = attrs.append();
173 attr.name = reader.get_name();
174 attr.value = reader.get_value();
175 }
176 while (reader.move_to_next_attribute());
177
178 node_reader(g, p, attrs);
179
180 reader.move_to_element();
181 }
182
183 else if (reader.get_name() == arc_name)
184 {
185 assert(reader.has_attributes());
186 reader.move_to_first_attribute();
187 size_t src = std::atol(reader.get_value().c_str());
188 bool test = reader.move_to_next_attribute();
189 assert(test);
190 size_t tgt = std::atol(reader.get_value().c_str());
191 test = reader.move_to_next_attribute();
192
193 typename GT::Arc * a = g.insert_arc(map.find(src), map.find(tgt));
194
195 if (not test)
196 {
197 reader.move_to_element();
198 continue;
199 }
200
201 DynArray <Attr> attrs;
202
203 do
204 {
205 Attr & attr = attrs.append();
206 attr.name = reader.get_name();
207 attr.value = reader.get_value();
208 }
209 while (reader.move_to_next_attribute());
210
211 arc_reader(g, a, attrs);
212
213 reader.move_to_element();
214 }
215 }
216 return g;
217 }
218
219 GT read(const std::string & file_name)
220 {
221 xmlpp::TextReader reader(file_name);
222 return read_graph(reader);
223 }
224
225 void write_graph(GT & g, xmlpp::Document & doc)
226 {
227 xmlpp::Element * element = doc.create_root_node(graph_name);
228
229 xmlpp::Element * nodes = element->add_child("nodes");
230
232
233 size_t i = 0;
234
235 for (typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne(), ++i)
236 {
237 typename GT::Node * p = it.get_curr();
238
239 map.insert(p, i);
240
241 xmlpp::Element * node = nodes->add_child(node_name);
242
243 DynArray <Attr> attrs;
244
245 node_writer(g, p, attrs);
246
247 for (size_t i = 0; i < attrs.size(); ++i)
248 {
249 Attr & attr = attrs.access(i);
250 node->set_attribute(attr.name, attr.value);
251 }
252 }
253
254 xmlpp::Element * arcs = element->add_child("arcs");
255
256 for (typename GT::Arc_Iterator it(g); it.has_curr(); it.next_ne(), ++i)
257 {
258 typename GT::Arc * a = it.get_curr();
259
260 xmlpp::Element * arc = arcs->add_child(arc_name);
261
262 const size_t & src = map.find(g.get_src_node(a));
263 arc->set_attribute("src", std::to_string(src));
264
265 const size_t & tgt = map.find(g.get_tgt_node(a));
266 arc->set_attribute("tgt", std::to_string(tgt));
267
268 DynArray <Attr> attrs;
269
270 arc_writer(g, a, attrs);
271
272 for (size_t i = 0; i < attrs.size(); ++i)
273 {
274 Attr & attr = attrs.access(i);
275 arc->set_attribute(attr.name, attr.value);
276 }
277 }
278 }
279
280 void write(GT & g, const std::string & file_name)
281 {
282 xmlpp::Document doc;
283 write_graph(g, doc);
284 doc.write_to_file_formatted(file_name, "UTF-8");
285 }
286
287 public:
306
332
344 template <class F>
345 static std::optional<F> copy_own(const std::optional<F> & src)
346 {
347 if constexpr (std::is_copy_constructible_v<F>)
348 return src;
349 else
350 {
351 ah_runtime_error_if(src.has_value())
352 << "Xml_Graph: cannot copy a reader/writer that owns a "
353 "non-copy-constructible functor; share it instead "
354 "(construct from an lvalue)";
355 return std::nullopt;
356 }
357 }
358
384
385 const std::string & get_graph_name() const
386 {
387 return graph_name;
388 }
389
390 void set_graph_name(const std::string & _graph_name)
391 {
393 }
394
395 const std::string & get_node_name() const
396 {
397 return node_name;
398 }
399
400 void set_node_name(const std::string & _node_name)
401 {
403 }
404
405 const std::string & get_arc_name() const
406 {
407 return arc_name;
408 }
409
410 void set_arc_name(const std::string & _arc_name)
411 {
413 }
414
415 GT operator () (const std::string & file_name)
416 {
417 return read(file_name);
418 }
419
420 void operator () (GT & g, const std::string & file_name)
421 {
422 write(g, file_name);
423 }
424 };
425} // End namespace Aleph
426
427# endif // XML_GRAPH_H
428
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:271
C++20 concepts for the protocol shared by graph algorithms.
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
int num_nodes
Definition btreepic.C:410
size_t size() const noexcept
Return the current dimension of array.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
T & append()
Allocate a new entry to the end of array.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair.
Data & find(const Key &key)
Find the value associated with key.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:525
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:605
Class that writes and reads a graph (in a very elementary way) as XML.
Definition xml_graph.H:126
void write_graph(GT &g, xmlpp::Document &doc)
Definition xml_graph.H:225
const std::string & get_arc_name() const
Definition xml_graph.H:405
const std::string & get_node_name() const
Definition xml_graph.H:395
std::optional< Arc_Reader > own_arc_reader
Definition xml_graph.H:137
Xml_Graph(Node_Reader &&_node_reader=Node_Reader(), Arc_Reader &&_arc_reader=Arc_Reader(), Node_Writer &&_node_writer=Node_Writer(), Arc_Writer &&_arc_writer=Arc_Writer())
Build a reader/writer that owns its functors.
Definition xml_graph.H:318
Xml_Graph(const Xml_Graph &other)
Copy constructor.
Definition xml_graph.H:370
Xml_Graph(Node_Reader &_node_reader, Arc_Reader &_arc_reader, Node_Writer &_node_writer, Arc_Writer &_arc_writer)
Build a reader/writer that shares the caller's functors.
Definition xml_graph.H:298
Arc_Reader & arc_reader
Definition xml_graph.H:143
std::optional< Arc_Writer > own_arc_writer
Definition xml_graph.H:139
static std::optional< F > copy_own(const std::optional< F > &src)
Copy an other reader/writer whose functor may not be copy-constructible.
Definition xml_graph.H:345
GT read_graph(xmlpp::TextReader &reader)
Definition xml_graph.H:149
Arc_Writer & arc_writer
Definition xml_graph.H:147
const std::string & get_graph_name() const
Definition xml_graph.H:385
void set_graph_name(const std::string &_graph_name)
Definition xml_graph.H:390
void set_node_name(const std::string &_node_name)
Definition xml_graph.H:400
Node_Writer & node_writer
Definition xml_graph.H:145
std::string node_name
Definition xml_graph.H:129
std::string graph_name
Definition xml_graph.H:127
std::string arc_name
Definition xml_graph.H:131
void write(GT &g, const std::string &file_name)
Definition xml_graph.H:280
std::optional< Node_Writer > own_node_writer
Definition xml_graph.H:138
GT read(const std::string &file_name)
Definition xml_graph.H:219
GT operator()(const std::string &file_name)
Definition xml_graph.H:415
void set_arc_name(const std::string &_arc_name)
Definition xml_graph.H:410
std::optional< Node_Reader > own_node_reader
Definition xml_graph.H:136
Node_Reader & node_reader
Definition xml_graph.H:141
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition graph-dry.H:779
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
Definition graph-dry.H:785
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
DynArray< Graph::Arc * > arcs
Definition graphpic.C:408
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
STL namespace.
static char doc[]
Definition ntreepic.C:1832
std::string name
Definition xml_graph.H:66
std::string value
Definition xml_graph.H:67
void operator()(GT &, typename GT::Arc *, DynArray< Attr > &)
Definition xml_graph.H:91
void operator()(GT &, typename GT::Arc *, DynArray< Attr > &)
Definition xml_graph.H:100
void operator()(GT &, typename GT::Node *, DynArray< Attr > &)
Definition xml_graph.H:73
void operator()(GT &, typename GT::Node *, DynArray< Attr > &)
Definition xml_graph.H:82
void test()
Definition test-comb.C:40
Lazy and scalable dynamic array implementation.
Dynamic key-value map based on balanced binary search trees.
Generic graph and digraph implementations.