10 #ifndef SRC_INCLUDE_SMASH_KEY_H_
11 #define SRC_INCLUDE_SMASH_KEY_H_
18 #include <string_view>
102 template <
typename T>
105 [](
const T&) noexcept {
return true; };
125 template <
typename default_type>
127 static_assert(!std::is_const_v<default_type>);
128 static_assert(!std::is_volatile_v<default_type>);
129 static_assert(!std::is_reference_v<default_type>);
130 static_assert(!std::is_pointer_v<default_type>);
131 static_assert(!std::is_array_v<default_type>);
132 static_assert(!std::is_function_v<default_type>);
133 static_assert(!std::is_member_object_pointer_v<default_type>);
134 static_assert(!std::is_member_function_pointer_v<default_type>);
142 using std::runtime_error::runtime_error;
183 :
Key{labels,
Default<default_type>{value}, versions, validator} {}
202 :
Key{labels,
Default<default_type>{type_of_default}, versions,
226 return default_.is_dependent();
266 bool is_allowed() const noexcept {
return !removed_in_.has_value(); }
282 bool validate(
const default_type& value)
const noexcept {
284 return validator_(value);
286 logg[LogArea::Configuration::id].error(
287 "Validator of key " +
static_cast<std::string
>(*
this) +
288 " threw an exception when validating key value.\nThis should not "
289 "happen. Considering value invalid.");
303 return std::equal(std::begin(labels_), std::end(labels_),
304 std::begin(labels), std::end(labels));
313 explicit operator std::string() const noexcept {
328 std::string
as_yaml([[maybe_unused]] std::optional<default_type> value =
329 std::nullopt)
const noexcept {
330 std::stringstream value_as_string{};
331 if constexpr (is_writable_to_stream_v<std::stringstream, default_type>) {
333 value_as_string << *value;
334 }
else if (default_.type_ == DefaultType::Value) {
335 value_as_string << default_value();
338 value_as_string <<
"<not-streamable>";
340 return as_yaml(value_as_string.str());
353 std::string
as_yaml(std::string value)
const noexcept {
354 std::stringstream result{};
355 result <<
"{" <<
smash::join(labels_,
": {") <<
": " << value
356 <<
smash::join(std::vector<std::string>(labels_.size(),
"}"),
"");
388 template <
typename T>
401 explicit Default(T in) : value_{std::move(in)} {}
413 if (
type != DefaultType::Dependent) {
414 throw std::logic_error(
"Default constructor used with invalid type!");
425 T
value()
const {
return value_.value(); }
435 return type_ == DefaultType::Dependent;
442 std::optional<T> value_ = std::nullopt;
460 : default_{std::move(value)},
461 labels_{labels.begin(), labels.end()},
462 validator_{std::move(validator)} {
470 switch (
auto it = versions.end(); versions.size()) {
472 removed_in_ = *(--it);
475 deprecated_in_ = *(--it);
478 introduced_in_ = *(--it);
482 "Key constructor needs one, two or three version numbers.");
495 logg[LogArea::Configuration::id].error(
496 "Empty validator used at Key construction time.\nThis should not "
497 "happen. Using default validator instead.");
498 validator_ = detail::get_default_validator<default_type>();
500 if (default_.value_ && validator_(*(default_.value_)) ==
false) {
501 throw std::logic_error(
502 "Key " +
static_cast<std::string
>(*
this) +
503 " has been declared with an invalid default value.");
510 std::optional<Version> deprecated_in_{};
512 std::optional<Version> removed_in_{};
Wrapper class around a type with the capability to both store the type of default and its value,...
T value() const
Retrieve the default value stored in the object.
Default(T in)
Construct a new Default object storing its default value.
Default()
Construct a new Default object which denotes a mandatory value without a default.
Default(DefaultType type)
Construct a new Default object which has a value dependent on external information.
bool is_dependent() const noexcept
Ask whether the default value depends on other external information.
Object to store a YAML input file key together with metadata associated to it.
bool has_dependent_default() const noexcept
Ask whether the default value depends on other other keys.
bool is_allowed() const noexcept
Get whether the key is still allowed or not.
Key(const KeyLabels &labels, DefaultType type_of_default, const KeyMetadata &versions, validator_type validator)
Construct a new Key object which is supposed to have a default value, which however depends on other ...
bool has_same_labels(const KeyLabels &labels) const noexcept
Check if given labels are the same as those of this object.
std::string as_yaml(std::string value) const noexcept
Overload of the method taking a string as value.
Version deprecated_in() const
Get the SMASH version in which the key has been deprecated.
bool validate(const default_type &value) const noexcept
Get whether the given key value is valid.
Key(const KeyLabels &labels, Default< default_type > value, const KeyMetadata &versions, validator_type validator)
Private constructor of the Key object.
Version removed_in() const
Get the SMASH version in which the key has been removed.
Key(const KeyLabels &labels, const KeyMetadata &versions, validator_type validator)
Construct a new Key object without default value.
bool is_deprecated() const noexcept
Get whether the key is deprecated or not.
default_type default_value() const
Get the default value of the key.
const KeyLabels & labels() const
Method to access the Key labels.
std::string as_yaml([[maybe_unused]] std::optional< default_type > value=std::nullopt) const noexcept
Build and return a YAML-formatted string in the compact form (using braces as single line).
default_type type
Let the clients of this class have access to the key type.
Key(const KeyLabels &labels, default_type value, const KeyMetadata &versions, validator_type validator)
Construct a new Key object with default value.
typename detail::KeyTraits< default_type >::validator_type validator_type
Version introduced_in() const noexcept
Get the SMASH version in which the key has been introduced.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
const KeyTraits< T >::validator_type & get_default_validator() noexcept
Function template to get a default trivial validator.
DefaultType
New type to explicit distinguish between mandatory and optional keys.
@ Dependent
Default value which depends on other keys
@ Value
Normal default with a value associated to it.
@ Null
Default "type" for mandatory keys
std::vector< std::string_view > KeyLabels
Descriptive alias for storing key labels, i.e.
std::string quote(const std::string &s)
Add quotes around string.
std::initializer_list< std::string_view > KeyMetadata
Descriptive alias for storing keys metadata.
std::string join(const std::vector< std::string > &v, std::string_view delim)
Join strings using delimiter.
std::string Version
Descriptive alias for storing a SMASH version associated to keys metadata.
Thrown when too few or too many versions are passed to the constructor.
Class template to store Key traits outside the Key class, allowing for reuse both in the Key class it...
std::function< bool(const T &)> validator_type
Descriptive alias for the key validator.