1#ifndef PLUGINS_OPTIONS_H
2#define PLUGINS_OPTIONS_H
4#include "downward/utils/logging.h"
5#include "downward/utils/system.h"
10#include <unordered_map>
13namespace downward::cli::plugins {
28template <
typename ValueType,
typename =
void>
29struct OptionsAnyCaster {
30 static ValueType cast(
const std::any& operand)
32 return std::any_cast<ValueType>(operand);
36template <
typename ValueType>
37struct OptionsAnyCaster<
39 typename
std::enable_if<std::is_enum<ValueType>::value>::type> {
40 static ValueType cast(
const std::any& operand)
44 if (operand.type() ==
typeid(ValueType)) {
45 return std::any_cast<ValueType>(operand);
48 return static_cast<ValueType
>(std::any_cast<int>(operand));
53struct OptionsAnyCaster<
std::vector<T>> {
54 static std::vector<T> cast(
const std::any& operand)
56 if (operand.type() ==
typeid(std::vector<T>)) {
57 return std::any_cast<std::vector<T>>(operand);
60 const std::vector<std::any> any_elements =
61 std::any_cast<std::vector<std::any>>(operand);
62 std::vector<T> result;
63 result.reserve(any_elements.size());
64 for (
const std::any& element : any_elements) {
65 result.push_back(OptionsAnyCaster<T>::cast(element));
73 std::unordered_map<std::string, std::any> storage;
74 std::string unparsed_config;
84 Options(
const Options& other) =
default;
87 void set(
const std::string& key, T value)
93 T get(
const std::string& key)
const
95 const auto it = storage.find(key);
96 if (it == storage.end()) {
98 "Attempt to retrieve nonexisting object of name " + key +
99 " (type: " +
typeid(T).name() +
")");
102 T result = OptionsAnyCaster<T, void>::cast(it->second);
104 }
catch (
const std::bad_any_cast&) {
106 "Invalid conversion while retrieving config options!\n" + key +
107 " is not of type " +
typeid(T).name() +
" but of type " +
108 it->second.type().name());
112 template <
typename T>
113 T get(
const std::string& key,
const T& default_value)
const
115 if (storage.count(key))
118 return default_value;
121 template <
typename T>
122 std::vector<T> get_list(
const std::string& key)
const
124 return get<std::vector<T>>(key);
127 bool contains(
const std::string& key)
const;
128 const std::string& get_unparsed_config()
const;
129 void set_unparsed_config(
const std::string& config);
133void verify_list_non_empty(
134 const ::utils::Context& context,
135 const plugins::Options& opts,
136 const std::string& key)
138 std::vector<T> list = opts.get_list<T>(key);
140 context.error(
"List argument '" + key +
"' has to be non-empty.");