1 #ifndef DATAIO_CFG_UTILS_HH
2 #define DATAIO_CFG_UTILS_HH
7 #include <boost/core/demangle.hpp>
9 #include <yaml-cpp/yaml.h>
11 #include "../core/exceptions.hh"
12 #include "../core/string.hh"
13 #include "../core/types.hh"
71 template <
class Exc >
75 std::string prefix = {})
78 std::stringstream e_msg;
79 e_msg << prefix <<
" ";
80 e_msg <<
"Got " << boost::core::demangle(
typeid(e).name()) <<
". ";
87 e_msg <<
"The given node was a Zombie! Check that the key you are "
88 "trying to read from actually exists. ";
90 else if (not node.Mark().is_null())
95 e_msg <<
"Check that the corresponding line of the config file "
96 "matches the desired read operation or type conversion. ";
100 e_msg <<
"The content of the node is:" << std::endl << YAML::Dump(node);
103 return YAML::Exception(node.Mark(), e_msg.str());
113 s << YAML::Dump(node);
156 template <
typename ReturnType >
162 return node[key].template as< ReturnType >();
164 catch (YAML::Exception& e)
172 "Could not read key '" + key +
173 "' from given config node!");
175 catch (std::exception& e)
178 std::cerr << boost::core::demangle(
typeid(e).name())
179 <<
" occurred during reading key '" << key
180 <<
"' from config!" << std::endl;
187 throw std::runtime_error(
"Unexpected exception occurred during "
188 "reading key '" + key +
"'' from config!");
193 template <
typename ReturnType >
199 return get_as< ReturnType >(key, node);
221 template <
typename CVecT, DimType dim = 0 >
226 using element_t =
typename CVecT::elem_type;
229 if constexpr (std::is_constructible< CVecT, std::vector< element_t > >())
231 return get_as< std::vector< element_t > >(key, node);
235 static_assert(dim > 0,
236 "Need template argument dim given if target type is not "
237 "constructible from std::vector.");
241 const auto vec = get_as< std::array< element_t, dim > >(key, node);
243 for (
DimType i = 0; i < dim; i++)
256 template < DimType dim >
260 return DataIO::get_as_arma_vec< SpaceVecType< dim >, dim >(key, node);
266 template < DimType dim >
267 MultiIndexType< dim >
270 return DataIO::get_as_arma_vec< MultiIndexType< dim >, dim >(key, node);
282 namespace _internal {
292 template<
class T,
class Keys = std::list<std::
string> >
299 while (key.empty() and not key_sequence.empty()) {
300 key = key_sequence.front();
301 key_sequence.pop_front();
304 throw std::invalid_argument(
305 "During recursive_setitem, failed to retrieve a valid key for "
306 "continuing recursion. Make sure the given key sequence ("
307 +
join(key_sequence,
" -> ") +
") contains no empty elements!"
312 if (key_sequence.empty()) {
352 const std::vector<std::string>& key_sequence)
357 Config rv = YAML::Clone(d);
358 for (
const auto& key : key_sequence ) {
360 rv = get_as<Config>(key, rv);
365 "recursive_getitem failed for key or key sequence '"
366 +
join(key_sequence,
" -> ") +
"'!"
390 const std::string& key_sequence,
391 const std::string& delims =
".")
414 std::list<std::string> key_sequence,
417 if (key_sequence.empty()) {
418 throw std::invalid_argument(
419 "Key sequence for recursive_setitem may not be empty!"
441 const std::string& key_sequence,
443 const std::string& delims =
".")
446 d,
split<std::list<std::string>>(key_sequence, delims), val
For access to a dict-like structure with a bad key.
Definition: exceptions.hh:67
MultiIndexType< dim > get_as_MultiIndex(const std::string &key, const DataIO::Config &node)
Special case of Utopia::get_as to retrieve an entry as MultiIndex.
Definition: cfg_utils.hh:268
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
SpaceVecType< dim > get_as_SpaceVec(const std::string &key, const DataIO::Config &node)
Special case of Utopia::get_as to retrieve an entry as SpaceVec.
Definition: cfg_utils.hh:258
ReturnType get_as(const std::string &key, const DataIO::Config &node)
This function is a wrapper around the yaml-cpp YAML::Node::as function.
Definition: cfg_utils.hh:158
Config __recursive_setitem(Config d, Keys &&key_sequence, const T &val)
Helper function for recursive_setitem.
Definition: cfg_utils.hh:293
Config recursive_getitem(const Config &d, const std::vector< std::string > &key_sequence)
Recursively retrieve an element from the configuration tree.
Definition: cfg_utils.hh:351
YAML::Exception improve_yaml_exception(const Exc &e, const Config &node, std::string prefix={})
Improves yaml-cpp exceptions occurring for a given node.
Definition: cfg_utils.hh:73
void recursive_setitem(Config &d, std::list< std::string > key_sequence, const T val)
Recursively sets an element in a configuration tree.
Definition: cfg_utils.hh:413
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
CVecT get_as_arma_vec(const std::string &key, const DataIO::Config &node)
Retrieve a config entry as Armadillo column vector using get_.
Definition: cfg_utils.hh:223
DataIO::Config Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:80
SeqCont split(const std::string &s, const std::string &delims=" ")
Splits a string and returns a container of string segments.
Definition: string.hh:45
std::string join(const Cont &cont, const std::string &delim=", ")
Joins together the strings in a container.
Definition: string.hh:18
unsigned short DimType
Type for dimensions, i.e. very small unsigned integers.
Definition: types.hh:34