10 #ifndef SRC_INCLUDE_SMASH_KEY_H_
11 #define SRC_INCLUDE_SMASH_KEY_H_
18 #include <string_view>
59 result.push_back(std::string{rhs});
75 lhs.push_back(std::string{rhs});
76 return std::move(lhs);
100 template <
typename T>
134 template <
typename T>
137 [](
const T&) noexcept {
return true; };
157 template <
typename default_type>
159 static_assert(!std::is_const_v<default_type>);
160 static_assert(!std::is_volatile_v<default_type>);
161 static_assert(!std::is_reference_v<default_type>);
162 static_assert(!std::is_pointer_v<default_type>);
163 static_assert(!std::is_array_v<default_type>);
164 static_assert(!std::is_function_v<default_type>);
165 static_assert(!std::is_member_object_pointer_v<default_type>);
166 static_assert(!std::is_member_function_pointer_v<default_type>);
174 using std::runtime_error::runtime_error;
197 validator_type validator = detail::get_default_validator<default_type>())
215 validator_type validator = detail::get_default_validator<default_type>())
216 :
Key{labels,
Default<default_type>{value}, versions, validator} {}
235 validator_type validator = detail::get_default_validator<default_type>())
236 :
Key{labels,
Default<default_type>{type_of_default}, versions,
260 return default_.is_dependent();
300 bool is_allowed() const noexcept {
return !removed_in_.has_value(); }
316 bool validate(
const default_type& value)
const noexcept {
318 return validator_(value);
320 logg[LogArea::Configuration::id].error(
321 "Validator of key " +
static_cast<std::string
>(*
this) +
322 " threw an exception when validating key value.\nThis should not "
323 "happen. Considering value invalid.");
337 return std::equal(std::begin(labels_), std::end(labels_),
338 std::begin(labels), std::end(labels));
347 explicit operator std::string() const noexcept {
362 std::string
as_yaml([[maybe_unused]] std::optional<default_type> value =
363 std::nullopt)
const noexcept {
364 std::stringstream value_as_string{};
365 if constexpr (is_writable_to_stream_v<std::stringstream, default_type>) {
367 value_as_string << *value;
368 }
else if (default_.type_ == DefaultType::Value) {
369 value_as_string << default_value();
372 return as_yaml(value_as_string.str());
385 std::string
as_yaml(std::string value)
const noexcept {
386 std::stringstream result{};
387 result <<
"{" <<
smash::join(labels_,
": {") <<
": " << value
388 <<
smash::join(std::vector<std::string>(labels_.size(),
"}"),
"");
420 template <
typename T>
433 explicit Default(T in) : value_{std::move(in)} {}
445 if (
type != DefaultType::Dependent) {
446 throw std::logic_error(
"Default constructor used with invalid type!");
457 T
value()
const {
return value_.value(); }
467 return type_ == DefaultType::Dependent;
474 std::optional<T> value_ = std::nullopt;
492 : default_{std::move(value)},
493 labels_{labels.begin(), labels.end()},
494 validator_{std::move(validator)} {
502 switch (
auto it = versions.end(); versions.size()) {
504 removed_in_ = *(--it);
507 deprecated_in_ = *(--it);
510 introduced_in_ = *(--it);
514 "Key constructor needs one, two or three version numbers.");
527 logg[LogArea::Configuration::id].error(
528 "Empty validator used at Key construction time.\nThis should not "
529 "happen. Using default validator instead.");
530 validator_ = detail::get_default_validator<default_type>();
532 if (default_.value_ && validator_(*(default_.value_)) ==
false) {
533 throw std::logic_error(
534 "Key " +
static_cast<std::string
>(*
this) +
535 " has been declared with an invalid default value.");
542 std::optional<Version> deprecated_in_{};
544 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.
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.
Key(const KeyLabels &labels, const KeyMetadata &versions, validator_type validator=detail::get_default_validator< default_type >())
Construct a new Key object without default value.
Version removed_in() const
Get the SMASH version in which the key has been removed.
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.
Key(const KeyLabels &labels, default_type value, const KeyMetadata &versions, validator_type validator=detail::get_default_validator< default_type >())
Construct a new Key object with default value.
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, DefaultType type_of_default, const KeyMetadata &versions, validator_type validator=detail::get_default_validator< default_type >())
Construct a new Key object which is supposed to have a default value, which however depends on other ...
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.
std::vector< std::string > KeyLabels
Descriptive alias for storing key labels, i.e.
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::string quote(const std::string &s)
Add quotes around string.
std::string join(const std::vector< std::string > &v, const std::string &delim)
Join strings using delimiter.
std::initializer_list< std::string_view > KeyMetadata
Descriptive alias for storing keys metadata.
EnergyMomentumTensor operator+(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct addition operator.
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.