[libcxx-commits] [libcxx] 2193e8b - [libcxx] adds concept `std::copy_constructible`

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 10 09:57:29 PST 2021


Author: Christopher Di Bella
Date: 2021-02-10T17:56:42Z
New Revision: 2193e8be3efa5eea452c6c5bbc2f6393c8f10e62

URL: https://github.com/llvm/llvm-project/commit/2193e8be3efa5eea452c6c5bbc2f6393c8f10e62
DIFF: https://github.com/llvm/llvm-project/commit/2193e8be3efa5eea452c6c5bbc2f6393c8f10e62.diff

LOG: [libcxx] adds concept `std::copy_constructible`

Implements parts of:
    - P0898R3 Standard Library Concepts
    - P1754 Rename concepts to standard_case for C++20, while we still can

Depends on D96230

Differential Revision: https://reviews.llvm.org/D96232

Added: 
    libcxx/test/std/concepts/lang/copyconstructible.compile.pass.cpp

Modified: 
    libcxx/include/concepts

Removed: 
    


################################################################################
diff  --git a/libcxx/include/concepts b/libcxx/include/concepts
index 7ab03ffb65aa..e83dce757d15 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -189,6 +189,14 @@ template<class _Tp>
 concept move_constructible =
   constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
 
+// [concept.copyconstructible]
+template<class _Tp>
+concept copy_constructible =
+  move_constructible<_Tp> &&
+  constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> &&
+  constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> &&
+  constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;
+
 #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
index 000000000000..ad1fbee55a2c
--- /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<class T>
+// concept copy_constructible;
+
+#include <concepts>
+#include <type_traits>
+
+#include "moveconstructible.h"
+
+// Tests in this namespace are shared with moveconstructible.pass.cpp
+// There are some interesting 
diff erences, so it's best if they're tested here
+// too.
+namespace MoveConstructibleTests {
+static_assert(std::copy_constructible<int>);
+static_assert(std::copy_constructible<int*>);
+static_assert(std::copy_constructible<int&>);
+static_assert(std::copy_constructible<const int>);
+static_assert(std::copy_constructible<const int&>);
+static_assert(std::copy_constructible<volatile int>);
+static_assert(std::copy_constructible<volatile int&>);
+static_assert(std::copy_constructible<int (*)()>);
+static_assert(std::copy_constructible<int (&)()>);
+static_assert(std::copy_constructible<HasDefaultOps>);
+static_assert(std::copy_constructible<const CustomMoveCtor&>);
+static_assert(std::copy_constructible<volatile CustomMoveCtor&>);
+static_assert(std::copy_constructible<const CustomMoveAssign&>);
+static_assert(std::copy_constructible<volatile CustomMoveAssign&>);
+static_assert(std::copy_constructible<int HasDefaultOps::*>);
+static_assert(std::copy_constructible<void (HasDefaultOps::*)(int)>);
+static_assert(std::copy_constructible<MemberLvalueReference>);
+
+static_assert(!std::copy_constructible<void>);
+static_assert(!std::copy_constructible<CustomMoveAssign>);
+static_assert(!std::copy_constructible<const CustomMoveCtor>);
+static_assert(!std::copy_constructible<volatile CustomMoveCtor>);
+static_assert(!std::copy_constructible<const CustomMoveAssign>);
+static_assert(!std::copy_constructible<volatile CustomMoveAssign>);
+static_assert(!std::copy_constructible<int[10]>);
+static_assert(!std::copy_constructible<DeletedMoveCtor>);
+static_assert(!std::copy_constructible<ImplicitlyDeletedMoveCtor>);
+static_assert(!std::copy_constructible<DeletedMoveAssign>);
+static_assert(!std::copy_constructible<ImplicitlyDeletedMoveAssign>);
+
+static_assert(std::copy_constructible<DeletedMoveCtor&>);
+static_assert(std::copy_constructible<const DeletedMoveCtor&>);
+static_assert(std::copy_constructible<ImplicitlyDeletedMoveCtor&>);
+static_assert(std::copy_constructible<const ImplicitlyDeletedMoveCtor&>);
+static_assert(std::copy_constructible<DeletedMoveAssign&>);
+static_assert(std::copy_constructible<const DeletedMoveAssign&>);
+static_assert(std::copy_constructible<ImplicitlyDeletedMoveAssign&>);
+static_assert(std::copy_constructible<const ImplicitlyDeletedMoveAssign&>);
+
+// 
diff erent to moveconstructible.pass.cpp
+static_assert(!std::copy_constructible<int&&>);
+static_assert(!std::copy_constructible<const int&&>);
+static_assert(!std::copy_constructible<volatile int&&>);
+static_assert(!std::copy_constructible<CustomMoveCtor>);
+static_assert(!std::copy_constructible<MoveOnly>);
+static_assert(!std::copy_constructible<const CustomMoveCtor&&>);
+static_assert(!std::copy_constructible<volatile CustomMoveCtor&&>);
+static_assert(!std::copy_constructible<const CustomMoveAssign&&>);
+static_assert(!std::copy_constructible<volatile CustomMoveAssign&&>);
+static_assert(!std::copy_constructible<DeletedMoveCtor&&>);
+static_assert(!std::copy_constructible<const DeletedMoveCtor&&>);
+static_assert(!std::copy_constructible<ImplicitlyDeletedMoveCtor&&>);
+static_assert(!std::copy_constructible<const ImplicitlyDeletedMoveCtor&&>);
+static_assert(!std::copy_constructible<DeletedMoveAssign&&>);
+static_assert(!std::copy_constructible<const DeletedMoveAssign&&>);
+static_assert(!std::copy_constructible<ImplicitlyDeletedMoveAssign&&>);
+static_assert(!std::copy_constructible<const ImplicitlyDeletedMoveAssign&&>);
+static_assert(!std::copy_constructible<MemberRvalueReference>);
+} // namespace MoveConstructibleTests
+
+namespace CopyConstructibleTests {
+struct CopyCtorUserDefined {
+  CopyCtorUserDefined(CopyCtorUserDefined&&) noexcept = default;
+  CopyCtorUserDefined(const CopyCtorUserDefined&);
+};
+static_assert(std::copy_constructible<CopyCtorUserDefined>);
+
+struct CopyAssignUserDefined {
+  CopyAssignUserDefined& operator=(CopyAssignUserDefined&&) noexcept = default;
+  CopyAssignUserDefined& operator=(const CopyAssignUserDefined&);
+};
+static_assert(!std::copy_constructible<CopyAssignUserDefined>);
+
+struct CopyCtorAndAssignUserDefined {
+  CopyCtorAndAssignUserDefined(CopyCtorAndAssignUserDefined&&) noexcept =
+      default;
+  CopyCtorAndAssignUserDefined(const CopyCtorAndAssignUserDefined&);
+  CopyCtorAndAssignUserDefined&
+  operator=(CopyCtorAndAssignUserDefined&&) noexcept = default;
+  CopyCtorAndAssignUserDefined& operator=(const CopyCtorAndAssignUserDefined&);
+};
+static_assert(std::copy_constructible<CopyCtorAndAssignUserDefined>);
+
+struct CopyCtorDeleted {
+  CopyCtorDeleted(CopyCtorDeleted&&) noexcept = default;
+  CopyCtorDeleted(const CopyCtorDeleted&) = delete;
+};
+static_assert(!std::copy_constructible<CopyCtorDeleted>);
+
+struct CopyAssignDeleted {
+  CopyAssignDeleted(CopyAssignDeleted&&) noexcept = default;
+  CopyAssignDeleted(const CopyAssignDeleted&) = delete;
+};
+static_assert(!std::copy_constructible<CopyAssignDeleted>);
+
+struct CopyCtorHasMutableRef {
+  CopyCtorHasMutableRef(CopyCtorHasMutableRef&&) noexcept = default;
+  CopyCtorHasMutableRef(CopyCtorHasMutableRef&) = default;
+};
+static_assert(!std::copy_constructible<CopyCtorHasMutableRef>);
+
+struct CopyCtorProhibitsMutableRef {
+  CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&&) noexcept = default;
+  CopyCtorProhibitsMutableRef(const CopyCtorProhibitsMutableRef&) = default;
+  CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&) = delete;
+};
+static_assert(!std::copy_constructible<CopyCtorProhibitsMutableRef>);
+
+struct CopyAssignHasMutableRef {
+  CopyAssignHasMutableRef&
+  operator=(CopyAssignHasMutableRef&&) noexcept = default;
+  CopyAssignHasMutableRef& operator=(CopyAssignHasMutableRef&) = default;
+};
+static_assert(!std::copy_constructible<CopyAssignHasMutableRef>);
+
+struct CopyAssignProhibitsMutableRef {
+  CopyAssignProhibitsMutableRef&
+  operator=(CopyAssignProhibitsMutableRef&&) noexcept = default;
+  CopyAssignProhibitsMutableRef&
+  operator=(const CopyAssignProhibitsMutableRef&) = default;
+  CopyAssignProhibitsMutableRef&
+  operator=(CopyAssignProhibitsMutableRef&) = delete;
+};
+static_assert(!std::copy_constructible<CopyAssignProhibitsMutableRef>);
+
+struct CopyCtorOnly {
+  CopyCtorOnly(CopyCtorOnly&&) noexcept = delete;
+  CopyCtorOnly(const CopyCtorOnly&) = default;
+};
+static_assert(!std::copy_constructible<CopyCtorOnly>);
+
+struct CopyAssignOnly {
+  CopyAssignOnly& operator=(CopyAssignOnly&&) noexcept = delete;
+  CopyAssignOnly& operator=(const CopyAssignOnly&) = default;
+};
+static_assert(!std::copy_constructible<CopyAssignOnly>);
+
+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<CopyOnly>);
+
+struct ExplicitlyCopyable {
+  ExplicitlyCopyable(ExplicitlyCopyable&&) = default;
+  explicit ExplicitlyCopyable(const ExplicitlyCopyable&);
+};
+static_assert(!std::copy_constructible<ExplicitlyCopyable>);
+} // namespace CopyConstructibleTests
+
+int main(int, char**) { return 0; }


        


More information about the libcxx-commits mailing list