#ifndef ATOOLS_Org_ScopedSettings_H #define ATOOLS_Org_ScopedSettings_H #include "ATOOLS/Org/Settings.H" #include namespace ATOOLS { class Scoped_Settings { friend Settings; public: Scoped_Settings(); Scoped_Settings(const std::string& yamlstring); Scoped_Settings(const Scoped_Settings&); Scoped_Settings& operator=(Scoped_Settings); Scoped_Settings operator[](const std::string& scope) const; Scoped_Settings operator[](size_t scope) const; std::vector GetKeys(); void DeclareVectorSettingsWithEmptyDefault(const std::vector& keys); void DeclareMatrixSettingsWithEmptyDefault(const std::vector& keys); template Scoped_Settings& SetDefault(const T&); template Scoped_Settings& SetDefault(const std::vector&); template Scoped_Settings& SetDefault(std::initializer_list); template Scoped_Settings& SetDefault(const std::vector>&); template Scoped_Settings& SetDefault(std::initializer_list>); bool HasDefault() const; Scoped_Settings& ResetDefault(); template Scoped_Settings& SetReplacementList(const std::map& list); Scoped_Settings& SetDefaultSynonyms(const String_Vector&); Scoped_Settings& SetSynonyms(const String_Vector&); /// set a common replacement list: [Off, false, 0, no] -> None Scoped_Settings& UseNoneReplacements(); /// set a common replacement list: [None] -> max double Scoped_Settings& UseMaxDoubleReplacements(); /// set a common replacement list: [None] -> 0 Scoped_Settings& UseZeroReplacements(); bool IsSetExplicitly(); void SetInterpreterEnabled(bool b) { m_interpreterenabled = b; } template T Interprete(const std::string&); template void OverrideScalar(const T&); template void OverrideVector(const std::vector&); template void OverrideMatrix(const std::vector>&); template T Get(); // alias for GetScalar template T GetScalar(); template std::vector GetVector(); template std::vector> GetMatrix(); template T GetScalarWithOtherDefault(const T& otherdefault); /** * convenience method to read two-valued settings * * this is often useful in the context of beam-specific settings * @param expandsinglevalues If true and only a single value is * encountered, this value is automatically repeated to return a two-valued * vector. */ template std::vector GetTwoVector(bool expandsinglevalues=true); void ReplaceTags(std::string& s) { return m_rootsettings->ReplaceTags(s); } std::string GetPath() { return m_rootsettings->GetPath(); } bool IsScalar() const; bool IsList() const; bool IsMap() const; std::vector GetItems() const; size_t GetItemsCount(); Scoped_Settings GetItemAtIndex(const size_t&) const; /** * obtain the index of the current item * * If the scope does not point to a sequence of sub-settings, an exception * is thrown. */ size_t GetIndex() const; private: // use this if it is not otherwise guaranteed that rootsettings is kept // alive std::shared_ptr m_ownedsettings; Settings* m_rootsettings; Settings_Keys m_scopes; Scoped_Settings(Settings &rootsettings, const std::string& scope); Scoped_Settings Scoped(const Setting_Key& scope) const; void AppendScope(const Setting_Key& scope); bool m_interpreterenabled{ true }; }; template Scoped_Settings& Scoped_Settings::SetDefault(const T& value) { m_rootsettings->SetDefault(m_scopes, value); return *this; } template Scoped_Settings& Scoped_Settings::SetDefault(const std::vector& values) { m_rootsettings->SetDefault(m_scopes, values); return *this; } template Scoped_Settings& Scoped_Settings::SetDefault(std::initializer_list values) { m_rootsettings->SetDefault(m_scopes, std::vector(values)); return *this; } template Scoped_Settings& Scoped_Settings::SetDefault( const std::vector>& values) { m_rootsettings->SetDefaultMatrix(m_scopes, values); return *this; } template Scoped_Settings& Scoped_Settings::SetDefault(std::initializer_list> l) { std::vector> m; for (const auto& row : l) m.push_back(row); m_rootsettings->SetDefaultMatrix(m_scopes, m); return *this; } template Scoped_Settings& Scoped_Settings::SetReplacementList( const std::map& list) { m_rootsettings->SetReplacementList(m_scopes, list); return *this; } template void Scoped_Settings::OverrideScalar(const T& value) { m_rootsettings->OverrideScalar(m_scopes, value); } template void Scoped_Settings::OverrideVector(const std::vector& values) { m_rootsettings->OverrideVector(m_scopes, values); } template void Scoped_Settings::OverrideMatrix( const std::vector>& values) { m_rootsettings->OverrideMatrix(m_scopes, values); } template T Scoped_Settings::Get() { return GetScalar(); } template T Scoped_Settings::GetScalar() { auto wasenabled = m_rootsettings->SetInterpreterEnabled(m_interpreterenabled); const auto r = m_rootsettings->GetScalar(m_scopes); m_rootsettings->SetInterpreterEnabled(wasenabled); return r; } template std::vector Scoped_Settings::GetVector() { auto wasenabled = m_rootsettings->SetInterpreterEnabled(m_interpreterenabled); const auto r = m_rootsettings->GetVector(m_scopes); m_rootsettings->SetInterpreterEnabled(wasenabled); return r; } template std::vector> Scoped_Settings::GetMatrix() { auto wasenabled = m_rootsettings->SetInterpreterEnabled(m_interpreterenabled); const auto r = m_rootsettings->GetMatrix(m_scopes); m_rootsettings->SetInterpreterEnabled(wasenabled); return r; } template T Scoped_Settings::GetScalarWithOtherDefault(const T& otherdefault) { auto wasenabled = m_rootsettings->SetInterpreterEnabled(m_interpreterenabled); const auto r = m_rootsettings->GetScalarWithOtherDefault(m_scopes, otherdefault); m_rootsettings->SetInterpreterEnabled(wasenabled); return r; } template std::vector Scoped_Settings::GetTwoVector(bool expandsinglevalues) { auto values = GetVector(); if (values.size() == 1 && expandsinglevalues) { values.push_back(values[0]); } else if (values.size() != 2) { THROW(fatal_error, "The setting " + m_scopes.Name() + " must hold " + (expandsinglevalues ? "one or two" : "two") + " values."); } assert(values.size() == 2); return values; } template T Scoped_Settings::Interprete(const std::string& value) { return m_rootsettings->Interprete(value); } } #endif