This is an archive of the discontinued LLVM Phabricator instance.

[libc++][NFC] Format expression-equivalent wrappers consistently
ClosedPublic

Authored by ldionne on Aug 16 2021, 9:43 AM.

Details

Summary

That macro is meant to reduce duplication when writing a simple function
that is expression-equivalent to something else, where we currently use
the noexcept(noexcept(Z)) -> decltype(Z) { return Z; } pattern.

Diff Detail

Event Timeline

ldionne requested review of this revision.Aug 16 2021, 9:43 AM
ldionne created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptAug 16 2021, 9:43 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

I am not strongly attached to this change, however I wanted to put it up to answer @zoecarver 's comment in https://reviews.llvm.org/D107098#2917817.

In general I like this macro. I've written code like this too often myself. I only wonder about the new name; as non-native speaker this name doesn't feel to useful. The definition in the standard for expression-equivalent looks different http://eel.is/c++draft/defns.expression-equivalent#def:expression-equivalent.

So I wonder why is the name changed from _LIBCPP_INVOKE_RETURN to _LIBCPP_EXPRESSION_EQUIVALENT?

So I wonder why is the name changed from _LIBCPP_INVOKE_RETURN to _LIBCPP_EXPRESSION_EQUIVALENT?

The macro in <type_traits> was originally named _LIBCPP_INVOKE_RETURN because it was an implementation detail of std::invoke. But if we generalize it beyond invoke, it makes sense to name it after what it does, which is indeed to make something "expression-equivalent" in the Standard's sense (in terms of noexceptness and SFINAE-friendliness as well as the value it yields). So I think _LIBCPP_EXPRESSION_EQUIVALENT would be a fine name for it. My personal suggestion — "cute" but not at all sarcastic — is _LIBCPP_THREE_TIMES, after Vittorio Romeo's lightning talk. (It's shorter; it depicts even more explicitly what's hidden behind the macro façade; for better and worse, it eliminates the standardese jargon.)

Personally my preferences would be (from "best" to "worst":

  • Standardize on the tedious non-macro version, eliminating _LIBCPP_INVOKE_RETURN. Normalize everyone's whitespace to match what's in bind_back.h.
  • Standardize on _LIBCPP_EXPRESSION_EQUIVALENT or whatever its bikeshedded name ends up being, eliminating _LIBCPP_INVOKE_RETURN.
  • Just leave the status quo.

Even the "worst" of these is not bad at all.

There's also all the ones in __functional/operations.h, like greater_equal<void>

This doesn't seem to improve readability to me; but if it's to be done, it should be done everywhere.

There's also all the ones in __functional/operations.h, like greater_equal<void>

Thanks, fixed.

As I said, I'm not attached to this patch. In fact, I'm also not sure it increases readability. So instead, for now, I'll just make all the instances of this pattern consistent without using a macro.

Mostly for posterity: if we want to make this change in the future, we can do something like this: sed -i '' -E 's/(\s*)noexcept\(noexcept\((.+)\)\)\n\1-> decltype\( \2\)\n\1\{ return \2; \}/\1_LIBCPP_EXPRESSION_EQUIVALENT(\2)/g' $(find libcxx/include -type f) (except that sed doesn't match across lines).

ldionne updated this revision to Diff 366891.Aug 17 2021, 7:22 AM
ldionne retitled this revision from [libc++] Introduce _LIBCPP_EXPRESSION_EQUIVALENT to [libc++][NFC] Format expression-equivalent wrappers consistently.

Format consistently instead of using a macro

ldionne accepted this revision.Aug 17 2021, 9:00 AM
This revision is now accepted and ready to land.Aug 17 2021, 9:00 AM