[PATCH] D50106: [libc++] Fix tuple assignment from types derived from a tuple-like
Arthur O'Dwyer via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 19 14:40:37 PST 2021
Quuxplusone accepted this revision.
Quuxplusone added a comment.
Suggested some ways to improve test coverage, and continued bikeshedding on the SFINAE ;) but there's no reason to hold this up AFAIC.
================
Comment at: libcxx/include/tuple:58
tuple& operator=(const tuple&);
- tuple&
- operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
+ tuple& operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
template <class... U>
----------------
Since this already isn't mimicking the syntax of http://eel.is/c++draft/tuple.tuple#tuple.assign-1 , I think you should say
tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);
but it definitely doesn't matter.
================
Comment at: libcxx/include/tuple:975
+
+ // EXTENSION
+ template<class _Up, size_t _Np, class = _EnableIf<
----------------
Perhaps in a followup patch: could we delineate exactly what code is part of this extension and put it all under an `#if _LIBCPP_TUPLE_ARRAY_ASSIGNMENT` or something, such that we could say "this is the exact extent of the extension code" and maybe even get customers to try compiling with `-D_LIBCPP_TUPLE_ARRAY_ASSIGNMENT=0` to see what breaks?
I'm assuming that our goal here is to deprecate and remove this extension over time. But even if we support it forever, I think `#if` would be nicer than the `//EXTENSION` comments.
================
Comment at: libcxx/include/tuple:992
+ // EXTENSION
+ template<class _Up, size_t _Np, class = void, class = _EnableIf<
+ _And<
----------------
Nitpick: Sent you a Slack suggesting how to eliminate this `class = void`.
================
Comment at: libcxx/test/libcxx/utilities/tuple/tuple.tuple/tuple.assign/const_array.pass.cpp:53
+ typedef std::array<int, 1> Array;
+ static_assert(!std::is_nothrow_assignable<Tuple&, Array const&>::value, "");
+ }
----------------
I would like to see this file combined with rvalue_array.pass.cpp, and also test the currently missing two value categories:
static_assert(std::is_nothrow_assignable<Tuple&, Array&>::value, "");
static_assert(std::is_nothrow_assignable<Tuple&, const Array&&>::value, "");
and also the negative cases:
static_assert(!std::is_assignable<Tuple&, std::array<long,2>&>::value, "");
static_assert(!std::is_assignable<Tuple&, std::array<long,2>&&>::value, "");
static_assert(!std::is_assignable<Tuple&, const std::array<long,2>&>::value, "");
static_assert(!std::is_assignable<Tuple&, const std::array<long,2>&&>::value, "");
static_assert(!std::is_assignable<Tuple&, std::array<long,4>&>::value, "");
static_assert(!std::is_assignable<Tuple&, std::array<long,4>&&>::value, "");
static_assert(!std::is_assignable<Tuple&, const std::array<long,4>&>::value, "");
static_assert(!std::is_assignable<Tuple&, const std::array<long,4>&&>::value, "");
================
Comment at: libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp:52
+ typedef std::pair<PotentiallyThrowingCopyAssignable, int> Pair;
+ static_assert(!std::is_nothrow_assignable<Tuple&, Pair const&>::value, "");
+ }
----------------
Don't just test for lack-of-nothrow-assignability; test for assignability-but-maythrow:
static_assert(std::is_assignable<Tuple&, Pair const&>::value, "");
static_assert(!std::is_nothrow_assignable<Tuple&, Pair const&>::value, "");
And as above, I'd prefer to see tests for `Pair&` and `Pair&&` and `const Pair&&` as well.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D50106/new/
https://reviews.llvm.org/D50106
More information about the cfe-commits
mailing list