This patch ensures that SFINAE is used to delete assignment operators in pair and tuple based on issue 2729.
Details
Diff Detail
Event Timeline
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.
test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp | ||
---|---|---|
115 | 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 | I think it would be clearer to say NonMoveAssignable here, since this is really the property we're using. |
test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp | ||
---|---|---|
76 | 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 | You should be able to add this to make it copy-assignable: NonMoveAssignable& operator=(NonMoveAssignable const&) = default; |
test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp | ||
---|---|---|
25 | 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. |
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.
- Rebase off main
- Add tests for the remaining overloads.
- Format changes with git-clang-format.
@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 ↗ | (On Diff #325073) | 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. |
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 ↗ | (On Diff #325073) | Oh, ok, thanks a lot :-). |
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).