Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow format_as() to format reference #3739

Merged
merged 1 commit into from
Dec 10, 2023
Merged

Conversation

tchaikov
Copy link
Contributor

@tchaikov tchaikov commented Dec 8, 2023

before this change, format_as() is unable to format a type which has auto format_as() -> const another_type&, and another_type is formattable. because format_as_result maps the result type as it is, and the compiler refuses to compile
static_cast<T*>(nullptr), where T is a reference type. but it would be handy if we could use format_as() to format types which, for instance, owns / inherit from a formattable type, and delegate the formatter to these variables instead without creating a copy of them.

in this change:

  • instruct format_as_result to map the result type to the decayed type, so that type can be the decayed type of result type, and this also enables type to be formattable, as long as the decayed type is formattable.
  • corresponding test is added to format-test.cc

Copy link
Contributor

@vitaut vitaut left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

@@ -1332,7 +1332,7 @@ using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
template <typename T> struct format_as_result {
template <typename U,
FMT_ENABLE_IF(std::is_enum<U>::value || std::is_class<U>::value)>
static auto map(U*) -> decltype(format_as(std::declval<U>()));
static auto map(U*) -> typename std::decay<decltype(format_as(std::declval<U>()))>::type;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be remove_cvref_t and not decay.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes. it's a better fit in this case.

struct struct_as_const_reference {
const std::string name = "foo";
};
auto format_as(const struct_as_const_reference& s) -> const std::string& { return s.name; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Please apply clang-format.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure.

@tchaikov
Copy link
Contributor Author

v2:

  • s/std::decay/remove_cvref_t/
  • clang-format the change.

before this change, format_as() is unable to format a type which
has `auto format_as() -> const another_type&`, and `another_type`
is formattable. because `format_as_result` maps the result type
as it is, and the compiler refuses to compile
`static_cast<T*>(nullptr)`, where T is a reference type. but
it would be handy if we could use `format_as()` to format types
which, for instance, owns / inherit from a formattable type, and
delegate the formatter to these variables instead without creating
a copy of them.

in this change:

* instruct `format_as_result` to map the
  result type to the decayed type, so that `type` can be the decayed
  type of result type, and this also enables `type` to be formattable,
  as long as the decayed type is formattable.
* corresponding test is added to format-test.cc

Signed-off-by: Kefu Chai <[email protected]>
@vitaut vitaut merged commit 274ba26 into fmtlib:master Dec 10, 2023
40 checks passed
@vitaut
Copy link
Contributor

vitaut commented Dec 10, 2023

Merged, thanks!

@tchaikov tchaikov deleted the format-as branch December 11, 2023 02:07
happymonkey1 pushed a commit to happymonkey1/fmt that referenced this pull request Apr 7, 2024
before this change, format_as() is unable to format a type which
has `auto format_as() -> const another_type&`, and `another_type`
is formattable. because `format_as_result` maps the result type
as it is, and the compiler refuses to compile
`static_cast<T*>(nullptr)`, where T is a reference type. but
it would be handy if we could use `format_as()` to format types
which, for instance, owns / inherit from a formattable type, and
delegate the formatter to these variables instead without creating
a copy of them.

in this change:

* instruct `format_as_result` to map the
  result type to the decayed type, so that `type` can be the decayed
  type of result type, and this also enables `type` to be formattable,
  as long as the decayed type is formattable.
* corresponding test is added to format-test.cc

Signed-off-by: Kefu Chai <[email protected]>
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.

2 participants