Skip to content

Conversation

@chiphogg
Copy link
Member

@chiphogg chiphogg commented Aug 13, 2025

We tried this earlier (#491), but then reverted it (#495). That was
just a few short weeks ago: what changed?

We learned that our old format string syntax wasn't just hard to
implement; it was actually impossible. This led naturally to a new
idea
that may not be as flexible, but actually still supports the most
important use cases. Happily, this new idea is very easy to implement
without using any internal implementation details of the formatting
libraries. It even gives us a little (very little) room for evolving
more options for formatting the unit label, such as setting the fill
character, although we don't currently expect to ever need or want them.

I was also able to verify support for std::format by generating a
single file, and uploading it to godbolt. This shows that on a
compiler version and setup that includes std::format, Au supports it
via the "au/std_format.hh" header. I also updated the single-file
script to have --no-std-format (which is the default) and
--std-format options. A future PR will add versions with/without
std::format support to our automatically generated single-file
options.

On the CMake side, we need to skip linting for std_format.hh. It's
too hard and too complicated to set up reliable rules for when we should
and shouldn't make it available. Therefore, we always make it
available, but we trust that users will only include it if they know
they can support it. That's the point of the opt-in header strategy.
Note, though, that this required us to bump the minimum CMake version
from 3.24 to 3.27.

Fixes #149.

We tried this earlier (#491), but then reverted it (#495).  That was
just a few short weeks ago: what changed?

We learned that our old format string syntax wasn't just _hard_ to
implement; it was actually [impossible].  This led naturally to a [new
idea] that may not be as flexible, but actually still supports the most
important use cases.  Happily, this new idea is very easy to implement
without using any internal implementation details of the formatting
libraries.  It even gives us a little (_very_ little) room for evolving
more options for formatting the unit label, such as setting the fill
character, although we don't currently expect to ever need or want them.

I was also able to verify support for `std::format` by generating a
single file, and uploading it to [godbolt].  This shows that on a
compiler version and setup that includes `std::format`, Au supports it
out of the box with no configuration.

Overall, I feel confident enough in this solution to land it for the
0.5.0 release.  Fixes #149.

[impossible]: fmtlib/fmt#4508 (comment)
[new idea]: fmtlib/fmt#4508 (comment)
[godbolt]: https://godbolt.org/z/6jhW1jboW
@chiphogg chiphogg requested a review from Copilot August 13, 2025 11:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for string formatting of Au quantities using either the {fmt} library or C++20's std::format. The implementation provides a template-based formatter that allows customization of both the numeric value and unit label formatting.

  • Adds QuantityFormatter template to handle formatting with configurable numeric and unit label options
  • Provides automatic std::format support and instructions for {fmt} library integration
  • Includes comprehensive documentation with examples and setup instructions

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/reference/index.md Adds reference to new format support documentation
docs/reference/format.md Complete documentation for format support with examples and setup
au/quantity.hh Implements QuantityFormatter template and std::format specialization
au/fmt_test.cc Test suite for {fmt} library integration
au/BUILD.bazel Adds build target for fmt tests
WORKSPACE Adds fmt library dependency

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@chiphogg chiphogg marked this pull request as draft August 13, 2025 11:26
Copy link
Member Author

@chiphogg chiphogg left a comment

Choose a reason for hiding this comment

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

The "zero setup" version of std::format support turns out to be impossible. There will always be some build systems that scan includes such as #include <format> in order to build an include graph, regardless of any surrounding #ifdef-type preprocessor macros. If we make this design choice, we will break current or future users.

The way forward is to add a new header, "au/std_format.hh", that users can opt in and include. Only users who can support #include <format> would ever do this, so this would be a robust fix.

We also need to upgrade the single file tool to give an option for std::format support, off by default.

chiphogg and others added 2 commits August 14, 2025 16:03
Co-authored-by: Michael Hordijk <hordijk@aurora.tech>
@chiphogg
Copy link
Member Author

chiphogg commented Aug 14, 2025

For clarity (and my own convenience), here's my TODO list to get this out of draft:

  • Move the "automatic" std support into "au/std_format.hh", with no macro guards (it's opt-in)
  • Update the docs
  • Update single-file script to let people opt in to std::format support
  • Start publishing std::format versions of the single file script
  • Re-test on godbolt

@chiphogg chiphogg marked this pull request as ready for review August 16, 2025 17:46
@chiphogg chiphogg requested a review from hoffbrinkle August 16, 2025 17:46
@chiphogg chiphogg merged commit 0835a64 into main Aug 17, 2025
14 checks passed
@chiphogg chiphogg deleted the chiphogg/fmt-again#149 branch August 17, 2025 02:14
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.

Add support for fmtlib

3 participants