diff --git a/libcxx/include/concepts b/libcxx/include/concepts --- a/libcxx/include/concepts +++ b/libcxx/include/concepts @@ -189,6 +189,14 @@ concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; +// [concept.copyconstructible] +template +concept copy_constructible = + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to && + constructible_from<_Tp, const _Tp> && convertible_to; + #endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp b/libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp @@ -0,0 +1,177 @@ +//===----------------------------------------------------------------------===// +// +// 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++98, c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts + +// template +// concept copy_constructible; + +#include +#include + +#include "moveconstructible.h" + +// Tests in this namespace are shared with moveconstructible.pass.cpp +// There are some interesting differences, so it's best if they're tested here +// too. +namespace MoveConstructibleTests { +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); + +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); + +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); +static_assert(std::copy_constructible); + +// different to moveconstructible.pass.cpp +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +static_assert(!std::copy_constructible); +} // namespace MoveConstructibleTests + +namespace CopyConstructibleTests { +struct CopyCtorUserDefined { + CopyCtorUserDefined(CopyCtorUserDefined&&) noexcept = default; + CopyCtorUserDefined(const CopyCtorUserDefined&); +}; +static_assert(std::copy_constructible); + +struct CopyAssignUserDefined { + CopyAssignUserDefined& operator=(CopyAssignUserDefined&&) noexcept = default; + CopyAssignUserDefined& operator=(const CopyAssignUserDefined&); +}; +static_assert(!std::copy_constructible); + +struct CopyCtorAndAssignUserDefined { + CopyCtorAndAssignUserDefined(CopyCtorAndAssignUserDefined&&) noexcept = + default; + CopyCtorAndAssignUserDefined(const CopyCtorAndAssignUserDefined&); + CopyCtorAndAssignUserDefined& + operator=(CopyCtorAndAssignUserDefined&&) noexcept = default; + CopyCtorAndAssignUserDefined& operator=(const CopyCtorAndAssignUserDefined&); +}; +static_assert(std::copy_constructible); + +struct CopyCtorDeleted { + CopyCtorDeleted(CopyCtorDeleted&&) noexcept = default; + CopyCtorDeleted(const CopyCtorDeleted&) = delete; +}; +static_assert(!std::copy_constructible); + +struct CopyAssignDeleted { + CopyAssignDeleted(CopyAssignDeleted&&) noexcept = default; + CopyAssignDeleted(const CopyAssignDeleted&) = delete; +}; +static_assert(!std::copy_constructible); + +struct CopyCtorHasMutableRef { + CopyCtorHasMutableRef(CopyCtorHasMutableRef&&) noexcept = default; + CopyCtorHasMutableRef(CopyCtorHasMutableRef&) = default; +}; +static_assert(!std::copy_constructible); + +struct CopyCtorProhibitsMutableRef { + CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&&) noexcept = default; + CopyCtorProhibitsMutableRef(const CopyCtorProhibitsMutableRef&) = default; + CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&) = delete; +}; +static_assert(!std::copy_constructible); + +struct CopyAssignHasMutableRef { + CopyAssignHasMutableRef& + operator=(CopyAssignHasMutableRef&&) noexcept = default; + CopyAssignHasMutableRef& operator=(CopyAssignHasMutableRef&) = default; +}; +static_assert(!std::copy_constructible); + +struct CopyAssignProhibitsMutableRef { + CopyAssignProhibitsMutableRef& + operator=(CopyAssignProhibitsMutableRef&&) noexcept = default; + CopyAssignProhibitsMutableRef& + operator=(const CopyAssignProhibitsMutableRef&) = default; + CopyAssignProhibitsMutableRef& + operator=(CopyAssignProhibitsMutableRef&) = delete; +}; +static_assert(!std::copy_constructible); + +struct CopyCtorOnly { + CopyCtorOnly(CopyCtorOnly&&) noexcept = delete; + CopyCtorOnly(const CopyCtorOnly&) = default; +}; +static_assert(!std::copy_constructible); + +struct CopyAssignOnly { + CopyAssignOnly& operator=(CopyAssignOnly&&) noexcept = delete; + CopyAssignOnly& operator=(const CopyAssignOnly&) = default; +}; +static_assert(!std::copy_constructible); + +struct CopyOnly { + CopyOnly(CopyOnly&&) noexcept = delete; + CopyOnly(const CopyOnly&) = default; + + CopyOnly& operator=(CopyOnly&&) noexcept = delete; + CopyOnly& operator=(const CopyOnly&) = default; +}; +static_assert(!std::copy_constructible); + +struct ExplicitlyCopyable { + ExplicitlyCopyable(ExplicitlyCopyable&&) = default; + explicit ExplicitlyCopyable(const ExplicitlyCopyable&); +}; +static_assert(!std::copy_constructible); +} // namespace CopyConstructibleTests + +int main(int, char**) { return 0; }