CoolProp 8.0.0
An open-source fluid property and humid air property database
Configuration.h
Go to the documentation of this file.
1#ifndef COOLPROP_CONFIGURATION
2#define COOLPROP_CONFIGURATION
3
6#include <cstdlib>
7#include <unordered_map>
8
9/* See http://stackoverflow.com/a/148610
10 * See http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511
11 * This will be used to generate an enum like:
12 * enum configuration_keys {NORMALIZE_GAS_CONSTANTS, CRITICAL_SPLINES_ENABLED};
13 *
14 * The values in this list are given by:
15 * enum, string representation of enum, default value, description
16 *
17 * The type of the default value specifies the only type that will be accepted for this parameter
18 */
20
21// Evidently SWIG+MATLAB cannot properly wrap enums within classes
23{
30};
31
32namespace CoolProp {
33
36
38configuration_keys config_string_to_key(const std::string& s);
39
42
44std::string config_key_description(const std::string& key);
45
49{
50 public:
52 return type;
53 }
54
56 operator bool() const {
57 check_data_type(CONFIGURATION_BOOL_TYPE);
58 return v_bool;
59 };
61 operator double() const {
62 check_data_type(CONFIGURATION_DOUBLE_TYPE);
63 return v_double;
64 };
66 operator std::string() const {
67 check_data_type(CONFIGURATION_STRING_TYPE);
68 return v_string;
69 };
71 operator int() const {
72 check_data_type(CONFIGURATION_INTEGER_TYPE);
73 return v_integer;
74 };
75 // Initializer for bool
77
78 v_bool = val;
79 };
80 // Initializer for integer
82
83 v_integer = val;
84 };
85 // Initializer for double
87
88 v_double = val;
89 };
90 // Initializer for const char *
92 : key(key), type(CONFIGURATION_STRING_TYPE), v_string(val) {
93
94 };
95 // Initializer for string
96 ConfigurationItem(configuration_keys key, const std::string& val)
97 : key(key), type(CONFIGURATION_STRING_TYPE), v_string(val) {
98
99 };
100 void set_bool(bool val) {
101 check_data_type(CONFIGURATION_BOOL_TYPE);
102 v_bool = val;
103 }
104 void set_integer(int val) {
105 check_data_type(CONFIGURATION_INTEGER_TYPE);
106 v_integer = val;
107 }
108 void set_double(double val) {
109 check_data_type(CONFIGURATION_DOUBLE_TYPE);
110 v_double = val;
111 }
112 void set_string(const std::string& val) {
113 check_data_type(CONFIGURATION_STRING_TYPE);
114 v_string = val;
115 }
116
118 return this->key;
119 }
120
121 private:
122 void check_data_type(ConfigurationDataTypes type) const {
123 if (type != this->type) {
124 throw ValueError(format("type does not match"));
125 }
126 };
128 union
129 {
130 double v_double;
131 bool v_bool;
133 };
134 std::string v_string;
136};
137
139{
140 protected:
141 std::unordered_map<configuration_keys, ConfigurationItem> items;
142
143 public:
145 set_defaults();
146 };
147 ~Configuration() = default;
148
151 // Try to find it
152 auto it = items.find(key);
153 // If equal to end, not found
154 if (it != items.end()) {
155 // Found, return it
156 return it->second;
157 } else {
158 throw ValueError(format("invalid item"));
159 }
160 }
162 void add_item(const ConfigurationItem& item) {
163 std::pair<configuration_keys, ConfigurationItem> pair(item.get_key(), item);
164 items.insert(pair);
165 };
166
168 std::unordered_map<configuration_keys, ConfigurationItem>& get_items() {
169 return items;
170 };
171
174 std::string envkey = "COOLPROP_" + config_key_to_string(key);
175 const char* envval = std::getenv(envkey.c_str());
176 if (envval) {
177 auto tobool = [](const std::string& x) {
178 if (x == "True" || x == "true") {
179 return true;
180 }
181 if (x == "False" || x == "false") {
182 return false;
183 }
184 throw ValueError(x);
185 };
186 switch (get_item(key).get_type()) {
188 items.erase(key);
189 items.emplace(key, ConfigurationItem(key, std::string(envval)));
190 break;
192 int i;
193 try {
194 i = std::stoi(envval);
195 } catch (...) {
196 auto skey = config_key_to_string(key);
197 std::string msg = "Unable to convert \"" + std::string(envval) + "\" to int for key [" + skey + "]";
198 std::cerr << msg << '\n';
199 throw ValueError(msg);
200 }
201 items.erase(key);
202 items.emplace(key, ConfigurationItem(key, i));
203 break;
204 }
206 double d;
207 try {
208 d = std::stod(envval);
209 } catch (...) {
210 auto skey = config_key_to_string(key);
211 std::string msg = "Unable to convert \"" + std::string(envval) + "\" to double for key [" + skey + "]";
212 std::cerr << msg << '\n';
213 throw ValueError(msg);
214 }
215 items.erase(key);
216 items.emplace(key, ConfigurationItem(key, d));
217 break;
218 }
220 bool b;
221 try {
222 b = tobool(envval);
223 } catch (...) {
224 auto skey = config_key_to_string(key);
225 std::string msg = "Unable to convert \"" + std::string(envval) + "\" to bool for key [" + skey + "]";
226 std::cerr << msg << '\n';
227 throw ValueError(msg);
228 }
229 items.erase(key);
230 items.emplace(key, ConfigurationItem(key, b));
231 break;
232 }
233 default: {
234 auto skey = config_key_to_string(key);
235 throw ValueError("This key [" + skey + "] has the wrong type; value was " + std::string(envval) + " ");
236 }
237 }
238 return true;
239 }
240 return false;
241 }
242
245/* ***MAGIC WARNING**!!
246 * See http://stackoverflow.com/a/148610
247 * See http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c#202511
248 */
249#define X(Enum, String, Default, Desc) add_item(ConfigurationItem(Enum, Default));
251#undef X
252
253 // See if the variable is already present as environment variable
254#define X(Enum, String, Default, Desc) possibly_set_from_env(Enum);
256#undef X
257
258 };
259};
260
264
274std::string get_config_as_json_string();
275
279
281void set_config_bool(configuration_keys key, bool val);
283void set_config_int(configuration_keys key, int val);
285void set_config_double(configuration_keys key, double val);
287void set_config_string(configuration_keys key, const std::string& val);
289void set_config_as_json_string(const std::string& s);
290} // namespace CoolProp
291
292#endif // COOLPROP_CONFIGURATION