From 8e211e2160eb0fc12232552e0e02dd7f584e7fcf Mon Sep 17 00:00:00 2001 From: Peter Hill Date: Thu, 23 Oct 2025 17:04:28 +0100 Subject: [PATCH] Enable non-const iteration over `Options` --- include/bout/options.hxx | 8 ++++++++ src/sys/options/options_netcdf.cxx | 5 +---- tests/unit/sys/test_options.cxx | 11 +++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/bout/options.hxx b/include/bout/options.hxx index 9356326d0e..dbb926838a 100644 --- a/include/bout/options.hxx +++ b/include/bout/options.hxx @@ -205,6 +205,14 @@ public: bout::utils::variant, Matrix, Tensor>; + /// Methods to iterate over `Options` + auto begin() { return std::begin(children); } + auto end() { return std::end(children); } + auto begin() const { return std::begin(children); } + auto end() const { return std::end(children); } + auto cbegin() const { return std::cbegin(children); } + auto cend() const { return std::cend(children); } + /// A tree representation with leaves containing ValueType. /// Used to construct Options from initializer lists. /// diff --git a/src/sys/options/options_netcdf.cxx b/src/sys/options/options_netcdf.cxx index 60dfba2102..94b62f0f02 100644 --- a/src/sys/options/options_netcdf.cxx +++ b/src/sys/options/options_netcdf.cxx @@ -448,10 +448,7 @@ void NcPutAttVisitor::operator()(const std::string& value) { void writeGroup(const Options& options, NcGroup group, const std::string& time_dimension) { - for (const auto& childpair : options.getChildren()) { - const auto& name = childpair.first; - const auto& child = childpair.second; - + for (const auto& [name, child] : options) { if (child.isValue()) { try { auto nctype = bout::utils::visit(NcTypeVisitor(), child.value); diff --git a/tests/unit/sys/test_options.cxx b/tests/unit/sys/test_options.cxx index a9a3bf4af4..67e405953d 100644 --- a/tests/unit/sys/test_options.cxx +++ b/tests/unit/sys/test_options.cxx @@ -1439,3 +1439,14 @@ TEST_F(OptionsTest, BoolCompound) { ASSERT_TRUE(Options("true & !false").as()); ASSERT_TRUE(Options("2 > 1 & 2 < 3").as()); } + +TEST_F(OptionsTest, Iterate) { + Options option{{{"value1", 1}, {"value2", 2}}}; + + for (auto& [name, value] : option) { + value.force(value.as() + 1); + } + + ASSERT_EQ(option["value1"], 2); + ASSERT_EQ(option["value2"], 3); +}