#include <configuration.h>
Interface to the SMASH configuration files.
The configuration is created from a YAML file and then stores a nested map of maps (normally a tree, but YAML allows it to be cyclic - even though we don't want that feature). Since the resource owned by the object is a YAML::Node
that handle memory in a similar way as a pointer does, it is forbidden (nor should it be needed) to copy instances of this class, while moving is fine (see special members documentation for more information).
The typical usage of a Configuration is to create it, consume (i.e. take
) all its values and let it being destructed. Since this is the contact point with SMASH input file, the class is meant to be strict in its usage, so that it is possible to help the inexpert user, who might being using a wrong input file and/or e.g. specify an unused key hoping in an effect that indeed does not occur. Therefore, it is imposed that all keys must be parsed before an instance gets destroyed. If this is not the case, an exception will be thrown.
For the typical usage in SMASH one needs to read the value once. In that case, use the Configuration::take function, for example:
Note the curly braces in the function call. It is a std::initializer_list
of strings. This allows an arbitrary nesting depth via the same function. But as a consequence the keys must all be given as constant strings at compile time.
The opposite operation of take
is the Configuration::set_value method, which has a similar syntax, but needs the new value to be assigned, e.g.
If you need to delegate parsing of a section to some object, you can use the Configuration::extract_sub_configuration method, which is taking a full section and returning a new, distinct Configuration instance.
Last but not least, the Configuration::validate method is used by SMASH to check that all given keys are allowed in the present version of the codebase. This is achieved by querying the "database" InputKeys class.
const Configuration&
being passed to a function). Definition at line 276 of file configuration.h.
Classes | |
struct | FileDoesNotExist |
Thrown if the file does not exist. More... | |
struct | IncorrectTypeInAssignment |
Thrown when the types in the config file and C++ don't match. More... | |
struct | ParseError |
Thrown for YAML parse errors. More... | |
class | Value |
Return type of Configuration::take that automatically determines the target type. More... | |
Public Types | |
enum class | GetEmpty { Yes , No } |
Flag to tune method(s) behavior such that it is descriptive from the caller side. More... | |
enum class | Is { Invalid , Deprecated , Valid } |
Return type of Configuration::validate which conveys more information that simply a two-state boolean variable. More... | |
Public Member Functions | |
Configuration (const std::filesystem::path &path) | |
Read config.yaml from the specified path. More... | |
Configuration (const std::filesystem::path &path, const std::filesystem::path &filename) | |
Read a YAML config file from the specified path. More... | |
Configuration (const char *yaml, const char sflag) | |
Initialize configuration with a YAML formatted string. More... | |
Configuration (const char *yaml) | |
Configuration (const Configuration &)=delete | |
Prevent Configuration objects from being copied. More... | |
Configuration & | operator= (const Configuration &)=delete |
Prevent Configuration objects from being copy-assigned. More... | |
Configuration (Configuration &&) | |
Provide class with move constructor. More... | |
Configuration & | operator= (Configuration &&) |
Provide class with move assignment operator. More... | |
~Configuration () noexcept(false) | |
Destroy the object, optionally throwing if not all keys were taken. More... | |
void | merge_yaml (const std::string &yaml) |
Merge the configuration in yaml into the existing tree. More... | |
std::vector< std::string > | list_upmost_nodes () |
Lists all YAML::Nodes from the configuration setup. More... | |
Value | take (std::initializer_list< const char * > keys) |
The default interface for SMASH to read configuration values. More... | |
template<typename T > | |
T | take (std::initializer_list< const char * > keys, T default_value) |
Value | read (std::initializer_list< const char * > keys) const |
Additional interface for SMASH to read configuration values without removing them. More... | |
template<typename T > | |
T | read (std::initializer_list< const char * > keys, T default_value) |
template<typename T > | |
void | set_value (std::initializer_list< const char * > keys, T &&value) |
Overwrite the value of the specified YAML node. More... | |
void | remove_all_entries_in_section_but_one (const std::string &key, std::initializer_list< const char * > section={}) |
Remove all entries in the given section except for key . More... | |
Configuration | extract_sub_configuration (std::initializer_list< const char * > keys, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No) |
Create a new configuration from a then-removed section of the present object. More... | |
bool | has_value_including_empty (std::initializer_list< const char * > keys) const |
Return whether there is a (maybe empty) value behind the requested keys . More... | |
bool | has_value (std::initializer_list< const char * > keys) const |
Return whether there is a non-empty value behind the requested keys . More... | |
bool | is_empty () const |
std::string | to_string () const |
Return a string of the current YAML tree. More... | |
void | clear () |
Erase the Configuration content. More... | |
Is | validate (bool full_validation=true) const |
Validate content of configuration in terms of YAML keys. More... | |
Static Public Attributes | |
static const char | InitializeFromYAMLString = 'S' |
Flag to mark initialization with a YAML formatted string. More... | |
Private Member Functions | |
Configuration (const YAML::Node &node) | |
Create a subobject that has its root node at the given node. More... | |
YAML::Node | find_node_creating_it_if_not_existing (std::vector< const char * > keys) const |
Descend in and if needed modify the YAML tree from the given node using the provided keys. More... | |
std::optional< YAML::Node > | find_existing_node (std::vector< const char * > keys) const |
Descend in the YAML tree from the given node using the provided keys. More... | |
Private Attributes | |
YAML::Node | root_node_ {YAML::NodeType::Map} |
The general_config.yaml contents - fully parsed. More... | |
int | uncaught_exceptions_ {std::uncaught_exceptions()} |
Counter to be able to optionally throw in destructor. More... | |
|
strong |
Flag to tune method(s) behavior such that it is descriptive from the caller side.
For example, see extract_sub_configuration.
Enumerator | |
---|---|
Yes | |
No |
Definition at line 971 of file configuration.h.
|
strong |
Return type of Configuration::validate which conveys more information that simply a two-state boolean variable.
Enumerator | |
---|---|
Invalid | |
Deprecated | |
Valid |
Definition at line 977 of file configuration.h.
|
explicit |
Read config.yaml from the specified path.
[in] | path | The directory where the SMASH config files are located. |
Definition at line 122 of file configuration.cc.
|
explicit |
Read a YAML config file from the specified path.
[in] | path | The directory where the SMASH config files are located. |
[in] | filename | The filename (without path) of the YAML config file, in case you don't want the default "config.yaml". |
Definition at line 126 of file configuration.cc.
|
inlineexplicit |
Initialize configuration with a YAML formatted string.
This is useful in 3-rd party application where we may not be able or willing to read in external files.
[in] | yaml | YAML formatted configuration data. |
[in] | sflag | control flag InitializeFromYAMLString. |
Definition at line 1004 of file configuration.h.
|
inlineexplicit |
Definition at line 1024 of file configuration.h.
|
delete |
Prevent Configuration objects from being copied.
Underneath, the resource is a YAML::Node
and since this handles memory in a similar way as a pointer would do, copying an object would make several instances point to the same memory and it would make it difficult to use this object correctly. Therefore, copies are not allowed.
smash::Configuration::Configuration | ( | Configuration && | other | ) |
Provide class with move constructor.
In contrast to copying, moving is fine, since this keeps the owner of the resource unique.
Definition at line 152 of file configuration.cc.
|
noexcept |
Destroy the object, optionally throwing if not all keys were taken.
This is a way to enforce that the object has to be consumed (i.e. completely parsed) during its lifetime. Since this object might be destructed during stack unwinding, the destructor has to throw only if it is safe to do so and the uncaught_exceptions_ member is used to properly implement this behavior.
Definition at line 170 of file configuration.cc.
|
inlineprivate |
Create a subobject that has its root node at the given node.
Definition at line 1272 of file configuration.h.
|
delete |
Prevent Configuration objects from being copy-assigned.
See copy constructor Configuration(const Configuration &) for more information.
Configuration & smash::Configuration::operator= | ( | Configuration && | other | ) |
Provide class with move assignment operator.
See move constructor Configuration(Configuration &&) for more information.
Definition at line 159 of file configuration.cc.
void smash::Configuration::merge_yaml | ( | const std::string & | yaml | ) |
Merge the configuration in yaml
into the existing tree.
The function parses the string in yaml
into its internal tree representation. Then it merges the nodes from the new tree into the existing tree. The merge resolves conflicts by taking the value from yaml
.
[in] | yaml | A string with YAML (or JSON) content that is to be merged. |
Definition at line 183 of file configuration.cc.
std::vector< std::string > smash::Configuration::list_upmost_nodes | ( | ) |
Lists all YAML::Nodes from the configuration setup.
Definition at line 197 of file configuration.cc.
Configuration::Value smash::Configuration::take | ( | std::initializer_list< const char * > | keys | ) |
The default interface for SMASH to read configuration values.
The function returns the value at the specified keys
and removes it from the Configuration object. Therefore, a subsequent call to take or has_value with the same keys
returns an undefined value / false
. By removing the value, the Configuration object keeps track which settings were never read.
take
operation and it might be done once for all. However, on one hand it is a natural behaviour to expect and on the other hand this is hardly going to be an application bottle-neck.[in] | keys | You can pass an arbitrary number of keys inside curly braces, following the nesting structure in the config file. For example, given Group: Key: Valuecall string value = config.take({"Group", "Key"});
"Group" also be removed from the configuration, since it remains without any value. |
Definition at line 206 of file configuration.cc.
|
inline |
Definition at line 1129 of file configuration.h.
Configuration::Value smash::Configuration::read | ( | std::initializer_list< const char * > | keys | ) | const |
Additional interface for SMASH to read configuration values without removing them.
The function returns the value at the specified keys
but does not remove it from the Configuration object. Semantically, this means the value was not used.
[in] | keys | You can pass an arbitrary number of keys inside curly braces, following the nesting structure in the config file. |
Definition at line 225 of file configuration.cc.
|
inline |
Definition at line 1154 of file configuration.h.
|
inline |
Overwrite the value of the specified YAML node.
[in] | keys | You can pass an arbitrary number of keys inside curly braces, following the nesting structure in the config file. |
[in] | value | An arbitrary value that yaml-cpp can convert into YAML representation. Any builtin type, strings, maps, and vectors can be used here. |
Definition at line 1171 of file configuration.h.
void smash::Configuration::remove_all_entries_in_section_but_one | ( | const std::string & | key, |
std::initializer_list< const char * > | section = {} |
||
) |
Remove all entries in the given section except for key
.
[in] | key | The key of the map entry to keep. |
[in] | section | You can pass an arbitrary number of keys inside curly braces, following the nesting structure in the config file, in order to specify the section where to delete entries. Omitting the section is equivalent to specifying {} and the top-level section is understood. |
Definition at line 236 of file configuration.cc.
Configuration smash::Configuration::extract_sub_configuration | ( | std::initializer_list< const char * > | keys, |
Configuration::GetEmpty | empty_if_not_existing = Configuration::GetEmpty::No |
||
) |
Create a new configuration from a then-removed section of the present object.
This method is meant to be used to deal with sections only, i.e. it will throw if used to extract a key value that is not a section (namely a map in YAML language). Use take for that purpose, instead.
[in] | keys | You can pass an arbitrary number of keys inside curly braces, following the nesting structure in the config file. |
[in] | empty_if_not_existing | Specify Configuration::GetEmpty::Yes if you want an empty Configuration in case the requested section does not exist. |
std::runtime_error | if the method is used
|
Configuration
containing the chosen section. Definition at line 271 of file configuration.cc.
bool smash::Configuration::has_value_including_empty | ( | std::initializer_list< const char * > | keys | ) | const |
Return whether there is a (maybe empty) value behind the requested keys
.
[in] | keys | List of keys to be checked for |
Definition at line 309 of file configuration.cc.
bool smash::Configuration::has_value | ( | std::initializer_list< const char * > | keys | ) | const |
Return whether there is a non-empty value behind the requested keys
.
[in] | keys | List of keys to be checked for |
Definition at line 315 of file configuration.cc.
|
inline |
true
if the object is empty; false
if at least one key exists. Definition at line 1230 of file configuration.h.
std::string smash::Configuration::to_string | ( | ) | const |
Return a string
of the current YAML tree.
Definition at line 320 of file configuration.cc.
|
inline |
Erase the Configuration content.
This function is useful e.g. in tests to clean up not taken keys that would trigger an exception being thrown at by the destructor.
Definition at line 1243 of file configuration.h.
Configuration::Is smash::Configuration::validate | ( | bool | full_validation = true | ) | const |
Validate content of configuration in terms of YAML keys.
A warning or error message is printed for deprecated or invalid keys, respectively, together with information about SMASH versions, if possible.
false
as soon as an invalid key is found. However, a full validation is more user-friendly, since as much information as possible about the input file is provided.[in] | full_validation | Whether all keys are checked or not. |
Is::Valid
if the object contains valid keys only; Is::Deprecated
if the object is valid but has deprecated key(s); Is::Invalid
if the object contains at least one invalid key. Definition at line 585 of file configuration.cc.
|
private |
Descend in and if needed modify the YAML tree from the given node using the provided keys.
After this call nodes corresponding to the passed keys are guaranteed to exist in the tree.
[in] | keys | Keys that will be possibly added to the YAML tree. |
Definition at line 339 of file configuration.cc.
|
private |
Descend in the YAML tree from the given node using the provided keys.
This function must not use the YAML::Node subscript operator, which is at the very bottom level creating an undefined node in the YAML tree, hence "wasting" some memory. Note that the fact that this method is marked as const does not forbid to use the access operator on root_node_
, because of how the YAML library works. We want the tree to be completely untouched by this method.
[in] | keys | Keys that will be used to descend the YAML tree. |
std::optional<YAML::Node>
containing the node in the tree reached by using the provided keys, if it exists; std::nullopt
otherwise.has_value
and putting there a try-catch block would probably cause a performance cost that can be avoided (exceptions on the exceptional path are expensive). Definition at line 326 of file configuration.cc.
|
static |
Flag to mark initialization with a YAML formatted string.
Definition at line 965 of file configuration.h.
|
private |
The general_config.yaml contents - fully parsed.
Definition at line 1315 of file configuration.h.
|
private |
Counter to be able to optionally throw in destructor.
Definition at line 1318 of file configuration.h.