1 /* Copyright (c) 2016. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #ifndef _XBT_CONFIG_HPP_
8 #define _XBT_CONFIG_HPP_
12 #include <type_traits>
15 #include <xbt/config.h>
20 /** Get the base type of a e_xbt_cfgelm_type_t
22 * * `type` is the type used in the config framework to store
23 * the values of this type;
25 * * `get()` is used to get such a value from the configuration.
27 template<e_xbt_cfgelm_type_t type>
29 template<> struct base_type<xbt_cfgelm_boolean> {
31 static inline bool get(const char* name)
33 return xbt_cfg_get_boolean(name) ? true : false;
36 template<> struct base_type<xbt_cfgelm_int> {
38 static inline int get(const char* name)
40 return xbt_cfg_get_int(name);
43 template<> struct base_type<xbt_cfgelm_double> {
45 static inline double get(const char* name)
47 return xbt_cfg_get_double(name);
50 template<> struct base_type<xbt_cfgelm_string> {
51 typedef std::string type;
52 static inline std::string get(const char* name)
54 char* value = xbt_cfg_get_string(name);
55 return value != nullptr ? value : "";
59 /** Associate the e_xbt_cfgelm_type_t to use for a given type */
61 struct cfgelm_type : public std::integral_constant<e_xbt_cfgelm_type_t,
62 std::is_same<T, bool>::value ? xbt_cfgelm_boolean :
63 std::is_integral<T>::value ? xbt_cfgelm_int :
64 std::is_floating_point<T>::value ? xbt_cfgelm_double :
68 /** Get a value of a given type from the configuration */
69 template<class T> inline
70 T get(const char* name)
72 return T(base_type<cfgelm_type<T>::value>::get(name));
74 template<class T> inline
75 T get(std::string const& name)
77 return T(base_type<cfgelm_type<T>::value>::get(name.c_str()));
80 inline void setDefault(const char* name, int value)
82 xbt_cfg_setdefault_int(name, value);
84 inline void setDefault(const char* name, double value)
86 xbt_cfg_setdefault_double(name, value);
88 inline void setDefault(const char* name, const char* value)
90 xbt_cfg_setdefault_string(name, value);
92 inline void setDefault(const char* name, std::string const& value)
94 xbt_cfg_setdefault_string(name, value.c_str());
96 inline void setDefault(const char* name, bool value)
98 xbt_cfg_setdefault_boolean(name, value ? "yes" : "no");
101 /** Set the default value of a given configuration option */
102 template<class T> inline
103 void setDefault(const char* name, T value)
105 setDefault(name, base_type<cfgelm_type<T>::value>::type(value));
110 /** Register a configuration flag
112 * @param name name of the option
113 * @param description Description of the option
114 * @param type config storage type for the option
115 * @param callback called with the option name (expected to use `simgrid::config::get`)
117 XBT_PUBLIC(void) registerConfig(const char* name, const char* description,
118 e_xbt_cfgelm_type_t type,
119 std::function<void(const char*)> callback);
121 /** Bind a variable to configuration flag
123 * @param value Bound variable
124 * @param name Flag name
125 * @param description Option description
128 void declareFlag(T& value, const char* name, const char* description)
130 registerConfig(name, description, cfgelm_type<T>::value,
131 [&value](const char* name) {
132 value = simgrid::config::get<T>(name);
134 setDefault(name, value);
137 /** Bind a variable to configuration flag
139 * @param value Bound variable
140 * @param name Flag name
141 * @param description Option description
142 * @f Callback (called with the option name) providing the value
144 template<class T, class F>
145 void declareFlag(T& value, const char* name, const char* description, F f)
147 registerConfig(name, description, cfgelm_type<T>::value,
148 [&value,f](const char* name) {
151 setDefault(name, value);
154 /** A variable bound to a CLI option
157 * static simgrid::config::flag<int> answer("answer", "Expected answer", 42);
158 * static simgrid::config::flag<std::string> name("name", "Ford Prefect", "John Doe");
159 * static simgrid::config::flag<double> gamma("gamma", "Gamma factor", 1.987);
169 * @param name Flag name
170 * @param desc Flag description
171 * @param value Flag initial/default value
173 flag(const char* name, const char* desc, T value) : value_(value)
175 declareFlag(value_, name, desc);
179 flag(flag const&) = delete;
180 flag& operator=(flag const&) = delete;
182 // Get the underlying value:
183 T& get() { return value_; }
184 T const& get() const { return value_; }
186 // Implicit conversion to the underlying type:
187 operator T&() { return value_; }
188 operator T const&() const{ return value_; }