Skip to content

Conversation

@wgtmac
Copy link
Member

@wgtmac wgtmac commented Apr 23, 2025

  • Added std::formatter specialization for std::map, std::unordered_map and std::vector when their elements are also formattable.
  • Added std::formatter specialization for classes that have a ToString at hands.

@wgtmac wgtmac force-pushed the add_formatter branch 2 times, most recently from f30ab7f to 9dfeade Compare April 23, 2025 07:43

/// \brief std::formatter specialization for std::vector
template <typename T>
struct std::formatter<std::vector<T>> : std::formatter<std::string_view> {
Copy link
Member

Choose a reason for hiding this comment

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

FWIW, I think the "idiomatic" way is supposed to be std::format::join and ranges. I wonder if specializing on std types may come back to bite us later.

Example: https://stackoverflow.com/a/77993463

Copy link
Member

Choose a reason for hiding this comment

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

Or another example, albeit C++23: https://stackoverflow.com/a/71196142

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we need to rename this file to formatter_internal.h so we don't expose it to the downstream. In this approach, we take full control of it.

Copy link
Member

Choose a reason for hiding this comment

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

SGTM.

It might be good to expose formatter specializations on our own types, just so long as they're separate from the specializations for std types

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok I see that's what you've done.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes :)

std::map<std::string, std::vector<int>> nested_map = {
{"primes", {2, 3, 5, 7, 11}}, {"fibonacci", {1, 1, 2, 3, 5, 8, 13}}};
std::string result = std::format("{}", nested_map);
EXPECT_TRUE(result.find("primes") != std::string::npos);
Copy link
Member

Choose a reason for hiding this comment

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

Note that you can do EXPECT_THAT(result, testing::HasSubstr("primes")); which will also give a much better error on failure

}

// Format key (handle if it's a smart pointer)
if constexpr (requires { *key; }) {
Copy link
Member

Choose a reason for hiding this comment

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

Won't this also fire on something like std::optional that might be undesirable?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've modified the concept to strictly check smart pointer type.

@wgtmac
Copy link
Member Author

wgtmac commented Apr 23, 2025

I've moved specialization for std containers to the internal header file to not pollute downstream. Let me know what you think @lidavidm

@lidavidm
Copy link
Member

LGTM

Copy link
Collaborator

@zhjwpku zhjwpku left a comment

Choose a reason for hiding this comment

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

Impressive, I used chatgpt to help me understanding the C++20 std::views::transform, thanks for working on this.

Copy link
Contributor

@yingcai-cy yingcai-cy left a comment

Choose a reason for hiding this comment

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

Good job!

@Fokko Fokko merged commit 60bff25 into apache:main Apr 23, 2025
6 checks passed
@Fokko
Copy link
Contributor

Fokko commented Apr 23, 2025

Thanks @wgtmac for working on this, and thanks @lidavidm, @zhjwpku and @yingcai-cy for the review 🙌

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.

5 participants