diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -675,12 +675,12 @@ // tuple(const tuple&) constructors (including allocator_arg_t variants) template struct _EnableCopyFromOtherTuple : _And< + _Not, tuple<_Up...> > >, _Or< _BoolConstant, // _Tp and _Up are 1-element packs - the pack expansions look // weird to avoid tripping up the type traits in degenerate cases _Lazy<_And, - _Not >..., _Not&, _Tp> >..., _Not&> >... > @@ -741,12 +741,12 @@ // tuple(tuple&&) constructors (including allocator_arg_t variants) template struct _EnableMoveFromOtherTuple : _And< + _Not, tuple<_Up...> > >, _Or< _BoolConstant, // _Tp and _Up are 1-element packs - the pack expansions look // weird to avoid tripping up the type traits in degenerate cases _Lazy<_And, - _Not >..., _Not, _Tp> >..., _Not > >... > diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.with_any.compile.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.with_any.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/copy.with_any.compile.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// This test makes sure that we can copy/move a std::tuple containing a type +// that checks for copy constructibility itself, like std::any. +// +// Problem showcased in https://reviews.llvm.org/D96523#2730953. + +#include +#include +#include + +template +struct And : std::true_type { }; + +template +struct And + : std::conditional, std::false_type>::type +{ }; + +struct any { + any(); + any(any const&) = default; + + template , class = std::enable_if_t< + !std::is_same::value && + std::is_copy_constructible::value + > > + any(ValueType&&); +}; + +struct B { + B(); + B(any); +}; + +void f() { + { + std::tuple a; + std::tuple b = a; (void)b; + } + + { + std::tuple a; + std::tuple b = std::move(a); (void)b; + } +}