Skip to content

Fmt wrappers (more) - #3514

Open
tomc271 wants to merge 37 commits into
nextfrom
fmt-wrappers-more
Open

tomc271 wants to merge 37 commits into
nextfrom
fmt-wrappers-more

Conversation

@tomc271

@tomc271 tomc271 commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator
  • Fix: Don't call format_as() directly
  • Rename the toString() functions generated by BOUT_ENUM_CLASS macro to format_as()
  • Replace more toString() calls with fmt::to_string()`
  • Replace {:s} with {}
  • Restore basic toString() function for Field types (and disable the fmt range formatter)
  • A few other fixes

so that {fmt} will not treat them as ranges
so that it uses `format_as()`` instead.
instead of `format_as()`
Disable the range formatter for Array, Matrix, and Tensor
(so that {fmt} will not treat them as ranges
so that it uses `format_as()`` instead).
alongside the enum class and operator<<.

This resolves ADL name lookup failures where operator<< failed to resolve the correct `format_as()` overload for namespaced enum classes.
as automatically generated by macro.
Type-specific format specifiers not always supported now that `toString()` is not being explicitly called.
Move `std::enable_if_t` to the third template parameter (Enable).
Also use `std::remove_cv_t` to ensure the trait matches const fields.
This prevents {fmt} from ignoring the custom formatter and throwing compile-time "invalid format specifier" errors.
…ustom `fmt::formatter` specializations rather than format_as overloads.
…ustom `fmt::formatter` specializations rather than format_as overloads.
Type-specific format specifiers not always supported now that `toString()` is not being explicitly called.
Include headers directly
Reorder various things
Whitespace changes
so that {fmt} will not treat them as ranges
so that it uses `format_as()`` instead.
Make it a const ref to match the definition in the header.
@dschwoerer

Copy link
Copy Markdown
Contributor

It would be nice if functions would first be deprecated for a release, before they get removed.
Would that be a lot of extra work?

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

inline std::ostream& operator<<(std::ostream& out, const enumname& e) { \
return out << toString(e); \
} \
#define BOUT_ENUM_CLASS_NS(ns, enumname, ...) \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variadic macro 'BOUT_ENUM_CLASS_NS' used; consider using a 'constexpr' variadic template function [cppcoreguidelines-macro-usage]

#define BOUT_ENUM_CLASS_NS(ns, enumname, ...)                                  \
        ^

Comment thread include/bout/difops.hxx
inline bout::FieldMetric Grad_par(const Field2D& var, CELL_LOC outloc,
DIFF_METHOD method) {
return Grad_par(var, outloc, toString(method));
return Grad_par(var, outloc, fmt::to_string(method));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::to_string" is directly included [misc-include-cleaner]

include/bout/difops.hxx:38:

- #include "bout/bout_enum_class.hxx"
+ #include "fmt/format.h"
+ #include "bout/bout_enum_class.hxx"

Comment thread include/bout/field2d.hxx
#include "bout/region.hxx"

#include "fmt/format.h"
#include <fmt/base.h>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header format.h is not used directly [misc-include-cleaner]

Suggested change
#include <fmt/base.h>
#include <fmt/base.h>

Comment thread include/bout/field2d.hxx

#include "fmt/format.h"
#include <fmt/base.h>
#include <fmt/core.h>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header base.h is not used directly [misc-include-cleaner]

Suggested change
#include <fmt/core.h>
#include <fmt/core.h>

Comment thread include/bout/field3d.hxx
#pragma once

#include "fmt/base.h"
#include "fmt/format.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header base.h is not used directly [misc-include-cleaner]

Suggested change
#include "fmt/format.h"
#include "fmt/format.h"


void printLocation(const Field3D& var) { output << toString(var.getLocation()); }
void printLocation(const Field2D& var) { output << toString(var.getLocation()); }
void printLocation(const Field3D& var) { output << fmt::to_string(var.getLocation()); }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::to_string" is directly included [misc-include-cleaner]

src/mesh/interpolation_xz.cxx:25:

- #include "parallel/fci_comm.hxx"
+ #include "fmt/format.h"
+ #include "parallel/fci_comm.hxx"

void printLocation(const Field3D& var) { output << toString(var.getLocation()); }
void printLocation(const Field2D& var) { output << toString(var.getLocation()); }
void printLocation(const Field3D& var) { output << fmt::to_string(var.getLocation()); }
void printLocation(const Field2D& var) { output << fmt::to_string(var.getLocation()); }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'printLocation' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]

Suggested change
void printLocation(const Field2D& var) { output << fmt::to_string(var.getLocation()); }
static void printLocation(const Field2D& var) { output << fmt::to_string(var.getLocation()); }

Timer time("io");
const std::string loc_string =
(location == CELL_CENTRE) ? "" : "_" + toString(location);
(location == CELL_CENTRE) ? "" : "_" + fmt::to_string(location);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "CELL_CENTRE" is directly included [misc-include-cleaner]

      (location == CELL_CENTRE) ? "" : "_" + fmt::to_string(location);
                   ^

Timer time("io");
const std::string loc_string =
(location == CELL_CENTRE) ? "" : "_" + toString(location);
(location == CELL_CENTRE) ? "" : "_" + fmt::to_string(location);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::to_string" is directly included [misc-include-cleaner]

src/mesh/parallel/shiftedmetric.cxx:8:

- #include "bout/paralleltransform.hxx"
+ #include "fmt/format.h"
+ #include "bout/paralleltransform.hxx"

output_error.write(
"acoef={:s} bcoef={:s} ccoef={:s} dcoef={:s} ecoef{:s} with {:s} at {:s} ...",
acoef, bcoef, ccoef, dcoef, ecoef, func, toString(location));
acoef, bcoef, ccoef, dcoef, ecoef, func, fmt::to_string(location));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::to_string" is directly included [misc-include-cleaner]

tests/integrated/test-invpar/test_invpar.cxx:5:

- #include <bout/bout.hxx>
+ #include "fmt/format.h"
+ #include <bout/bout.hxx>

@ZedThree

Copy link
Copy Markdown
Member

I thought the plan as discussed was to move the implementations to format_as, make toString call format_as, and then deprecate toString?

@tomc271

tomc271 commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

I thought the plan as discussed was to move the implementations to format_as, make toString call format_as, and then deprecate toString?

Yes that's right, athough I also asked about whether to try replacing the existing toString calls with fmt::to_string, and I think you said yes to that?

(Rather than calling format_as directly, I think that one is supposed to use fmt:: to_string (or fmt::format or fmt::print, etc)).

Define `Options options;` above `FieldFactory factory;` so that C++ destroys them in the correct order when the test finishes.
@ZedThree

Copy link
Copy Markdown
Member

Yes that's right, athough I also asked about whether to try replacing the existing toString calls with fmt::to_string, and I think you said yes to that?

Yes, replace the calls not the function :)

@tomc271
tomc271 marked this pull request as ready for review October 19, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants