diff --git a/include/bout/boutexception.hxx b/include/bout/boutexception.hxx index 565eb6b46d..d525aeb608 100644 --- a/include/bout/boutexception.hxx +++ b/include/bout/boutexception.hxx @@ -21,7 +21,7 @@ public: template BoutException(S&& format, Args&&... args) - : BoutException(fmt::format(std::forward(format), + : BoutException(fmt::format(fmt::runtime(std::forward(format)), std::forward(args)...)) {} ~BoutException() override; @@ -46,7 +46,7 @@ public: BoutRhsFail(std::string message) : BoutException(std::move(message)) {} template BoutRhsFail(S&& format, Args&&... args) - : BoutRhsFail(fmt::format(std::forward(format), + : BoutRhsFail(fmt::format(fmt::runtime(std::forward(format)), std::forward(args)...)) {} }; @@ -55,7 +55,7 @@ public: BoutIterationFail(std::string message) : BoutException(std::move(message)) {} template BoutIterationFail(S&& format, Args&&... args) - : BoutIterationFail(fmt::format(std::forward(format), + : BoutIterationFail(fmt::format(fmt::runtime(std::forward(format)), std::forward(args)...)) {} }; diff --git a/include/bout/msg_stack.hxx b/include/bout/msg_stack.hxx index 1abb26d2c7..8771aeab42 100644 --- a/include/bout/msg_stack.hxx +++ b/include/bout/msg_stack.hxx @@ -62,7 +62,7 @@ public: template int push(const S& format, const Args&... args) { - return push(fmt::format(format, args...)); + return push(fmt::format(fmt::runtime(format), args...)); } void pop(); ///< Remove the last message @@ -134,8 +134,8 @@ public: template MsgStackItem(const std::string& file, int line, const S& msg, const Args&... args) - : point(msg_stack.push("{:s} on line {:d} of '{:s}'", fmt::format(msg, args...), - line, file)) {} + : point(msg_stack.push("{:s} on line {:d} of '{:s}'", + fmt::format(fmt::runtime(msg), args...), line, file)) {} ~MsgStackItem() { // If an exception has occurred, don't pop the message if (exception_count == std::uncaught_exceptions()) { diff --git a/include/bout/optionsreader.hxx b/include/bout/optionsreader.hxx index de3d40514d..0c9c227916 100644 --- a/include/bout/optionsreader.hxx +++ b/include/bout/optionsreader.hxx @@ -71,7 +71,7 @@ public: template void read(Options* options, const S& format, const Args&... args) { - return read(options, fmt::format(format, args...)); + return read(options, fmt::format(fmt::runtime(format), args...)); } /// Write options to file @@ -82,7 +82,7 @@ public: template void write(Options* options, const S& format, const Args&... args) { - return write(options, fmt::format(format, args...)); + return write(options, fmt::format(fmt::runtime(format), args...)); } /// Parse options from the command line diff --git a/include/bout/output.hxx b/include/bout/output.hxx index 34b4f19376..4eb1d615ca 100644 --- a/include/bout/output.hxx +++ b/include/bout/output.hxx @@ -83,7 +83,8 @@ public: template Output(const S& format, Args&&... args) - : Output(fmt::format(format, std::forward(args)...)) {} + : Output(fmt::format(fmt::runtime(format), std::forward(args)...)) { + } ~Output() override { close(); } @@ -95,7 +96,7 @@ public: template int open(const S& format, Args&&... args) { - return open(fmt::format(format, std::forward(args)...)); + return open(fmt::format(fmt::runtime(format), std::forward(args)...)); } /// Close the log file @@ -106,14 +107,14 @@ public: template void write(const S& format, Args&&... args) { - write(fmt::format(format, std::forward(args)...)); + write(fmt::format(fmt::runtime(format), std::forward(args)...)); } /// Same as write, but only to screen virtual void print(const std::string& message); template void print(const S& format, Args&&... args) { - print(fmt::format(format, std::forward(args)...)); + print(fmt::format(fmt::runtime(format), std::forward(args)...)); } /// Add an output stream. All output will be sent to all streams @@ -178,7 +179,8 @@ public: void write(const S& format, Args&&... args) { if (enabled) { ASSERT1(base != nullptr); - base->write(fmt::format(format, std::forward(args)...)); + base->write( + fmt::format(fmt::runtime(format), std::forward(args)...)); } } @@ -190,7 +192,8 @@ public: void print(const S& format, Args&&... args) { if (enabled) { ASSERT1(base != nullptr); - base->print(fmt::format(format, std::forward(args)...)); + base->print( + fmt::format(fmt::runtime(format), std::forward(args)...)); } } diff --git a/include/bout/sys/expressionparser.hxx b/include/bout/sys/expressionparser.hxx index b312ce2fb1..78525e5b69 100644 --- a/include/bout/sys/expressionparser.hxx +++ b/include/bout/sys/expressionparser.hxx @@ -243,7 +243,7 @@ public: template ParseException(const S& format, const Args&... args) - : message(fmt::format(format, args...)) {} + : message(fmt::format(fmt::runtime(format), args...)) {} ~ParseException() override = default; diff --git a/include/bout/utils.hxx b/include/bout/utils.hxx index 04aa0b281d..560f97f954 100644 --- a/include/bout/utils.hxx +++ b/include/bout/utils.hxx @@ -186,6 +186,7 @@ typename std::vector::size_type erase_if(std::vector& c, Pre return r; } #else +using std::erase; using std::erase_if; #endif } // namespace utils diff --git a/src/bout++.cxx b/src/bout++.cxx index d6888874c6..4ca4d352ca 100644 --- a/src/bout++.cxx +++ b/src/bout++.cxx @@ -324,7 +324,7 @@ template // type. Note that this does require all the options are used in the // constructor, and not in a `init` method or similar std::cout << fmt::format("Input options for {} '{}':\n\n", Factory::type_name, type); - std::cout << fmt::format("{:id}\n", help_options); + std::cout << fmt::format(fmt::runtime("{:id}\n"), help_options); std::exit(EXIT_SUCCESS); } diff --git a/src/mesh/impls/bout/boutmesh.cxx b/src/mesh/impls/bout/boutmesh.cxx index 4be01d4637..3ba16b5f2f 100644 --- a/src/mesh/impls/bout/boutmesh.cxx +++ b/src/mesh/impls/bout/boutmesh.cxx @@ -163,14 +163,16 @@ CheckMeshResult checkBoutMeshYDecomposition(int num_y_processors, int ny, // Check size of Y mesh if we've got multiple processors in Y if (num_local_y_points < num_y_guards and num_y_processors != 1) { return {false, - fmt::format(_("\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n"), ny, - num_y_processors, num_local_y_points, num_y_guards)}; + fmt::format(fmt::runtime(_( + "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n")), + ny, num_y_processors, num_local_y_points, num_y_guards)}; } // Check branch cuts if ((jyseps1_1 + 1) % num_local_y_points != 0) { - return {false, fmt::format(_("\t -> Leg region jyseps1_1+1 ({:d}) must be a " - "multiple of MYSUB ({:d})\n"), - jyseps1_1 + 1, num_local_y_points)}; + return {false, + fmt::format(fmt::runtime(_("\t -> Leg region jyseps1_1+1 ({:d}) must be a " + "multiple of MYSUB ({:d})\n")), + jyseps1_1 + 1, num_local_y_points)}; } if (jyseps2_1 != jyseps1_2) { @@ -179,50 +181,57 @@ CheckMeshResult checkBoutMeshYDecomposition(int num_y_processors, int ny, if ((jyseps2_1 - jyseps1_1) % num_local_y_points != 0) { return { false, - fmt::format(_("\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must " - "be a multiple of MYSUB ({:d})\n"), + fmt::format(fmt::runtime(_( + "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must " + "be a multiple of MYSUB ({:d})\n")), jyseps2_1, jyseps1_1, jyseps2_1 - jyseps1_1, num_local_y_points)}; } if ((jyseps2_2 - jyseps1_2) % num_local_y_points != 0) { return { false, - fmt::format(_("\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must " - "be a multiple of MYSUB ({:d})\n"), + fmt::format(fmt::runtime(_( + "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must " + "be a multiple of MYSUB ({:d})\n")), jyseps2_2, jyseps1_2, jyseps2_2 - jyseps1_2, num_local_y_points)}; } // Check upper legs if ((ny_inner - jyseps2_1 - 1) % num_local_y_points != 0) { - return { - false, - fmt::format(_("\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must " - "be a multiple of MYSUB ({:d})\n"), - ny_inner, jyseps2_1, ny_inner - jyseps2_1 - 1, num_local_y_points)}; + return {false, + fmt::format( + fmt::runtime( + _("\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must " + "be a multiple of MYSUB ({:d})\n")), + ny_inner, jyseps2_1, ny_inner - jyseps2_1 - 1, num_local_y_points)}; } if ((jyseps1_2 - ny_inner + 1) % num_local_y_points != 0) { - return { - false, - fmt::format(_("\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must " - "be a multiple of MYSUB ({:d})\n"), - jyseps1_2, ny_inner, jyseps1_2 - ny_inner + 1, num_local_y_points)}; + return {false, + fmt::format( + fmt::runtime( + _("\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must " + "be a multiple of MYSUB ({:d})\n")), + jyseps1_2, ny_inner, jyseps1_2 - ny_inner + 1, num_local_y_points)}; } } else { // Single Null if ((jyseps2_2 - jyseps1_1) % num_local_y_points != 0) { return { false, - fmt::format(_("\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must " - "be a multiple of MYSUB ({:d})\n"), + fmt::format(fmt::runtime(_( + "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must " + "be a multiple of MYSUB ({:d})\n")), jyseps2_2, jyseps1_1, jyseps2_2 - jyseps1_1, num_local_y_points)}; } } if ((ny - jyseps2_2 - 1) % num_local_y_points != 0) { - return {false, fmt::format( - _("\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a " - "multiple of MYSUB ({:d})\n"), - ny, jyseps2_2, ny - jyseps2_2 - 1, num_local_y_points)}; + return { + false, + fmt::format(fmt::runtime(_( + "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a " + "multiple of MYSUB ({:d})\n")), + ny, jyseps2_2, ny - jyseps2_2 - 1, num_local_y_points)}; } return {true, ""}; diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index b5ea01d231..eff2de2e1f 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -1,7 +1,6 @@ #include #include #include -#include #include @@ -11,7 +10,6 @@ #include #include -#include #include diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index 804f371bbe..1c381b26df 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -327,13 +327,15 @@ may need to change your input file. // No matches, just point out the error if (possible_matches.empty()) { - return fmt::format(message_template, name, problem_bit); + return fmt::format(fmt::runtime(message_template), name, problem_bit); } // Give the first suggestion as a possible alternative - std::string error_message = fmt::format(message_template, name, problem_bit); - error_message += fmt::format(_("\n {1: ^{2}}{0}\n Did you mean '{0}'?"), - possible_matches.begin()->name, "", start); + std::string error_message = + fmt::format(fmt::runtime(message_template), name, problem_bit); + error_message += + fmt::format(fmt::runtime(_("\n {1: ^{2}}{0}\n Did you mean '{0}'?")), + possible_matches.begin()->name, "", start); return error_message; }; diff --git a/src/sys/options.cxx b/src/sys/options.cxx index bb4c920b90..fb90868081 100644 --- a/src/sys/options.cxx +++ b/src/sys/options.cxx @@ -760,8 +760,9 @@ T as_amt(const Options& self, const T& similar_to) { const T result = bout::utils::visit( ConvertContainer{ - fmt::format(_("Value for option {:s} cannot be converted to an {}"), self.str(), - bout::utils::typeName()), + fmt::format( + fmt::runtime(_("Value for option {:s} cannot be converted to an {}")), + self.str(), bout::utils::typeName()), similar_to}, self.value); @@ -1098,20 +1099,22 @@ bout::details::OptionsFormatterBase::format(const Options& options, // Get all the child values first for (const auto& child : children) { if (child.second.isValue()) { - fmt::format_to(ctx.out(), format_string, child.second); + fmt::format_to(ctx.out(), fmt::runtime(format_string), child.second); fmt::format_to(ctx.out(), "\n"); } } // Now descend the tree, accumulating subsections for (const auto& subsection : options.subsections()) { - fmt::format_to(ctx.out(), format_string, *subsection.second); + fmt::format_to(ctx.out(), fmt::runtime(format_string), *subsection.second); } return ctx.out(); } -std::string toString(const Options& value) { return fmt::format("{}", value); } +std::string toString(const Options& value) { + return fmt::format(fmt::runtime("{}"), value); +} namespace bout { void checkForUnusedOptions() { @@ -1157,7 +1160,7 @@ void checkForUnusedOptions(const Options& options, const std::string& data_dir, } possible_misspellings += fmt::format("\nUnused option '{}', did you mean:\n", key); for (const auto& match : fuzzy_matches) { - possible_misspellings += fmt::format("\t{:idk}\n", match.match); + possible_misspellings += fmt::format(fmt::runtime("\t{:idk}\n"), match.match); } } diff --git a/src/sys/options/options_ini.cxx b/src/sys/options/options_ini.cxx index 939e100f1b..b51af8fdcf 100644 --- a/src/sys/options/options_ini.cxx +++ b/src/sys/options/options_ini.cxx @@ -157,7 +157,7 @@ void OptionINI::write(Options* options, const std::string& filename) { } // Call recursive function to write to file - fout << fmt::format("{:uds}", *options); + fout << fmt::format(fmt::runtime("{:uds}"), *options); fout.close(); } diff --git a/tests/unit/fake_mesh.hxx b/tests/unit/fake_mesh.hxx index 2feb43826d..e42c6bb5c0 100644 --- a/tests/unit/fake_mesh.hxx +++ b/tests/unit/fake_mesh.hxx @@ -231,18 +231,17 @@ public: "RGN_OUTER_X"}; // Sum up and get unique points in the boundaries defined above - addRegion2D("RGN_BNDRY", - std::accumulate(begin(boundary_names), end(boundary_names), - Region{}, - [this](Region& a, const std::string& b) { - return a + getRegion2D(b); - }) - .unique()); + addRegion2D("RGN_BNDRY", std::accumulate(begin(boundary_names), end(boundary_names), + Region{}, + [&](Region a, const std::string& b) { + return a + getRegion2D(b); + }) + .unique()); addRegion3D("RGN_BNDRY", std::accumulate(begin(boundary_names), end(boundary_names), Region{}, - [this](Region& a, const std::string& b) { + [this](Region a, const std::string& b) { return a + getRegion3D(b); }) .unique()); diff --git a/tests/unit/sys/test_options.cxx b/tests/unit/sys/test_options.cxx index b74cfdcb9f..f0256b6aa7 100644 --- a/tests/unit/sys/test_options.cxx +++ b/tests/unit/sys/test_options.cxx @@ -1099,7 +1099,9 @@ value6 = 12 } TEST_F(OptionsTest, InvalidFormat) { - EXPECT_THROW([[maybe_unused]] auto none = fmt::format("{:nope}", Options{}), fmt::format_error); + EXPECT_THROW([[maybe_unused]] auto none = + fmt::format(fmt::runtime("{:nope}"), Options{}), + fmt::format_error); } TEST_F(OptionsTest, FormatValue) { @@ -1110,7 +1112,7 @@ TEST_F(OptionsTest, FormatValue) { const std::string expected = "value1 = 4 # type: int, doc: This is a value, source: some test"; - EXPECT_EQ(expected, fmt::format("{:ds}", options["value1"])); + EXPECT_EQ(expected, fmt::format(fmt::runtime("{:ds}"), options["value1"])); } TEST_F(OptionsTest, FormatDefault) { @@ -1138,7 +1140,7 @@ value4 = 3.2 value6 = 12 )"; - EXPECT_EQ(fmt::format("{}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{}"), option), expected); } TEST_F(OptionsTest, FormatDocstrings) { @@ -1169,7 +1171,7 @@ value4 = 3.2 value6 = 12 )"; - EXPECT_EQ(fmt::format("{:d}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:d}"), option), expected); } TEST_F(OptionsTest, FormatDocstringsAndInline) { @@ -1192,9 +1194,9 @@ section2:subsection1:value4 = 3.2 section3:subsection2:value6 = 12 )"; - EXPECT_EQ(fmt::format("{:di}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:di}"), option), expected); // Order of format spec shouldn't matter - EXPECT_EQ(fmt::format("{:id}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:id}"), option), expected); } TEST_F(OptionsTest, FormatDocstringsAndInlineKeysOnly) { @@ -1219,16 +1221,16 @@ section2:subsection1:value4 section3:subsection2:value6 # source: a test )"; - EXPECT_EQ(fmt::format("{:ksdi}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:ksdi}"), option), expected); // Order of format spec shouldn't matter - EXPECT_EQ(fmt::format("{:idsk}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:idsk}"), option), expected); } TEST_F(OptionsTest, FormatUnused) { Options option{{"section1", {{"value1", 42}}}}; std::string expected = "section1:value1\t\t# unused value (NOT marked conditionally used)\n"; - EXPECT_EQ(fmt::format("{:iku}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:iku}"), option), expected); } TEST_F(OptionsTest, FormatConditionallyUsed) { @@ -1236,7 +1238,7 @@ TEST_F(OptionsTest, FormatConditionallyUsed) { option.setConditionallyUsed(); std::string expected = "section1:value1\t\t# unused value (marked conditionally used)\n"; - EXPECT_EQ(fmt::format("{:iku}", option), expected); + EXPECT_EQ(fmt::format(fmt::runtime("{:iku}"), option), expected); } TEST_F(OptionsTest, GetUnused) {