This is an archive of the discontinued LLVM Phabricator instance.

SFINAE on pair/tuple assignment operators 2729
ClosedPublic

Authored by zoecarver on May 25 2019, 12:11 PM.

Details

Reviewers
mclow.lists
ldionne
Group Reviewers
Restricted Project
Summary

This patch ensures that SFINAE is used to delete assignment operators in pair and tuple based on issue 2729.

Diff Detail

Event Timeline

zoecarver created this revision.May 25 2019, 12:11 PM
EricWF added a subscriber: EricWF.May 25 2019, 5:42 PM

We should already have tests for this.

And you should only write fail.cpp tests when there is absolutely no other way to test the behavior.
In this case it can be tested with a passing test and type traits.

zoecarver updated this revision to Diff 203178.Jun 5 2019, 9:20 AM
  • remove fail tests
  • update pass tests
ldionne requested changes to this revision.Jun 12 2019, 1:45 PM
ldionne added inline comments.
test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
115 ↗(On Diff #203178)

I think you'd be testing the same thing if you said !std::is_assignable<T, P const>::value, but the intent might be clearer. What do you think?

You could also use T& instead to clear up any impression that this matters to the test (I had to think about it).

test/std/utilities/tuple/tuple.tuple/tuple.assign/move_pair.pass.cpp
40 ↗(On Diff #203178)

I think it would be clearer to say NonMoveAssignable here, since this is really the property we're using.

This revision now requires changes to proceed.Jun 12 2019, 1:45 PM
zoecarver updated this revision to Diff 204401.Jun 12 2019, 5:43 PM
  • change name of helper struct
  • update constness and value type of type trait

@ldionne updated based on your review. Does this look good now?

ldionne requested changes to this revision.Oct 30 2019, 11:22 AM
ldionne added inline comments.
test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
76 ↗(On Diff #204401)

Why don't you keep the old check for static_assert(!std::is_copy_assignable<P>::value, ""); too?

test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
25 ↗(On Diff #204401)

You should be able to add this to make it copy-assignable:

NonMoveAssignable& operator=(NonMoveAssignable const&) = default;
This revision now requires changes to proceed.Oct 30 2019, 11:22 AM
zoecarver marked an inline comment as done.Dec 9 2019, 9:09 PM
zoecarver added inline comments.
test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
25 ↗(On Diff #204401)

Hmm you're right but that unfortunatly fails the test !std::is_move_assignable<std::pair<int, NonMoveAssignable>>::value. I'll look into fixing it.

  • Rebase off main
  • Remove changes to unrelated tests
Herald added a project: Restricted Project. · View Herald TranscriptFeb 17 2021, 11:07 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne requested changes to this revision.Feb 17 2021, 11:47 AM

So you added tests for std::tuple::operator=(std::pair const&) and std::tuple::operator=(std::pair&&), but not for:

  • pair& operator=(const pair& p);
  • template<class U, class V> pair& operator=(const pair<U, V>& p);
  • pair& operator=(pair&& p) noexcept(see below);
  • template<class U, class V> pair& operator=(pair<U, V>&& p);
  • tuple& operator=(const tuple& u);
  • tuple& operator=(tuple&& u) noexcept(see below);
  • template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
  • template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);

The list is taken from the issue you linked. Is it because those constructors are already tested in these cases?

Also, the LWG issue says:

std::is_copy_assignable<std::pair<int, std::unique_ptr<int>>>::value is true, and should be false.

Can you please add a test with unique_ptr to the tests for the constructors that should support it? I'm a big fan of just copy-pasting simple things that we know should work properly and test that they do indeed work as intended. This avoids bad surprises.

This revision now requires changes to proceed.Feb 17 2021, 11:47 AM
zoecarver updated this revision to Diff 325073.Feb 19 2021, 1:02 PM
  • Rebase off main
  • Add tests for the remaining overloads.
  • Format changes with git-clang-format.
zoecarver updated this revision to Diff 325076.Feb 19 2021, 1:10 PM
  • Add test in const_pair.pass.cpp (missed in original pass).

@ldionne sorry about that. I don't know how I overlooked the majority of the issue. Anyway, I've made sure that all the overloads have a test now.

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
108–110

This is just to mark where we have existing test coverage for this issue (to make it easier to review). I'll remove these comments when I commit.

ldionne accepted this revision.Feb 19 2021, 1:15 PM

@ldionne sorry about that. I don't know how I overlooked the majority of the issue. Anyway, I've made sure that all the overloads have a test now.

Meh, no worries! Thanks a lot for adding the missing tests.

Shiiiiip it!

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
108–110

Oh, ok, thanks a lot :-).

This revision is now accepted and ready to land.Feb 19 2021, 1:15 PM
zoecarver closed this revision.Feb 19 2021, 1:26 PM