Ariles
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 
11 #include <boost/math/special_functions.hpp>
13 #include <yaml-cpp/yaml.h>
14 
15 
16 namespace ariles2
17 {
18  namespace ns_yaml_cpp
19  {
20  namespace impl
21  {
23  {
24  public:
25  using EmitterPtr = std::shared_ptr<YAML::Emitter>;
26 
27 
28  public:
29  /// instance of YAML emitter, is destroyed and reinitialized by flush()
31 
32  std::size_t map_depth_;
34 
35 
36  public:
37  void initEmitter()
38  {
40  emitter_ = std::make_shared<YAML::Emitter>();
41  emitter_->SetDoublePrecision(std::numeric_limits<double>::digits10);
42  if (output_stream_->tellp() != 0)
43  {
44  *emitter_ << YAML::Newline;
45  }
46  *emitter_ << YAML::BeginMap;
47  map_depth_ = 0;
48  skip_root_map_ = false;
49  }
50 
51 
53  {
55  *emitter_ << YAML::EndMap;
56  *output_stream_ << emitter_->c_str();
57  emitter_.reset();
58  }
59 
60  public:
61  template <class... t_Args>
62  explicit Writer(t_Args &&...args) : FileVisitorImplementation(std::forward<t_Args>(args)...)
63  {
64  initEmitter();
65  }
66 
67 
68  void flush()
69  {
71  *output_stream_ << "\n";
72  output_stream_->flush();
73  initEmitter();
74  }
75  };
76  } // namespace impl
77  } // namespace ns_yaml_cpp
78 } // namespace ariles2
79 
80 
81 namespace ariles2
82 {
83  namespace ns_yaml_cpp
84  {
85  Writer::Writer(const std::string &file_name)
86  {
87  makeImplPtr(file_name);
88  }
89 
90 
91  Writer::Writer(std::ostream &output_stream)
92  {
93  makeImplPtr(output_stream);
94  }
95 
96 
97 
98  void Writer::startMap(const Parameters &, const std::size_t /*num_entries*/)
99  {
101  if (impl_->map_depth_ > 0 or not impl_->skip_root_map_)
102  {
103  *impl_->emitter_ << YAML::BeginMap;
104  }
105  ++impl_->map_depth_;
106  }
107 
108  void Writer::startMapEntry(const std::string &map_name)
109  {
111  CPPUT_TRACE_VALUE(map_name);
112  *impl_->emitter_ << YAML::Key << map_name;
113  *impl_->emitter_ << YAML::Value;
114  }
115 
117  {
119  CPPUT_ASSERT(impl_->map_depth_ > 0, "Internal logic error.");
120  --impl_->map_depth_;
121  if (impl_->map_depth_ > 0 or not impl_->skip_root_map_)
122  {
123  *impl_->emitter_ << YAML::EndMap;
124  }
125  }
126 
127 
129  {
131  impl_->flush();
132  }
133 
134 
135  void Writer::startArray(const std::size_t /*size*/, const bool compact)
136  {
138  if (compact)
139  {
140  *impl_->emitter_ << YAML::Flow;
141  }
142  *impl_->emitter_ << YAML::BeginSeq;
143  }
144 
145 
147  {
149  *impl_->emitter_ << YAML::EndSeq;
150  }
151 
152 
153  void Writer::startRoot(const std::string &name, const Parameters &)
154  {
156  CPPUT_TRACE_VALUE(name);
157  if (name.empty())
158  {
159  impl_->skip_root_map_ = true;
160  }
161  else
162  {
163  startMapEntry(name);
164  }
165  }
166 
167  void Writer::endRoot(const std::string &name)
168  {
170  if (not name.empty())
171  {
172  endMapEntry();
173  }
174  impl_->skip_root_map_ = false;
175  }
176 
177 
178 #define ARILES2_BASIC_TYPE(type) \
179  void Writer::writeElement(const type &element, const Parameters &) \
180  { \
181  *impl_->emitter_ << element; \
182  }
183 
185 
186 #undef ARILES2_BASIC_TYPE
187 
188 
189 #define ARILES2_BASIC_TYPE(type) \
190  void Writer::writeElement(const type &element, const Parameters &) \
191  { \
192  if (boost::math::isnan(element)) \
193  { \
194  *impl_->emitter_ << ".nan"; \
195  } \
196  else \
197  { \
198  if (boost::math::isinf(element)) \
199  { \
200  if (element < 0.0) \
201  { \
202  *impl_->emitter_ << "-.inf"; \
203  } \
204  else \
205  { \
206  *impl_->emitter_ << ".inf"; \
207  } \
208  } \
209  else \
210  { \
211  *impl_->emitter_ << static_cast<double>(element); \
212  } \
213  } \
214  }
215 
217 
218 #undef ARILES2_BASIC_TYPE
219 
220 
221 
222  void Writer::writeElement(const std::string &element, const Parameters &)
223  {
224  *impl_->emitter_ << element;
225  }
226 
227  void Writer::writeElement(const bool &element, const Parameters &)
228  {
229  *impl_->emitter_ << element;
230  }
231  } // namespace ns_yaml_cpp
232 } // namespace ariles2
void flush()
Flush the configuration to the output.
Definition: writer.cpp:128
void endRoot(const std::string &name)
Definition: writer.cpp:167
void startMap(const Parameters &, const std::size_t)
Starts a nested map in the configuration file.
Definition: writer.cpp:98
Writer(const std::string &file_name)
Definition: writer.cpp:85
void startRoot(const std::string &name, const Parameters &)
Definition: writer.cpp:153
void startMapEntry(const std::string &map_name)
Starts a nested map in the configuration file.
Definition: writer.cpp:108
void startArray(const std::size_t, const bool compact=false)
Definition: writer.cpp:135
void endMap()
Ends a nested map in the configuration file.
Definition: writer.cpp:116
std::shared_ptr< YAML::Emitter > EmitterPtr
Definition: writer.cpp:25
EmitterPtr emitter_
instance of YAML emitter, is destroyed and reinitialized by flush()
Definition: writer.cpp:30
std::ostream * output_stream_
output stream
Definition: write.h:380
FileVisitorImplementation(const std::string &file_name)
Definition: write.h:384
void writeElement(const std::complex< t_Scalar > &entry, const Parameters &param)
Definition: write.h:264
#define CPPUT_ASSERT(condition,...)
Definition: exception.h:32
#define ARILES2_BASIC_REAL_TYPES_LIST
Definition: helpers.h:59
#define ARILES2_BASIC_INTEGER_TYPES_LIST
Definition: helpers.h:55
visitor::Parameters Parameters
Definition: count.h:26
CPPUT_MACRO_SUBSTITUTE(ARILES2_BASIC_INTEGER_TYPES_LIST) CPPUT_MACRO_SUBSTITUTE(ARILES2_BASIC_REAL_TYPES_LIST) void Writer
Definition: writer.cpp:184
Definition: basic.h:17
#define CPPUT_TRACE_FUNCTION
Definition: trace.h:126
#define CPPUT_TRACE_VALUE(value)
Definition: trace.h:127