MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
tomlutils.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef TOMLUTILS_H_
8#define TOMLUTILS_H_
9
10#include <memory>
11#include <utility>
12#include "INCLUDE/maiamacro.h"
13#include "INCLUDE/maiatypes.h"
14#include "enums.h"
15
16// Disable RTTI and exceptions
17#define CPPTOML_NO_RTTI
18#define CPPTOML_NO_EXCEPTIONS
19#include "cpptoml.h"
20
21namespace maia {
22namespace io {
23namespace toml {
24
26template <VariableType e>
27struct Enum2Type;
28template <>
30 using type = MString;
31};
32template <>
33struct Enum2Type<MINT> {
34 using type = MInt;
35};
36template <>
38 using type = MFloat;
39};
40template <>
42 using type = MBool;
43};
44template <class T>
46template <>
48 static const VariableType type = MSTRING;
49 static MString name() { return "string"; }
50};
51template <>
53 static const VariableType type = MINT;
54 static MString name() { return "int"; }
55};
56template <>
58 static const VariableType type = MFLOAT;
59 static MString name() { return "float"; }
60};
61template <>
63 static const VariableType type = MBOOL;
64 static MString name() { return "bool"; }
65};
66
67
69class Property {
70 public:
71 // C'tors
72 Property() = default;
73 Property(MString name_, std::vector<MString> data)
74 : m_name(std::move(name_)), m_type(MSTRING), m_size(data.size()), m_string(std::move(data)) {}
75 Property(MString name_, std::vector<MInt> data)
76 : m_name(std::move(name_)), m_type(MINT), m_size(data.size()), m_int(std::move(data)) {}
77 Property(MString name_, std::vector<MFloat> data)
78 : m_name(std::move(name_)), m_type(MFLOAT), m_size(data.size()), m_float(std::move(data)) {}
79 Property(MString name_, std::vector<MBool> data)
80 : m_name(std::move(name_)), m_type(MBOOL), m_size(data.size()), m_bool(std::move(data)) {}
81
82 // General member functions
83 MString name() const { return m_name; }
84 VariableType type() const { return m_type; }
85 MString type2string() const;
86 MLong size() const { return m_size; }
87 MBool valid() const { return m_size != -1; }
88
89 // Accessors
90 const std::vector<MString>& asString() const {
91 if(type() != MSTRING) {
92 TERMM(1, "bad type");
93 }
94 return m_string;
95 }
96 const std::vector<MInt>& asInt() const {
97 if(type() != MINT) {
98 TERMM(1, "bad type");
99 }
100 return m_int;
101 }
102 const std::vector<MFloat>& asFloat() const {
103 if(type() != MFLOAT) {
104 TERMM(1, "bad type");
105 }
106 return m_float;
107 }
108 const std::vector<MBool>& asBool() const {
109 if(type() != MBOOL) {
110 TERMM(1, "bad type");
111 }
112 return m_bool;
113 }
114
115 private:
119 std::vector<MString> m_string;
120 std::vector<MInt> m_int;
121 std::vector<MFloat> m_float;
122 std::vector<MBool> m_bool;
123};
124
125
127 switch(type()) {
128 case MSTRING:
130 case MINT:
132 case MFLOAT:
134 case MBOOL:
136 default:
137 TERMM(1, "bad value type: " + std::to_string(type()));
138 }
139}
140
142inline VariableType value2type(const std::shared_ptr<cpptoml::base>& value) {
143 if(value->as<std::string>()) {
144 return MSTRING;
145 } else if(value->as<int64_t>()) {
146 return MINT;
147 } else if(value->as<double>()) {
148 return MFLOAT;
149 } else if(value->as<bool>()) {
150 return MBOOL;
151 } else {
152 TERMM(1, "bad value type");
153 }
154}
155
156
158inline Property makeProperty(const MString& name, const std::shared_ptr<cpptoml::base>& item) {
159 if(item->is_value()) {
160 switch(value2type(item)) {
161 case MSTRING: {
162 std::vector<MString> data(1);
163 data[0] = item->as<std::string>()->get();
164 return Property(name, data);
165 }
166 case MINT: {
167 std::vector<MInt> data(1);
168#if defined(MAIA_GCC_COMPILER)
169#pragma GCC diagnostic push
170#pragma GCC diagnostic ignored "-Wnull-dereference"
171#endif
172 data[0] = static_cast<MInt>(item->as<int64_t>()->get());
173#if defined(MAIA_GCC_COMPILER)
174#pragma GCC diagnostic pop
175#endif
176 return Property(name, data);
177 }
178 case MFLOAT: {
179 std::vector<MFloat> data(1);
180 data[0] = item->as<double>()->get();
181 return Property(name, data);
182 }
183 case MBOOL: {
184 std::vector<MBool> data(1);
185 data[0] = item->as<bool>()->get();
186 return Property(name, data);
187 }
188 default:
189 TERMM(1, "bad value type");
190 }
191 } else if(item->is_array() || item->is_table()) {
192 if(item->as_array()->get().empty()) {
193 TERMM(1, "array of size 0 found, cannot detect type");
194 }
195
196 switch(value2type(item->as_array()->at(0))) {
197 case MSTRING: {
198 auto v = *item->as_array()->get_array_of<std::string>();
199 std::vector<MString> data(v.size());
200 copy(v.begin(), v.end(), data.begin());
201 return Property(name, data);
202 }
203 case MINT: {
204 auto v = *item->as_array()->get_array_of<MLong>();
205 std::vector<MInt> data(v.size());
206 copy(v.begin(), v.end(), data.begin());
207 return Property(name, data);
208 }
209 case MFLOAT: {
210 auto v = *item->as_array()->get_array_of<double>();
211 std::vector<MFloat> data(v.size());
212 copy(v.begin(), v.end(), data.begin());
213 return Property(name, data);
214 }
215 case MBOOL: {
216 auto v = *item->as_array()->get_array_of<bool>();
217 std::vector<MBool> data(v.size());
218 copy(v.begin(), v.end(), data.begin());
219 return Property(name, data);
220 }
221 default:
222 TERMM(1, "bad value type");
223 }
224 } else {
225 TERMM(1, "item is not a value or array");
226 }
227}
228
230inline void collectSolverAliases(const std::shared_ptr<cpptoml::table>& tab,
231 std::map<std::string, int>& solverAliases) {
232 // search for key "solverAlias"
233 for(auto&& item : *tab) {
234 auto&& key = item.first;
235 if(key == "solverAlias") {
236 auto&& solverAliasesTable = item.second;
237 // iterate over all items in solverAlias table
238 if(solverAliasesTable->is_table()) {
239 for(auto&& alias : *solverAliasesTable->as_table()) {
240 // check if solverAlias is given as string
241 if(value2type(alias.second) == MSTRING) {
242 // store solver alias in map (solverAlias <string> -> solverid <int> )
243 solverAliases[alias.second->as<std::string>()->get()] = std::stoi(alias.first);
244 } else {
245 TERMM(1, "solverAlias need to be defined as string!");
246 }
247 }
248 } else {
249 TERMM(1, "solverAlias needs to be in table format: solverAlias.solverId = 'alias'!");
250 }
251 }
252 }
253}
254
256inline void collectProperties(const std::shared_ptr<cpptoml::table>& tab,
257 std::vector<std::string>& names,
258 std::vector<Property>& properties,
259 std::map<std::string, int>& solverAliases) {
260 // // TODO labels:IO,toremove remove
261 // for (auto&& item : *tab) {
262 // // Store key, value for convenience
263 // auto&& key = item.first;
264 // auto&& value = item.second;
265 // std::cerr << "key " << key << " value " << value << std::endl;
266 // }
267
268 // Iterate over table
269 for(auto&& item : *tab) {
270 // Store key, value for convenience
271 auto&& key = item.first;
272 auto&& value = item.second;
273 std::stringstream key_ss;
274 key_ss << key;
275
276 if(key_ss.str() == "default") {
277 // if default is the key we just add name to properties
278 properties.emplace_back(makeProperty(names[0], value));
279 } else if(cpptoml::is_number(key_ss.str().c_str()[0]) && !value->is_table()) {
280 std::stringstream k;
281 k << names[0] << "." << (std::atoi(key.c_str()));
282 properties.emplace_back(makeProperty(k.str(), value));
283 } else if(std::find_if(solverAliases.begin(), solverAliases.end(),
284 [&key_ss, &solverAliases](std::pair<const std::string, int>& entry) {
285 return !solverAliases.empty() && (entry.first == key_ss.str());
286 })
287 != solverAliases.end()
288 && !names.empty()) {
289 std::stringstream k;
290 k << names[0] << "." << solverAliases[key_ss.str()];
291 properties.emplace_back(makeProperty(k.str(), value));
292 } else if(value->is_value() || value->is_array()) {
293 // Determine fully qualified name
294 std::stringstream solverId;
295 std::stringstream k;
296 MInt counter = 0;
297 for(auto&& name : names) {
298 solverId << name << ".";
299 counter++;
300 }
301
302 if(solverId.str().empty()) {
303 k << key;
304 } else {
305 MString subString1 = solverId.str().substr(0, solverId.str().size() - 1);
306 MString subString2 = solverId.str().substr(0, solverId.str().find('.'));
307 if(subString2 == "solver" || subString1 == "solver") {
308 if(strstr(key.c_str(), ".") != nullptr) {
309 std::stringstream error;
310 error << "Setting a solverId inside the solver table environment '" << subString1 << "' is prohibited!!! ";
311 TERMM(1, error.str());
312 }
313 switch(counter) {
314 case 1: {
315 k << key;
316 break;
317 }
318 case 2: {
319 const char* du = std::strrchr(subString1.c_str(), '.') + 1;
320 const MInt singleSolverId = std::atoi(du);
321 k << key << "." << singleSolverId;
322 break;
323 }
324 default: {
325 std::stringstream error;
326 error << "Too many nested tables: " << subString1 << " Please use 'solver.solverId' instead!!!";
327 TERMM(1, error.str());
328 }
329 }
330 } else {
331 std::stringstream error;
332 error << "Unknown table type: " << subString2 << " Please use 'solver' instead!!!";
333 TERMM(1, error.str());
334 }
335 }
336
337 // Add info to collected properties
338 properties.emplace_back(makeProperty(k.str(), value));
339 } else if(value->is_table()) {
340 // If value is a table, add key to list of names and descend one recursion level
341 names.push_back(key);
342 collectProperties(value->as_table(), names, properties, solverAliases);
343 names.pop_back();
344 } else {
345 TERMM(1, "only values, arrays, and tables are supported");
346 }
347 }
348}
349
350
352inline void collectProperties(const std::shared_ptr<cpptoml::table>& tab, std::vector<Property>& properties,
353 std::map<std::string, int>& solverAliases) {
354 std::vector<std::string> names;
355 collectProperties(tab, names, properties, solverAliases);
356}
357
359inline void collectProperties(const std::shared_ptr<cpptoml::table>& tab, std::vector<Property>& properties) {
360 std::vector<std::string> names;
361 std::map<std::string, int> aliasesdummy;
362 collectProperties(tab, names, properties, aliasesdummy);
363}
364
365} // namespace toml
366} // namespace io
367} // namespace maia
368
369#endif // ifndef TOMLUTILS_H_
Class that represents a single key-value pair for TOML properties.
Definition: tomlutils.h:69
std::vector< MString > m_string
Definition: tomlutils.h:119
const std::vector< MInt > & asInt() const
Definition: tomlutils.h:96
const std::vector< MBool > & asBool() const
Definition: tomlutils.h:108
const std::vector< MFloat > & asFloat() const
Definition: tomlutils.h:102
Property(MString name_, std::vector< MBool > data)
Definition: tomlutils.h:79
std::vector< MFloat > m_float
Definition: tomlutils.h:121
MBool valid() const
Definition: tomlutils.h:87
std::vector< MBool > m_bool
Definition: tomlutils.h:122
const std::vector< MString > & asString() const
Definition: tomlutils.h:90
MString type2string() const
Definition: tomlutils.h:126
Property(MString name_, std::vector< MFloat > data)
Definition: tomlutils.h:77
VariableType type() const
Definition: tomlutils.h:84
MLong size() const
Definition: tomlutils.h:86
Property(MString name_, std::vector< MInt > data)
Definition: tomlutils.h:75
Property(MString name_, std::vector< MString > data)
Definition: tomlutils.h:73
MString name() const
Definition: tomlutils.h:83
std::vector< MInt > m_int
Definition: tomlutils.h:120
VariableType
Definition: enums.h:269
@ MINT
Definition: enums.h:269
@ MFLOAT
Definition: enums.h:269
@ MBOOL
Definition: enums.h:269
@ MINVALID
Definition: enums.h:269
@ MSTRING
Definition: enums.h:269
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
bool MBool
Definition: maiatypes.h:58
MBool is_number(char c)
Definition: cpptoml.h:1471
VariableType value2type(const std::shared_ptr< cpptoml::base > &value)
Obtain type information from TOML value.
Definition: tomlutils.h:142
void collectProperties(const std::shared_ptr< cpptoml::table > &tab, std::vector< std::string > &names, std::vector< Property > &properties, std::map< std::string, int > &solverAliases)
Recursively traverse TOML table and collect all properties with name, type, and count.
Definition: tomlutils.h:256
void collectSolverAliases(const std::shared_ptr< cpptoml::table > &tab, std::map< std::string, int > &solverAliases)
Non-recursive search for solver aliases.
Definition: tomlutils.h:230
Property makeProperty(const MString &name, const std::shared_ptr< cpptoml::base > &item)
Create property from cpptoml item.
Definition: tomlutils.h:158
Namespace for auxiliary functions/classes.
Type traits for enum type.
Definition: tomlutils.h:27