This is an archive of the discontinued LLVM Phabricator instance.

[libc++] P0433R2: add the remaining deduction guides.
ClosedPublic

Authored by var-const on Oct 25 2021, 9:03 PM.

Details

Summary

Add deduction guides to valarray and scoped_allocator_adaptor. This largely
finishes implementation of the paper:

  • deduction guides for other classes mentioned in the paper were implemented previously (see the list below);
  • deduction guides for several classes contained in the proposal (reference_wrapper, lock_guard, scoped_lock, unique_lock, shared_lock) were removed by LWG2981.

Also add deduction guides to the synopsis for the few classes (e.g. pair)
where they were missing.

The only part of the paper that isn't fully implemented after this patch is
making sure certain deduction guides don't participate in overload resolution
when given incorrect template parameters.

List of significant commits implementing the other parts of P0433 (omitting some
minor fixes):

Additional notes:

  • It was revision 2 of the paper that was voted into the Standard. P0433R3 is a separate paper that is not part of the Standard.
  • The paper also mandates removing several make_*_searcher functions (e.g. make_boyer_moore_searcher) which are currently not implemented (except in experimental/).
  • The __cpp_lib_deduction_guides feature test macro from the paper was accidentally omitted from the Standard.

Diff Detail

Event Timeline

var-const requested review of this revision.Oct 25 2021, 9:03 PM
var-const created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptOct 25 2021, 9:03 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
var-const edited the summary of this revision. (Show Details)Oct 25 2021, 9:05 PM
var-const edited the summary of this revision. (Show Details)
var-const edited the summary of this revision. (Show Details)
var-const edited the summary of this revision. (Show Details)Oct 25 2021, 9:07 PM
var-const added a reviewer: ldionne.
var-const edited the summary of this revision. (Show Details)
var-const edited the summary of this revision. (Show Details)Oct 25 2021, 9:10 PM
Quuxplusone requested changes to this revision.Oct 26 2021, 7:00 AM
Quuxplusone added a subscriber: Quuxplusone.

Thanks for working on this!

libcxx/docs/Status/Cxx17.rst
43

I assume you've basically done the work already to figure out which guides you're talking about; could you specify that exact list right here? (Or even better, make a second PR that just fixes them ;))

libcxx/include/valarray
1086

Please line-break between > and valarray.

libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp
22–29

Instead of these three tests, I'd rather see these seven tests (to hit all the expected CTAD codepaths):

{
    std::valarray v = {1, 2, 3, 4, 5};  // from initializer_list<T>
    ASSERT_SAME_TYPE(decltype(v), std::valarray<int>);
}
{
    long a[] = {1, 2, 3, 4, 5};
    std::valarray v(a, 5);  // from const T(&)[N], size_t
    ASSERT_SAME_TYPE(decltype(v), std::valarray<long>);
}
{
    long a[] = {1, 2, 3, 4, 5};
    std::valarray v(&a[0], 5);  // from const T&, size_t
    ASSERT_SAME_TYPE(decltype(v), std::valarray<long*>);  // surprising but true
}
{
    std::valarray<long> v {1,2,3,4,5};
    std::valarray v2 = v[std::slice(2,5,1)];  // from slice_array<T>
    static_assert(std::is_same_v<decltype(v2), std::valarray<long>>);
}
{
    std::valarray<long> v {1,2,3,4,5};
    std::valarray v2 = v[std::gslice(0, {5}, {1})];  // from gslice_array<T>
    static_assert(std::is_same_v<decltype(v2), std::valarray<long>>);
}
{
    std::valarray<long> v = {1, 2, 3, 4, 5};
    std::valarray<bool> m = {true, false, true, false, true};
    std::valarray v2 = v[m];  // from mask_array<T>
    static_assert(std::is_same_v<decltype(v2), std::valarray<long>>);
}
{
    std::valarray<long> v = {1, 2, 3, 4, 5};
    std::valarray<size_t> i = {1, 2, 3};
    std::valarray v2 = v[i];  // from indirect_array<T>
    static_assert(std::is_same_v<decltype(v2), std::valarray<long>>);
}
libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/deduct.pass.cpp
30

Here and throughout, please check the actual type of a:

ASSERT_SAME_TYPE(decltype(a), std::scoped_allocator_adaptor<OuterAlloc>);

Checking the nested ::outer_allocator_type typedef isn't quite as good; and although checking both would be harmless, it also wouldn't be helpful. All we really care about in this specific test file is that CTAD produces the exactly correct scoped_allocator_adaptor<...> type; the existence/values of these nested typedefs can (and should already be) tested elsewhere.

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
40–65

FWIW, these three new tests strike me as redundant with line 35 (which itself — pre-existing — is already redundant with line 27).

This revision now requires changes to proceed.Oct 26 2021, 7:00 AM
ldionne added inline comments.Oct 26 2021, 8:58 AM
libcxx/docs/Status/Cxx17.rst
43

I think @var-const 's intent was to come back and fix them in a future PR. The guides he's talking about here are things like SFINAEing unordered_map guides away when the provided iterator is not an input iterator. We have a couple such guides that are not 100% correctly implemented.

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
40–65

IMO those are all relevant. The const T& one makes sure that we handle references correctly, the T* one that we handle pointers correctly, and the T[] one that arrays will cause the deduction guide to deduce an optional pointer.

Sure, when you know how it's implemented you realize that it's obvious it's going to work, but if you don't know how the deduction guide is implemented, IMO these test cases are useful.

var-const updated this revision to Diff 382516.Oct 26 2021, 8:50 PM
var-const marked 2 inline comments as done.
  • address feedback;
  • don't define the deduction guides for language versions below C++17.
libcxx/docs/Status/Cxx17.rst
43

There is a requirement for all containers that deduction guides should not participate in overload resolution when the given types do not qualify as input iterators / allocators / comparators / hash functors. This requirement is largely untested and I think in some cases not fully implemented. There is also a requirement that a unique_ptr cannot be deduced from a plain pointer (to prevent a case where deducing from a built-in array would also deduce a pointer) -- it's implemented correctly but not tested.

I thought that listing all of this would be a little too much detail, and I'm indeed working on addressing those in a follow-up, so I thought it's okay to be a little more vague in the description. Please let me know if you'd still like to expand the description.

libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp
22–29

Thanks a lot! Added.

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
40–65

@Quuxplusone Arthur, please let me know if you feel strongly about removing these. I'm slightly inclined to keep these tests (my intention was pretty much what Louis described), but I'm ok to remove them.

LGTM!

libcxx/docs/Status/Cxx17.rst
43

If there's a chance someone else will have to do the work later, then it's important to have a really good and unambiguous TODO list here. But if you're just holding the list in your head while you actively do the work, then this is fine.
It sounds like the latter is the case; therefore I'm OK with this.

libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp
46

ASAN rightly complains because I forgot that the second argument is "size", not "end". Make this std::slice(2,3,1) and I think it'll be quiet.

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
40–65

Personally I do still think they're unneeded; but Louis' preference overrules mine. Keep.

ldionne accepted this revision.Oct 27 2021, 8:00 AM
This revision is now accepted and ready to land.Oct 27 2021, 8:00 AM

Fix the Asan issue.

var-const marked an inline comment as done.Oct 27 2021, 11:22 PM
var-const added inline comments.
libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp
46

Done, thanks.

This revision was automatically updated to reflect the committed changes.
var-const marked an inline comment as done.