Ariles
write.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2017-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 
11 #pragma once
12 
13 #include "serialization.h"
14 #include "count.h"
15 #include "count_missing.h"
16 
17 /**
18 @defgroup write Write
19 @ingroup serialization
20 
21 @brief Base for serialization.
22 */
23 
24 namespace ariles2
25 {
26  /// @ingroup write
27  namespace write
28  {
30  {
31  public:
33 
34 
35  public:
36  explicit Parameters(const bool override_parameters = true) : serialization::Parameters(override_parameters)
37  {
38  compact_arrays_ = false;
39  }
40  };
41 
42 
43 
44  template <class t_Derived, class t_Parameters>
45  class VisitorBase : public serialization::Base<t_Derived, t_Parameters>
46  {
47  public:
48  virtual void startRoot(const std::string &name, const t_Parameters & /*param*/)
49  {
51  if (not name.empty())
52  {
53  startMapEntry(name);
54  }
55  }
56  virtual void endRoot(const std::string &name)
57  {
59  if (not name.empty())
60  {
61  endMapEntry();
62  }
63  }
64  /**
65  * @brief Flush the configuration to the output
66  */
67  virtual void flush() = 0;
68 
69 
70  /**
71  * @brief Starts a nested map in the configuration file
72  *
73  * @param[in] param parameters
74  * @param[in] num_entries number of child entries
75  */
76  virtual void startMap(const t_Parameters & /*param*/, const std::size_t /*num_entries*/)
77  {
78  }
79  /**
80  * @brief Starts a nested map in the configuration file
81  *
82  * @param[in] map_name name of the map
83  */
84  virtual void startMapEntry(const std::string &map_name)
85  {
86  CPPUT_UNUSED_ARG(map_name)
87  }
88  virtual void endMapEntry()
89  {
90  }
91  /**
92  * @brief Ends a nested map in the configuration file
93  */
94  virtual void endMap()
95  {
96  }
97 
98 
99  virtual bool startIteratedMap(const std::size_t num_entries, const t_Parameters &param)
100  {
101  startMap(param, num_entries);
102  return (true);
103  }
104  virtual void startIteratedMapElement(const std::string &map_name)
105  {
106  startMapEntry(map_name);
107  }
108  virtual void endIteratedMapElement()
109  {
110  endMapEntry();
111  }
112  virtual void endIteratedMap()
113  {
114  endMap();
115  }
116 
117 
118  virtual void startArray(const std::size_t size, const bool compact = false) = 0;
119  virtual void startArrayElement()
120  {
122  }
123  virtual void endArrayElement()
124  {
126  }
127  virtual void endArray()
128  {
130  }
131 
132 
133  virtual void startVector(const std::size_t size)
134  {
136  this->startArray(size, /*compact*/ true);
137  }
138  virtual void startVectorElement()
139  {
141  this->startArrayElement();
142  }
143  virtual void endVectorElement()
144  {
146  this->endArrayElement();
147  }
148  virtual void endVector()
149  {
151  this->endArray();
152  }
153 
154 
155  virtual void startMatrix(
156  const bool dynamic,
157  const std::size_t cols,
158  const std::size_t rows,
159  const t_Parameters &param)
160  {
162  if (param.flat_matrices_)
163  {
164  if (dynamic or param.explicit_matrix_size_)
165  {
166  this->startMap(param, 3);
167 
168  this->startMapEntry("cols");
169  this->writeElement(cols, param);
170  this->endMapEntry();
171 
172  this->startMapEntry("rows");
173  this->writeElement(rows, param);
174  this->endMapEntry();
175 
176  this->startMapEntry("data");
177  }
178 
179  this->startVector(cols * rows);
180  }
181  else
182  {
183  this->startArray(rows, /*compact=*/true);
184  }
185  }
186  virtual void startMatrixRow(const std::size_t cols, const t_Parameters &param)
187  {
189  if (not param.flat_matrices_)
190  {
191  this->startArrayElement();
192  this->startVector(cols);
193  }
194  }
195  virtual void startMatrixElement()
196  {
198  this->startVectorElement();
199  }
200  virtual void endMatrixElement()
201  {
203  this->endVectorElement();
204  }
205  virtual void endMatrixRow(const t_Parameters &param)
206  {
208  if (not param.flat_matrices_)
209  {
210  this->endVector();
211  this->endArrayElement();
212  }
213  }
214  virtual void endMatrix(const bool dynamic, const t_Parameters &param)
215  {
217  if (param.flat_matrices_)
218  {
219  this->endVector();
220 
221  if (dynamic or param.explicit_matrix_size_)
222  {
223  this->endMapEntry();
224  this->endMap();
225  }
226  }
227  else
228  {
229  this->endArray();
230  }
231  }
232 
233 
234 
235  void startPointer(const bool is_null, const t_Parameters &param)
236  {
237  if (is_null)
238  {
239  this->startMap(param, 1);
240  this->startMapEntry("is_null");
241  this->writeElement(is_null, param);
242  this->endMapEntry();
243  }
244  else
245  {
246  this->startMap(param, 2);
247  this->startMapEntry("is_null");
248  this->writeElement(is_null, param);
249  this->endMapEntry();
250  this->startMapEntry("value");
251  }
252  }
253  void endPointer(const bool is_null)
254  {
255  if (not is_null)
256  {
257  this->endMapEntry();
258  }
259  this->endMap();
260  }
261 
262 
263  template <class t_Scalar>
264  void writeElement(const std::complex<t_Scalar> &entry, const t_Parameters &param)
265  {
266  this->startArray(2, /*compact=*/true);
267  this->startArrayElement();
268  this->writeElement(entry.real(), param);
269  this->endArrayElement();
270  this->startArrayElement();
271  this->writeElement(entry.imag(), param);
272  this->endArrayElement();
273  this->endArray();
274  }
275  virtual void writeElement(const std::complex<float> &entry, const t_Parameters &param)
276  {
277  writeElement<float>(entry, param);
278  }
279  virtual void writeElement(const std::complex<double> &entry, const t_Parameters &param)
280  {
281  writeElement<double>(entry, param);
282  }
283 
284 
285 #define ARILES2_BASIC_TYPE(type) virtual void writeElement(const type &entry, const t_Parameters &param) = 0;
286 
288 
289 #undef ARILES2_BASIC_TYPE
290 
291  template <typename t_Entry>
292  void visit(const t_Entry &entry, const std::string &entry_name, const t_Parameters &param)
293  {
295  this->startRoot(entry_name, param);
296  apply_write(static_cast<t_Derived &>(*this), entry, param);
297  this->endRoot(entry_name);
298  this->flush();
299  }
300 
301  template <typename t_Entry>
302  void visitMapEntry(const t_Entry &entry, const std::string &entry_name, const t_Parameters &param)
303  {
305  CPPUT_TRACE_VALUE(entry_name);
306  CPPUT_TRACE_TYPE(entry);
307 
308  if (param.allow_missing_entries_ and isMissing(entry))
309  {
310  return;
311  }
312 
313  this->startMapEntry(entry_name);
314  apply_write(static_cast<t_Derived &>(*this), entry, param);
315  this->endMapEntry();
316  }
317 
318  template <typename t_Element>
319  void visitArrayElement(const t_Element &element, const t_Parameters &param)
320  {
322  CPPUT_TRACE_TYPE(element);
323 
324  this->startArrayElement();
325  apply_write(static_cast<t_Derived &>(*this), element, param);
326  this->endArrayElement();
327  }
328 
329  template <typename t_Element>
330  void visitVectorElement(const t_Element &element, const t_Parameters &param)
331  {
333 
334  this->startVectorElement();
335  this->writeElement(element, param);
336  this->endVectorElement();
337  }
338 
339  template <typename t_Element>
340  void visitMatrixElement(const t_Element &element, const t_Parameters &param)
341  {
343 
344  this->startMatrixElement();
345  this->writeElement(element, param);
346  this->endMatrixElement();
347  }
348  };
349 
350 
351  class Visitor : public VisitorBase<Visitor, Parameters>
352  {
353  protected:
354  Visitor() = default;
355  ~Visitor() = default;
356 
357  public:
358  template <class t_Entry>
359  void startMap(t_Entry &entry, const Parameters &parameters)
360  {
361  std::size_t map_size = ariles2::apply<ariles2::Count>(entry);
362  if (parameters.allow_missing_entries_)
363  {
364  map_size -= ariles2::apply<ariles2::CountMissing>(entry);
365  }
366  startMap(parameters, map_size);
367  }
368 
370  };
371 
372 
374  {
375  public:
376  /// output file stream
377  std::ofstream config_ofs_;
378 
379  /// output stream
380  std::ostream *output_stream_;
381 
382 
383  protected:
384  explicit FileVisitorImplementation(const std::string &file_name)
385  {
386  openFile(file_name);
388  }
389 
390  explicit FileVisitorImplementation(std::ostream &output_stream)
391  {
392  output_stream_ = &output_stream;
393  }
394 
395  /**
396  * @brief open configuration file
397  *
398  * @param[in] file_name
399  */
400  void openFile(const std::string &file_name)
401  {
402  config_ofs_.open(file_name.c_str());
403 
405  config_ofs_.good(), "Could not open configuration file for writing: ", file_name.c_str());
406  }
407  };
408 
409 
411 
412 
413 #define ARILES2_NAMED_ENTRY_write(v, entry, name) visitor.visitMapEntry(entry, #name, parameters);
414 #define ARILES2_PARENT_write(v, entry)
415 #define ARILES2_VISIT_write \
416  template <class t_Visitor> /* cppcheck-suppress duplInheritedMember */ \
417  void arilesVisit( \
418  t_Visitor &visitor, \
419  const typename t_Visitor::Parameters &parameters, \
420  ARILES2_IS_BASE_ENABLER(ariles2::write::Visitor, t_Visitor)) const \
421  { \
422  CPPUT_TRACE_FUNCTION; \
423  CPPUT_UNUSED_ARG(visitor); \
424  CPPUT_UNUSED_ARG(parameters); \
425  arilesVisitParents(visitor, parameters); \
426  ARILES2_ENTRIES(write) \
427  }
428 
429 #define ARILES2_METHODS_write ARILES2_METHODS(write, ARILES2_EMPTY_MACRO, const)
430 #define ARILES2_BASE_METHODS_write ARILES2_BASE_METHODS(write)
431  } // namespace write
432 
433 
434  /// @ingroup write
436 } // namespace ariles2
std::ostream * output_stream_
output stream
Definition: write.h:380
std::ofstream config_ofs_
output file stream
Definition: write.h:377
FileVisitorImplementation(std::ostream &output_stream)
Definition: write.h:390
FileVisitorImplementation(const std::string &file_name)
Definition: write.h:384
void openFile(const std::string &file_name)
open configuration file
Definition: write.h:400
Parameters(const bool override_parameters=true)
Definition: write.h:36
virtual void writeElement(const std::complex< double > &entry, const t_Parameters &param)
Definition: write.h:279
virtual void startArrayElement()
Definition: write.h:119
void visitMatrixElement(const t_Element &element, const t_Parameters &param)
Definition: write.h:340
virtual void startArray(const std::size_t size, const bool compact=false)=0
virtual void startRoot(const std::string &name, const t_Parameters &)
Definition: write.h:48
virtual void startMatrix(const bool dynamic, const std::size_t cols, const std::size_t rows, const t_Parameters &param)
Definition: write.h:155
virtual void startVectorElement()
Definition: write.h:138
virtual void endArrayElement()
Definition: write.h:123
virtual void endIteratedMapElement()
Definition: write.h:108
virtual void writeElement(const std::complex< float > &entry, const t_Parameters &param)
Definition: write.h:275
virtual void endMap()
Ends a nested map in the configuration file.
Definition: write.h:94
void visitMapEntry(const t_Entry &entry, const std::string &entry_name, const t_Parameters &param)
Definition: write.h:302
virtual void startMatrixRow(const std::size_t cols, const t_Parameters &param)
Definition: write.h:186
virtual void startMatrixElement()
Definition: write.h:195
virtual void flush()=0
Flush the configuration to the output.
virtual void endMatrixElement()
Definition: write.h:200
virtual void endMatrixRow(const t_Parameters &param)
Definition: write.h:205
ARILES2_BASIC_TYPES_LIST void visit(const t_Entry &entry, const std::string &entry_name, const t_Parameters &param)
Definition: write.h:292
void visitArrayElement(const t_Element &element, const t_Parameters &param)
Definition: write.h:319
virtual void startMapEntry(const std::string &map_name)
Starts a nested map in the configuration file.
Definition: write.h:84
virtual void startIteratedMapElement(const std::string &map_name)
Definition: write.h:104
virtual bool startIteratedMap(const std::size_t num_entries, const t_Parameters &param)
Definition: write.h:99
virtual void endMapEntry()
Definition: write.h:88
virtual void endArray()
Definition: write.h:127
void startPointer(const bool is_null, const t_Parameters &param)
Definition: write.h:235
virtual void endRoot(const std::string &name)
Definition: write.h:56
void endPointer(const bool is_null)
Definition: write.h:253
virtual void endMatrix(const bool dynamic, const t_Parameters &param)
Definition: write.h:214
virtual void startVector(const std::size_t size)
Definition: write.h:133
virtual void endIteratedMap()
Definition: write.h:112
virtual void endVectorElement()
Definition: write.h:143
void visitVectorElement(const t_Element &element, const t_Parameters &param)
Definition: write.h:330
virtual void startMap(const t_Parameters &, const std::size_t)
Starts a nested map in the configuration file.
Definition: write.h:76
virtual void endVector()
Definition: write.h:148
void writeElement(const std::complex< t_Scalar > &entry, const t_Parameters &param)
Definition: write.h:264
void startMap(t_Entry &entry, const Parameters &parameters)
Definition: write.h:359
#define CPPUT_PERSISTENT_ASSERT(condition,...)
Definition: exception.h:23
#define ARILES2_BASIC_TYPES_LIST
Definition: helpers.h:72
#define CPPUT_UNUSED_ARG(parameter)
Definition: misc.h:19
void apply_write(t_Visitor &writer, const t_Entry &entry, const typename t_Visitor::Parameters &parameters, ARILES2_IS_BASE_ENABLER(ariles2::write::Base, t_Entry))
Definition: basic.h:82
Definition: basic.h:17
bool isMissing(const ARILES2_POINTER_TYPE< t_Entry > &entry)
#define CPPUT_TRACE_FUNCTION
Definition: trace.h:126
#define CPPUT_TRACE_TYPE(type)
Definition: trace.h:128
#define CPPUT_TRACE_VALUE(value)
Definition: trace.h:127