1 /* Copyright (c) 2016-2018. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
14 #include <initializer_list>
17 #include <type_traits>
21 #include <xbt/config.h>
26 class XBT_PUBLIC missing_key_error : public std::runtime_error {
28 explicit missing_key_error(const std::string& what)
29 : std::runtime_error(what) {}
30 explicit missing_key_error(const char* what)
31 : std::runtime_error(what) {}
32 ~missing_key_error() override;
35 template<class T> inline
36 std::string to_string(T&& value)
38 return std::to_string(std::forward<T>(value));
40 inline std::string const& to_string(std::string& value)
44 inline std::string const& to_string(std::string const& value)
48 inline std::string to_string(std::string&& value)
50 return std::move(value);
55 template <class T> XBT_PUBLIC T const& getConfig(const char* name);
57 extern template XBT_PUBLIC int const& getConfig<int>(const char* name);
58 extern template XBT_PUBLIC double const& getConfig<double>(const char* name);
59 extern template XBT_PUBLIC bool const& getConfig<bool>(const char* name);
60 extern template XBT_PUBLIC std::string const& getConfig<std::string>(const char* name);
64 /** Register a configuration flag
66 * @param name name of the option
67 * @param description Description of the option
68 * @param value Initial/default value
69 * @param callback called with the option value
72 XBT_PUBLIC void declareFlag(const char* name, const char* description, T value,
73 std::function<void(const T&)> callback = std::function<void(const T&)>());
75 extern template XBT_PUBLIC void declareFlag(const char* name, const char* description, int value,
76 std::function<void(int const&)> callback);
77 extern template XBT_PUBLIC void declareFlag(const char* name, const char* description, double value,
78 std::function<void(double const&)> callback);
79 extern template XBT_PUBLIC void declareFlag(const char* name, const char* description, bool value,
80 std::function<void(bool const&)> callback);
81 extern template XBT_PUBLIC void declareFlag(const char* name, const char* description, std::string value,
82 std::function<void(std::string const&)> callback);
86 XBT_PUBLIC void alias(const char* realname, const char* aliasname);
89 void alias(std::initializer_list<const char*> names)
91 auto i = names.begin();
92 for (++i; i != names.end(); ++i)
93 alias(*names.begin(), *i);
96 /** Bind a variable to configuration flag
98 * @param value Bound variable
99 * @param name Flag name
100 * @param description Option description
103 void bindFlag(T& value, const char* name, const char* description)
105 declareFlag<T>(name, description, value, [&value](T const& val) {
111 void bindFlag(T& value, std::initializer_list<const char*> names, const char* description)
113 bindFlag(value, *names.begin(), description);
117 /** Bind a variable to configuration flag
121 * simgrid::config::bindFlag(a, "x", [](int x) {
122 * if (x < x_min || x => x_max)
123 * throw std::range_error("must be in [x_min, x_max)")
127 // F is a checker, F : T& -> ()
128 template<class T, class F>
129 typename std::enable_if<std::is_same<
131 decltype( std::declval<F>()(std::declval<const T&>()) )
132 >::value, void>::type
133 bindFlag(T& value, std::initializer_list<const char*> names, const char* description,
136 bindFlag(value, *names.begin(), description);
140 template<class T, class F>
141 typename std::enable_if<std::is_same<
143 decltype( std::declval<F>()(std::declval<const T&>()) )
144 >::value, void>::type
145 bindFlag(T& value, const char* name, const char* description,
148 declareFlag(name, description, value, [&value,callback](const T& val) {
150 value = std::move(val);
154 /** Bind a variable to configuration flag
158 * simgrid::config::bindFlag(a, "x", [](int x) { return return x > 0; });
161 // F is a predicate, F : T const& -> bool
162 template<class T, class F>
163 typename std::enable_if<std::is_same<
165 decltype( std::declval<F>()(std::declval<const T&>()) )
166 >::value, void>::type
167 bindFlag(T& value, const char* name, const char* description,
170 declareFlag(name, description, value, [&value, callback](const T& val) {
171 if (not callback(val))
172 throw std::range_error("invalid value");
173 value = std::move(val);
177 /** A variable bound to a CLI option
180 * static simgrid::config::flag<int> answer("answer", "Expected answer", 42);
181 * static simgrid::config::flag<std::string> name("name", "Ford Prefect", "John Doe");
182 * static simgrid::config::flag<double> gamma("gamma", "Gamma factor", 1.987);
192 * @param name Flag name
193 * @param desc Flag description
194 * @param value Flag initial/default value
196 Flag(const char* name, const char* desc, T value) : value_(value)
198 simgrid::config::bindFlag(value_, name, desc);
202 Flag(const char* name, const char* desc, T value, F callback) : value_(value)
204 simgrid::config::bindFlag(value_, name, desc, std::move(callback));
208 Flag(Flag const&) = delete;
209 Flag& operator=(Flag const&) = delete;
211 // Get the underlying value:
212 T& get() { return value_; }
213 T const& get() const { return value_; }
215 // Implicit conversion to the underlying type:
216 operator T&() { return value_; }
217 operator T const&() const{ return value_; }
219 // Basic interop with T:
221 Flag& operator=(U const& that) { value_ = that; return *this; }
223 Flag& operator=(U && that) { value_ = that; return *this; }
225 bool operator==(U const& that) const { return value_ == that; }
227 bool operator!=(U const& that) const { return value_ != that; }
229 bool operator<(U const& that) const { return value_ < that; }
231 bool operator>(U const& that) const { return value_ > that; }
233 bool operator<=(U const& that) const { return value_ <= that; }
235 bool operator>=(U const& that) const { return value_ >= that; }
240 XBT_PUBLIC std::string xbt_cfg_get_string(const char* name);