diff --git a/src/io/ParameterMap.cpp b/src/io/ParameterMap.cpp index ac5e81382..7de922f47 100644 --- a/src/io/ParameterMap.cpp +++ b/src/io/ParameterMap.cpp @@ -417,4 +417,54 @@ int ParameterMap::warn_unused_parameters(const std::set& ignore_par } } return unused_params; +} + +void ParameterMap::Enforce_Table_Content_Uniform_Access_Status(std::string table_name, bool expect_unused) const +{ + // error check: + std::string_view table_name_view(table_name); + if (table_name_view.back() == '.') table_name_view = table_name_view.substr(0, table_name_view.size() - 1); + CHOLLA_ASSERT(table_name_view.size() > 0, "the table_name_view must contain at least one character"); + + std::string prefix = std::string(table_name_view) + '.'; + std::size_t prefix_size = prefix.size(); + + std::string problematic_parameter{}; + for (auto it = entries_.lower_bound(prefix); it != entries_.end(); ++it) { + const std::string& name = it->first; + const ParameterMap::ParamEntry& param_entry = it->second; + if (name.compare(0, prefix_size, prefix) != 0) break; + + if (param_entry.accessed == expect_unused) { + problematic_parameter = name; + break; + } + } + + if (problematic_parameter.size() == 0) return; // no issues! + + // Report the errors: + if (expect_unused) { + CHOLLA_ERROR("Internal Error: the %s shouldn't have been accessed yet", problematic_parameter.c_str()); + } else { + // gather the parameters that have been accessed (for an informative message) + std::string par_list{}; + for (auto it = entries_.lower_bound(prefix); it != entries_.end(); ++it) { + const std::string& name = it->first; + const ParameterMap::ParamEntry& param_entry = it->second; + if (name.compare(0, prefix_size, prefix) != 0) break; + + if (param_entry.accessed) { + par_list += "\n "; + par_list += name; + } + } + + if (par_list.size() > 0) { + CHOLLA_ERROR("Based on the parameter(s):%s\nthe %s parameter should not be present in the parameter file", + par_list.c_str(), problematic_parameter.c_str()); + } + CHOLLA_ERROR("Something is wrong, the %s parameter should not be present in the parameter file", + problematic_parameter.c_str()); + } } \ No newline at end of file diff --git a/src/io/ParameterMap.h b/src/io/ParameterMap.h index 392ac2f9f..4d848ab13 100644 --- a/src/io/ParameterMap.h +++ b/src/io/ParameterMap.h @@ -199,6 +199,13 @@ class ParameterMap } } + /*! Aborts with an error message if one or more of the parameters in the specified table has been used or has not + * been used. The precise details depend on the `expect_unused` argument. + * + * \note + * It may be better if this were a function that operated on ParameterMap rather than a method */ + void Enforce_Table_Content_Uniform_Access_Status(std::string table_name, bool expect_unused) const; + private: // private helper methods /* helper function template that tries to retrieve values associated with a given parameter. * diff --git a/src/io/ParameterMap_tests.cpp b/src/io/ParameterMap_tests.cpp index 8622748eb..717d57964 100644 --- a/src/io/ParameterMap_tests.cpp +++ b/src/io/ParameterMap_tests.cpp @@ -259,10 +259,15 @@ key2=456 DummyFile dummy = DummyFile(CONTENTS); ParameterMap pmap = ParameterMap(dummy.fp, 0, nullptr); ASSERT_EQ(pmap.size(), 4); + pmap.Enforce_Table_Content_Uniform_Access_Status("table-1", true); ASSERT_EQ(pmap.value("table-1.key1"), -1.0); ASSERT_EQ(pmap.value("table-1.key2"), 123); + pmap.Enforce_Table_Content_Uniform_Access_Status("table-1", false); + + pmap.Enforce_Table_Content_Uniform_Access_Status("table-2", true); ASSERT_EQ(pmap.value("table-2.key1"), -2.0); ASSERT_EQ(pmap.value("table-2.key2"), 456); + pmap.Enforce_Table_Content_Uniform_Access_Status("table-2", false); } TEST(tALLParameterMapTables, EmptyName)