diff --git a/toolbox/util/Config.hpp b/toolbox/util/Config.hpp index 1734ec22..ac0c2c94 100644 --- a/toolbox/util/Config.hpp +++ b/toolbox/util/Config.hpp @@ -21,10 +21,12 @@ #include #include +#include +#include #include #include #include -#include +#include namespace toolbox { inline namespace util { @@ -246,10 +248,23 @@ class TOOLBOX_API MultiConfig { return section(std::string{name}); } + template + void for_each_section(F f) const + noexcept(noexcept( + f(std::declval(), + std::declval()) + )) + { + std::for_each(map_.begin(), map_.end(), [&f](const auto& kv) { + f(kv.first, kv.second); + }); + } + private: Config root_; // Map of named sections. - std::map map_; + using MapType = std::map; + MapType map_; }; } // namespace util diff --git a/toolbox/util/Config.ut.cpp b/toolbox/util/Config.ut.cpp index 494a7439..48014b49 100644 --- a/toolbox/util/Config.ut.cpp +++ b/toolbox/util/Config.ut.cpp @@ -458,4 +458,34 @@ foo=101 BOOST_CHECK_EQUAL(foo_it == foo_rng.end(), true); } +BOOST_AUTO_TEST_CASE(MultiConfig_for_each_section) +{ + const string text{R"( +[First] +key_abc=value_abc + +[Second] +key_xyz=value_xyz +)"}; + + std::map sections; + + MultiConfig c; + istringstream is{text}; + c.read(is); + c.for_each_section([§ions](const std::string& name, const util::Config& config) { + sections.emplace(name, config); + }); + auto first{sections.find("First")}; + auto second{sections.find("Second")}; + if (first == sections.end()) { + BOOST_FAIL("Missing section 'First'"); + } + if (second == sections.end()) { + BOOST_FAIL("Missing section 'Second'"); + } + BOOST_CHECK_EQUAL(first->second.get("key_abc"), "value_abc"sv); + BOOST_CHECK_EQUAL(second->second.get("key_xyz"), "value_xyz"sv); +} + BOOST_AUTO_TEST_SUITE_END()