File indexing completed on 2025-04-19 09:09:54
0001 #ifndef ATOOLS_Org_Settings_H
0002 #define ATOOLS_Org_Settings_H
0003
0004 #include "ATOOLS/Org/Command_Line_Interface.H"
0005 #include "ATOOLS/Org/Settings_Keys.H"
0006 #include "ATOOLS/Org/Yaml_Reader.H"
0007 #include "ATOOLS/Org/MyStrStream.H"
0008 #include "ATOOLS/Org/Read_Write_Base.H"
0009
0010 #include <vector>
0011 #include <unordered_set>
0012
0013 namespace ATOOLS {
0014
0015 class Settings_Keys;
0016 class Scoped_Settings;
0017 class Settings_Writer;
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 class Settings {
0072
0073 friend Scoped_Settings;
0074 friend Settings_Writer;
0075
0076 public:
0077
0078 static void InitializeMainSettings(int argc, char* argv[]);
0079 static void FinalizeMainSettings();
0080 static Settings& GetMainSettings();
0081
0082 Settings();
0083 Settings(const std::string& yaml);
0084
0085 Scoped_Settings operator[](const std::string& scope);
0086
0087 std::vector<std::string> GetKeys();
0088
0089
0090 void DeclareVectorSettingsWithEmptyDefault(const std::vector<std::string>& keys);
0091 void DeclareMatrixSettingsWithEmptyDefault(const std::vector<std::string>& keys);
0092
0093
0094
0095
0096
0097
0098
0099 void AddGlobalTag(const std::string& key, const std::string& value);
0100
0101
0102
0103
0104
0105
0106
0107 void AddTag(const std::string& key, const std::string& value);
0108 const String_Map& GetTags() { return m_tags; }
0109 void ReplaceTags(std::string&);
0110
0111 std::string GetPath();
0112 String_Vector GetConfigFiles();
0113 String_Vector GetUserConfigFiles();
0114
0115 private:
0116
0117 static std::unique_ptr<Settings> mainsettings;
0118
0119
0120 typedef String_Vector Defaults_Key;
0121 typedef String_Matrix Defaults_Value;
0122 typedef std::map<Defaults_Key, Defaults_Value> Defaults;
0123 Defaults m_defaults;
0124 Defaults m_overrides;
0125
0126
0127 std::map<Settings_Keys, std::set<Defaults_Value>> m_usedvalues;
0128 std::map<Defaults_Key, std::unordered_set<std::string>> m_otherscalardefaults;
0129
0130 std::map<Defaults_Key, String_Map> m_replacements;
0131 std::map<Defaults_Key, String_Vector> m_defaultsynonyms;
0132 std::map<Defaults_Key, String_Vector> m_synonyms;
0133
0134 String_Map m_tags;
0135 String_Map m_globaltags;
0136
0137
0138
0139 std::vector<std::unique_ptr<Yaml_Reader>> m_yamlreaders;
0140
0141 Algebra_Interpreter m_interpeter;
0142 bool m_interpreterenabled{ true };
0143
0144 Settings(int argc, char* argv[]);
0145
0146 std::vector<std::string> GetKeys(const Settings_Keys&);
0147
0148 bool SetInterpreterEnabled(bool b) {
0149 const auto wasenabled = m_interpreterenabled;
0150 m_interpreterenabled = b;
0151 return wasenabled;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160 template <typename T>
0161 T Interprete(std::string);
0162
0163 void DeclareVectorSettingsWithEmptyDefault(const std::vector<std::string>& keys,
0164 const Settings_Keys&);
0165 void DeclareMatrixSettingsWithEmptyDefault(const std::vector<std::string>& keys,
0166 const Settings_Keys&);
0167
0168 template <typename T>
0169 void SetDefault(const Settings_Keys&, const T& value);
0170 void SetDefault(const Settings_Keys&, const char* value);
0171 template <typename T>
0172 void SetDefault(const Settings_Keys&,
0173 const std::vector<T>& values);
0174 template <typename T>
0175 void SetDefaultMatrix(const Settings_Keys&,
0176 const std::vector<std::vector<T>>& values);
0177 template <typename T>
0178 void SetDefaultMatrix(const std::vector<std::string>& keys,
0179 const std::vector<std::vector<T>>& values);
0180 bool HasDefault(const std::vector<std::string> &keys) const;
0181 void ResetDefault(const std::vector<std::string> &keys);
0182
0183 bool IsSetExplicitly(const Settings_Keys&);
0184
0185 template <typename T>
0186 void OverrideScalar(const Settings_Keys&, const T& value);
0187 template <typename T>
0188 void OverrideVector(const Settings_Keys&, const std::vector<T>& values);
0189 template <typename T>
0190 void OverrideMatrix(const Settings_Keys&,
0191 const std::vector<std::vector<T>>& values);
0192
0193 std::string GetScalarDefault(const Defaults_Key&, const Defaults&);
0194 String_Vector GetVectorDefault(const Defaults_Key&, const Defaults&);
0195 String_Matrix GetMatrixDefault(const Defaults_Key&, const Defaults&);
0196
0197 template <typename T>
0198 T GetScalar(const Settings_Keys&);
0199 template <typename T>
0200 std::vector<T> GetVector(const Settings_Keys&);
0201 template <typename T>
0202 std::vector<std::vector<T>> GetMatrix(const Settings_Keys&);
0203
0204 template <typename T>
0205 T GetScalarWithOtherDefault(const Settings_Keys&, const T& otherdefault);
0206
0207 template <typename T>
0208 void SetReplacementList(const Settings_Keys&,
0209 const std::map<std::string, T>& list);
0210
0211 void SetDefaultSynonyms(const Settings_Keys&,
0212 const String_Vector& synonyms);
0213
0214 void SetSynonyms(const Settings_Keys&,
0215 const String_Vector& synonyms);
0216
0217 bool IsScalar(const Settings_Keys&);
0218 bool IsList(const Settings_Keys&);
0219 bool IsMap(const Settings_Keys&);
0220 size_t GetItemsCount(const Settings_Keys&);
0221
0222 template <typename T>
0223 T Convert(const Settings_Keys&, const std::string&);
0224
0225 bool IsDefaultSynonym(const Settings_Keys&,
0226 const std::string& value);
0227
0228 std::string ApplyReplacements(const Settings_Keys&,
0229 const std::string& value);
0230
0231
0232 inline bool is_absolute(const std::string &s) {return (s.find("/") ==0);}
0233 };
0234
0235 template <typename T>
0236 void Settings::SetDefault(const Settings_Keys& keys,
0237 const T& value)
0238 {
0239 SetDefaultMatrix<T>(keys, {{value}});
0240 }
0241
0242 template <typename T>
0243 void Settings::SetDefault(const Settings_Keys& keys,
0244 const std::vector<T>& values)
0245 {
0246 SetDefaultMatrix<T>(keys, {values});
0247 }
0248
0249 template <typename T>
0250 void Settings::SetDefaultMatrix(const Settings_Keys& keys,
0251 const std::vector<std::vector<T> >& values)
0252 {
0253 SetDefaultMatrix(keys.IndicesRemoved(), values);
0254 }
0255
0256 template <typename T>
0257 void Settings::SetDefaultMatrix(const std::vector<std::string>& keys,
0258 const std::vector<std::vector<T> >& values)
0259 {
0260 String_Matrix stringvalues;
0261 for (const auto& valuerow : values) {
0262 std::vector<std::string> stringvaluerow;
0263 for (const auto& value : valuerow) {
0264 stringvaluerow.push_back(ToString(value));
0265 }
0266 stringvalues.push_back(stringvaluerow);
0267 }
0268 const auto it = m_defaults.find(keys);
0269 if (it != m_defaults.end()) {
0270 if (it->second != stringvalues) {
0271 THROW(fatal_error, "The default value for " +
0272 VectorToString(keys, 12, ":") +
0273 " is already set to a different value.");
0274 } else {
0275 return;
0276 }
0277 }
0278 m_defaults[keys] = stringvalues;
0279 }
0280
0281 template <typename T>
0282 void Settings::OverrideScalar(const Settings_Keys& settings_keys,
0283 const T& value)
0284 {
0285 OverrideVector<T>(settings_keys, {value});
0286 }
0287
0288 template <typename T>
0289 void Settings::OverrideVector(const Settings_Keys& settings_keys,
0290 const std::vector<T>& values)
0291 {
0292 OverrideMatrix<T>(settings_keys, {values});
0293 }
0294
0295 template <typename T>
0296 void Settings::OverrideMatrix(const Settings_Keys& settings_keys,
0297 const std::vector<std::vector<T>>& values)
0298 {
0299 String_Matrix stringvalues;
0300 for (const auto& valuerow : values) {
0301 std::vector<std::string> stringvaluerow;
0302 for (const auto& value : valuerow) {
0303 stringvaluerow.push_back(ToString(value));
0304 }
0305 stringvalues.push_back(stringvaluerow);
0306 }
0307 const std::vector<std::string> keys{ settings_keys.IndicesRemoved() };
0308 const auto it = m_overrides.find(keys);
0309 if (it != m_overrides.end()) {
0310 if (it->second != stringvalues) {
0311 THROW(fatal_error,
0312 "The override for "
0313 + keys.back() + " is already set to a different value.");
0314 } else {
0315 return;
0316 }
0317 }
0318 m_overrides[keys] = stringvalues;
0319 }
0320
0321 template <typename T>
0322 T Settings::GetScalar(const Settings_Keys& settings_keys)
0323 {
0324 Defaults_Key keys{ settings_keys.IndicesRemoved() };
0325 Settings_Keys used_synonym_settings_keys;
0326 std::string defaultvalue;
0327 defaultvalue = GetScalarDefault(keys, m_defaults);
0328 std::string value;
0329 if (m_overrides.find(keys) != m_overrides.end()) {
0330 value = GetScalarDefault(keys, m_overrides);
0331 } else {
0332 const auto it = m_synonyms.find(keys);
0333 for (auto& reader : m_yamlreaders) {
0334 value = reader->GetScalar<std::string>(settings_keys);
0335 if (value.empty() && it != m_synonyms.end()) {
0336 auto synonym_settings_keys = settings_keys;
0337 for (const auto& synonym : it->second) {
0338 synonym_settings_keys.back() = synonym;
0339 value = reader->GetScalar<std::string>(synonym_settings_keys);
0340 if (!value.empty()) {
0341 used_synonym_settings_keys = synonym_settings_keys;
0342 keys = synonym_settings_keys.IndicesRemoved();
0343 break;
0344 }
0345 }
0346 }
0347 if (!value.empty())
0348 break;
0349 }
0350 }
0351 if (value.empty() || IsDefaultSynonym(settings_keys, value)) {
0352 value = defaultvalue;
0353 }
0354 const auto convertedvalue = Convert<T>(settings_keys, value);
0355 if (value.empty()) {
0356 if (!used_synonym_settings_keys.empty())
0357 m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{""}});
0358 else
0359 m_usedvalues[settings_keys].insert(String_Matrix{{""}});
0360 }
0361 else {
0362 if (!used_synonym_settings_keys.empty())
0363 m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{ToString<T>(convertedvalue)}});
0364 else
0365 m_usedvalues[settings_keys].insert(String_Matrix{{ToString<T>(convertedvalue)}});
0366 }
0367 return Convert<T>(settings_keys, value);
0368 }
0369
0370 template <typename T>
0371 std::vector<T> Settings::GetVector(const Settings_Keys& settings_keys)
0372 {
0373 Defaults_Key keys{ settings_keys.IndicesRemoved() };
0374 Settings_Keys used_synonym_settings_keys;
0375 String_Vector defaultvalues;
0376 defaultvalues = GetVectorDefault(keys, m_defaults);
0377 std::vector<std::string> values;
0378 if (m_overrides.find(keys) != m_overrides.end()) {
0379 values = GetVectorDefault(keys, m_overrides);
0380 } else {
0381 const auto it = m_synonyms.find(keys);
0382 for (auto& reader : m_yamlreaders) {
0383 values = reader->GetVector<std::string>(settings_keys);
0384 if (values.empty() && it != m_synonyms.end()) {
0385 auto synonym_settings_keys = settings_keys;
0386 for (const auto& synonym : it->second) {
0387 synonym_settings_keys.back() = synonym;
0388 values = reader->GetVector<std::string>(synonym_settings_keys);
0389 if (!values.empty()) {
0390 used_synonym_settings_keys = synonym_settings_keys;
0391 keys = synonym_settings_keys.IndicesRemoved();
0392 break;
0393 }
0394 }
0395 }
0396 if (!values.empty())
0397 break;
0398 }
0399 }
0400 if (values.empty())
0401 values = defaultvalues;
0402 std::vector<T> convertedvalues;
0403 std::vector<std::string> convertedstringvalues;
0404 for (std::vector<std::string>::const_iterator it(values.begin());
0405 it != values.end();
0406 ++it) {
0407 convertedvalues.push_back(Convert<T>(settings_keys, *it));
0408 convertedstringvalues.push_back(ToString<T>(convertedvalues.back()));
0409 }
0410 if (values.empty()) {
0411 if (!used_synonym_settings_keys.empty())
0412 m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{}});
0413 else
0414 m_usedvalues[settings_keys].insert(String_Matrix{{}});
0415 }
0416 else {
0417 if (!used_synonym_settings_keys.empty())
0418 m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{convertedstringvalues});
0419 else
0420 m_usedvalues[settings_keys].insert(String_Matrix{convertedstringvalues});
0421 }
0422 return convertedvalues;
0423 }
0424
0425 template <typename T>
0426 std::vector<std::vector<T> > Settings::GetMatrix(
0427 const Settings_Keys& settings_keys)
0428 {
0429 Defaults_Key keys{ settings_keys.IndicesRemoved() };
0430 Settings_Keys used_synonym_settings_keys;
0431 String_Matrix defaultvalues;
0432 defaultvalues = GetMatrixDefault(keys, m_defaults);
0433 String_Matrix values;
0434 if (m_overrides.find(keys) != m_overrides.end()) {
0435 values = GetMatrixDefault(keys, m_overrides);
0436 } else {
0437 const auto it = m_synonyms.find(keys);
0438 for (auto& reader : m_yamlreaders) {
0439 values = reader->GetMatrix<std::string>(settings_keys);
0440 if (values.empty() && it != m_synonyms.end()) {
0441 auto synonym_settings_keys = settings_keys;
0442 for (const auto& synonym : it->second) {
0443 synonym_settings_keys.back() = synonym;
0444 values = reader->GetMatrix<std::string>(synonym_settings_keys);
0445 if (!values.empty()) {
0446 used_synonym_settings_keys = synonym_settings_keys;
0447 keys = synonym_settings_keys.IndicesRemoved();
0448 break;
0449 }
0450 }
0451 }
0452 if (!values.empty())
0453 break;
0454 }
0455 }
0456 if (values.empty())
0457 values = defaultvalues;
0458 std::vector<std::vector<T>> convertedvalues;
0459 String_Matrix convertedstringvalues;
0460 for (const auto& valuerow : values) {
0461 std::vector<T> convertedvaluerow;
0462 String_Vector convertedstringvaluerow;
0463 for (const auto& value : valuerow) {
0464 convertedvaluerow.push_back(Convert<T>(settings_keys, value));
0465 convertedstringvaluerow.push_back(ToString<T>(convertedvaluerow.back()));
0466 }
0467 convertedvalues.push_back(convertedvaluerow);
0468 convertedstringvalues.push_back(convertedstringvaluerow);
0469 }
0470 if (!used_synonym_settings_keys.empty())
0471 m_usedvalues[used_synonym_settings_keys].insert(convertedstringvalues);
0472 else
0473 m_usedvalues[settings_keys].insert(convertedstringvalues);
0474 return convertedvalues;
0475 }
0476
0477 template <typename T>
0478 T Settings::GetScalarWithOtherDefault(const Settings_Keys& settings_keys,
0479 const T& otherdefault)
0480 {
0481 const Defaults_Key keys{ settings_keys.IndicesRemoved() };
0482
0483 const auto it = m_defaults.find(keys);
0484 String_Matrix oldvalue;
0485 bool wasempty{ false };
0486 if (it == m_defaults.end()) {
0487 wasempty = true;
0488 } else {
0489 oldvalue = it->second;
0490 m_defaults.erase(it);
0491 }
0492 SetDefault(settings_keys, otherdefault);
0493 const T value{ GetScalar<T>(settings_keys) };
0494 if (wasempty)
0495 m_defaults.erase(m_defaults.find(keys));
0496 else
0497 m_defaults[keys] = oldvalue;
0498 m_otherscalardefaults[keys].insert(ToString<T>(otherdefault));
0499 return value;
0500 }
0501
0502 template <typename T>
0503 void Settings::SetReplacementList(const Settings_Keys& settings_keys,
0504 const std::map<std::string, T>& list)
0505 {
0506 const Defaults_Key keys{ settings_keys.IndicesRemoved() };
0507 const auto it = m_replacements.find(keys);
0508 if (m_replacements.find(keys) != m_replacements.end())
0509 if (list != it->second)
0510 THROW(fatal_error, "A different scalar replacement list for "
0511 + keys.back() + " has already been set.");
0512 m_replacements[keys] = list;
0513 }
0514
0515
0516 template <typename T>
0517 T Settings::Convert(const Settings_Keys& settings_keys,
0518 const std::string& value)
0519 {
0520 std::string convertedvalue{ value };
0521 ReplaceTags(convertedvalue);
0522 convertedvalue = ApplyReplacements(settings_keys, convertedvalue);
0523 return Interprete<T>(convertedvalue);
0524 }
0525
0526 template <typename T>
0527 T Settings::Interprete(std::string value)
0528 {
0529 T dummy;
0530 if (typeid(dummy) == typeid(int)
0531 || typeid(dummy)==typeid(unsigned int)
0532 || typeid(dummy)==typeid(long)
0533 || typeid(dummy)==typeid(float)
0534 || typeid(dummy)==typeid(double)
0535 || typeid(dummy)==typeid(unsigned long long)) {
0536 value = ReplaceUnits(value);
0537 if (m_interpreterenabled)
0538 value = m_interpeter.Interprete(value);
0539 }
0540 return ToType<T>(value);
0541 }
0542
0543 }
0544
0545 #endif