This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Introduce __identity_t<T>
ClosedPublic

Authored by Quuxplusone on Mar 3 2021, 8:20 AM.

Details

Reviewers
zoecarver
ldionne
curdeius
Group Reviewers
Restricted Project
Commits
rG09fa1d0e50a3: [libc++] Introduce __identity_t<T>. NFCI.
Summary

This is just a shorter synonym for __identity<T>::type.
Use it consistently throughout, where possible.

There is still some metaprogramming in <memory> and <variant>
where __identity is being used _without_ immediately calling
::type on it; but this is the unusual case, and it will become
even less usual as we start deliberately protecting certain types
against deduction (e.g. D97742).

(Btw, I've really looked at the instances in <memory> and I think they cannot trivially be adjusted to use __identity_t; it's using __dependent_type<__identity<T>, Dummy>::type and thus relying on the fact that __identity<T> is non-final even when T is final. I have not really looked at the instances in <variant>; I think it's using __identity<T> as an empty tag type for dispatch, similar to in_place_type_t<T>, but I'm not technically 100% sure.)

Diff Detail

Event Timeline

Quuxplusone requested review of this revision.Mar 3 2021, 8:20 AM
Quuxplusone created this revision.
Herald added a reviewer: Restricted Project. · View Herald TranscriptMar 3 2021, 8:20 AM
Quuxplusone added inline comments.Mar 3 2021, 8:22 AM
libcxx/include/type_traits
4046

(The first diff here is to eliminate a "noise" use of __identity where IMHO it's not really serving any purpose. The second and third diffs are for consistency of style between __result_of_mp and __result_of_mdp.)

curdeius accepted this revision.Mar 3 2021, 12:58 PM
curdeius added a subscriber: curdeius.

LGTM given that all the compilers support alias templates in C++03 mode, which seems to be the case for clang at least.

ldionne accepted this revision.Mar 3 2021, 1:33 PM

LGTM too. I don't understand why those are needed at all though, but Clang does fail to pass the tests if I remove them. So ship it.

This revision is now accepted and ready to land.Mar 3 2021, 1:33 PM

LGTM. I really liked _Ident<T> but I think your rationale in D97742 is correct.

zoecarver accepted this revision.Mar 3 2021, 2:31 PM

This is non-blocking, however I think it might be nicer to use __identity_t on the arguments of the constructors that need them instead of on the typedefs. Otherwise, it's really unclear *why* this convolution is needed. So for example, you could have

unordered_multiset(size_type __n, const __identity_t<allocator_type>& __a)
        : unordered_multiset(__n, hasher(), key_equal(), __a) {}

Feel free to do it now, do it later, or not do it at all.

Quuxplusone added inline comments.Mar 3 2021, 7:22 PM
libcxx/include/map
908

@ldionne wrote:

This is non-blocking, however I think it might be nicer to use __identity_t on the arguments of the constructors that need them instead of on the typedefs. Otherwise, it's really unclear why this convolution is needed.

I agree, but when I started trying to do that, I immediately ran into existing implementation divergence; see https://godbolt.org/z/bxhn84 (libstdc++ rejects, libc++ and MSVC accept) and my tonight's LWG reflector thread "P1518 redux: CTAD deducing Allocator/Compare from random constructors". I definitely think the libc++/MSVC behavior is the "correct" behavior, so I'd want to preserve it, even if it means putting __identity_t on more ctor arguments than the paper standard currently mandates.

But now that's a feature-ish enough change that I'm gonna just land this "NFCI" commit as-is, and open a different PR if I decide it's worth doing anything else (which I still might, but it's no longer a slam-dunk).

This revision was landed with ongoing or failed builds.Mar 3 2021, 7:24 PM
This revision was automatically updated to reflect the committed changes.
ldionne added inline comments.Mar 4 2021, 4:49 AM
libcxx/include/map
908

Okay, I agree with that. Thanks for keeping changes small and separated!