Ariles
Loading...
Searching...
No Matches
writer.cpp
Go to the documentation of this file.
1/**
2 @file
3 @author Alexander Sherikov
4
5 @copyright 2018-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6 (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7
8 @brief
9*/
10
12
13#include <vector>
14#include <utility>
15#include <set>
16
17#include <boost/lexical_cast.hpp>
18
19
20
21namespace ariles2
22{
23 namespace ns_graphviz
24 {
25 class NodeWrapper : public serialization::Node<std::string>
26 {
27 public:
29
30 public:
31 std::string actual_id_;
32 std::string label_;
33
34
35 public:
36 explicit NodeWrapper(const std::string &node, const Base::Type type = Base::Type::GENERIC)
37 : Base(node, type)
38 {
39 label_ = node;
40 actual_id_ = node;
41 }
42
43 explicit NodeWrapper(
44 const std::string &node,
45 const std::string &label,
46 const Base::Type type = Base::Type::GENERIC)
47 : Base(node, type)
48 {
49 label_ = label;
50 actual_id_ = node;
51 }
52
54 const std::string &node,
55 const std::string &label,
56 const std::size_t index,
57 const std::size_t size)
58 : Base(node, index, size)
59 {
60 label_ = label;
61 actual_id_ = node;
62 }
63 };
64 } // namespace ns_graphviz
65} // namespace ariles2
66
67
68namespace ariles2
69{
70 namespace ns_graphviz
71 {
72 namespace impl
73 {
75 {
76 public:
77 std::set<std::string> all_ids_;
79
80 const std::string separator_ = "_";
81
82
83 public:
84 template <class... t_Args>
85 explicit Visitor(t_Args &&...args) : FileVisitorImplementation(std::forward<t_Args>(args)...)
86 {
87 }
88
89
90 void clear()
91 {
92 all_ids_.clear();
93 node_stack_.clear();
94 }
95
96
98 {
100
101 const std::size_t stack_size = node_stack_.size();
102
103 CPPUT_ASSERT(0 < stack_size, "Internal error: stack must contain at least 2 entries.");
104
105 // node
106 back().actual_id_ = node_options.id_;
107
108 if (all_ids_.insert(back().actual_id_).second)
109 {
110 *output_stream_ << node_options.id_;
111 *output_stream_ << "[";
112 if (not node_options.label_.empty())
113 {
114 *output_stream_ << "label=\"" << node_options.label_ << "\"";
115 }
116 if (not node_options.options_.empty())
117 {
118 *output_stream_ << "," << node_options.options_;
119 }
120 *output_stream_ << "];\n";
121 }
122
123 // connection
124 if (stack_size > 1)
125 {
127 << node_stack_[stack_size - 2].actual_id_ //
128 << "->" //
129 << back().actual_id_ << ";\n";
130 }
131 }
132 };
133 } // namespace impl
134 } // namespace ns_graphviz
135} // namespace ariles2
136
137
138namespace ariles2
139{
140 namespace ns_graphviz
141 {
142 Visitor::Visitor(const std::string &file_name)
143 {
144 makeImplPtr(file_name);
145 }
146
147
148 Visitor::Visitor(std::ostream &output_stream)
149 {
150 makeImplPtr(output_stream);
151 }
152
153
155 {
156 impl_->output_stream_->flush();
157 }
158
159
160 void Visitor::startRoot(const std::string &name, const Parameters &parameters)
161 {
163 impl_->clear();
164 impl_->parameters_ = &parameters;
165 if (name.empty())
166 {
167 impl_->emplace("ariles");
168 }
169 else
170 {
171 impl_->emplace(name);
172 }
173 *impl_->output_stream_ //
174 << "digraph graph_" << impl_->back().node_ //
175 << " {\n" //
176 << parameters.graph_options_; //
177 }
178
179
180 void Visitor::endRoot(const std::string & /*name*/)
181 {
183 *impl_->output_stream_ << "}\n";
184 }
185
186 std::string Visitor::getDefaultNodeId() const
187 {
188 if (impl_->back().isArray())
189 {
190 return (impl_->back().node_ + "_" + boost::lexical_cast<std::string>(impl_->back().index_));
191 }
192 return (impl_->back().node_);
193 }
194
196 {
197 if (impl_->back().isArray())
198 {
199 return (impl_->back().label_ + "_" + boost::lexical_cast<std::string>(impl_->back().index_));
200 }
201 return (impl_->back().label_);
202 }
203
204 void Visitor::startMap(const Parameters &parameters, const Parameters::NodeOptions &node_options)
205 {
207 if (not impl_->parameters_->override_parameters_)
208 {
209 impl_->parameters_ = &parameters;
210 }
211 impl_->writeNodeAndConnection(node_options);
212 }
213
214 void Visitor::startMap(const Parameters &parameters, const std::size_t /*num_entries*/)
215 {
217 if (not impl_->parameters_->override_parameters_)
218 {
219 impl_->parameters_ = &parameters;
220 }
221 impl_->writeNodeAndConnection(
222 impl_->parameters_->getDefaultNodeOptions(getDefaultNodeId(), getDefaultNodeLabel()));
223 }
224
225 void Visitor::startMapEntry(const std::string &name)
226 {
228 if (impl_->back().isArray())
229 {
230 impl_->emplace(
231 impl_->concatWithNode(
232 impl_->separator_,
233 boost::lexical_cast<std::string>(impl_->back().index_),
234 impl_->separator_,
235 name),
236 name);
237 }
238 else
239 {
240 impl_->emplace(impl_->concatWithNode(impl_->separator_, name), name);
241 }
242 }
243
245 {
247 impl_->pop();
248 }
249
250
251 void Visitor::startArray(const std::size_t size, const bool compact)
252 {
254 CPPUT_ASSERT(not impl_->empty(), "Internal error: empty stack.");
255
256 if (size > 0 || not compact)
257 {
258 impl_->writeNodeAndConnection(
259 impl_->parameters_->getDefaultNodeOptions(getDefaultNodeId(), getDefaultNodeLabel()));
260 }
261
262 if (impl_->back().isArray())
263 {
264 const std::string index = boost::lexical_cast<std::string>(impl_->back().index_);
265 impl_->emplace(
266 impl_->concatWithNode(impl_->separator_, index),
267 cpput::concat::simple(impl_->back().label_, impl_->separator_, index),
268 0,
269 size);
270 }
271 else
272 {
273 impl_->emplace(impl_->back().node_, impl_->back().label_, 0, size);
274 }
275 }
276
278 {
279 impl_->shiftArray();
280 }
281
283 {
285 impl_->pop();
286 }
287
288
289#define ARILES2_BASIC_TYPE(type) \
290 void Visitor::writeElement(const type &, const Parameters &) \
291 { \
292 impl_->writeNodeAndConnection( \
293 impl_->parameters_->getDefaultNodeOptions(getDefaultNodeId(), getDefaultNodeLabel())); \
294 }
295
298
299#undef ARILES2_BASIC_TYPE
300 } // namespace ns_graphviz
301} // namespace ariles2
NodeWrapper(const std::string &node, const std::string &label, const std::size_t index, const std::size_t size)
Definition writer.cpp:53
NodeWrapper(const std::string &node, const std::string &label, const Base::Type type=Base::Type::GENERIC)
Definition writer.cpp:43
NodeWrapper(const std::string &node, const Base::Type type=Base::Type::GENERIC)
Definition writer.cpp:36
std::string getDefaultNodeId() const
Definition writer.cpp:186
std::string getDefaultNodeLabel() const
Definition writer.cpp:195
void startRoot(const std::string &name, const Parameters &)
Definition writer.cpp:160
void startMap(const Parameters &, const Parameters::NodeOptions &)
Definition writer.cpp:204
void startMapEntry(const std::string &map_name)
Starts a nested map in the configuration file.
Definition writer.cpp:225
void flush()
Flush the configuration to the output.
Definition writer.cpp:154
void startArray(const std::size_t size, const bool compact=false)
Definition writer.cpp:251
void endRoot(const std::string &name)
Definition writer.cpp:180
std::set< std::string > all_ids_
Definition writer.cpp:77
const Parameters * parameters_
Definition writer.cpp:78
void writeNodeAndConnection(const Parameters::NodeOptions &node_options)
Definition writer.cpp:97
std::ostream * output_stream_
output stream
Definition write.h:380
FileVisitorImplementation(const std::string &file_name)
Definition write.h:384
#define CPPUT_ASSERT(condition,...)
Definition exception.h:32
#define ARILES2_COMPLEX_NUMBER_TYPES_LIST
Definition helpers.h:68
#define ARILES2_BASIC_TYPES_LIST
Definition helpers.h:72
#define CPPUT_MACRO_SUBSTITUTE(macro)
Definition misc.h:21
std::string simple(t_String &&...strings)
Definition concat.h:38
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126