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< - _Or< + _Not, tuple<_Up...> > >, + _Lazy<_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< - _Or< + _Not, tuple<_Up...> > >, + _Lazy<_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/cnstr_with_any.compile.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/cnstr_with_any.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/cnstr_with_any.compile.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include + +#include "test_macros.h" + +template +struct And : std::true_type { }; + +template +struct And + : std::conditional, std::false_type>::type +{ }; + +struct any { + any(); + any(any const&) = default; + + template ::type, + class = typename std::enable_if< + !std::is_same::value && + std::is_copy_constructible::value + >::type> + any(ValueType&&); +}; + +struct A { + A(); + A(any); +}; + +#if TEST_STD_VER > 14 +struct B { + B(); + B(std::any); +}; +#endif + +void f() { + { + std::tuple x; + std::tuple y = x; (void)y; + } + { + std::tuple x; + std::tuple y = std::move(x); (void)y; + } + +#if TEST_STD_VER > 14 + { + std::tuple x; + std::tuple y = x; (void)y; + } + { + std::tuple x; + std::tuple y = std::move(x); (void)y; + } +#endif +}