1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: libcpp-no-concepts
11 
12 // template<class T>
13 // concept copy_constructible;
14 
15 #include <concepts>
16 #include <type_traits>
17 
18 #include "type_classification/moveconstructible.h"
19 
20 // Tests in this namespace are shared with moveconstructible.pass.cpp
21 // There are some interesting differences, so it's best if they're tested here
22 // too.
23 namespace MoveConstructibleTests {
24 static_assert(std::copy_constructible<int>);
25 static_assert(std::copy_constructible<int*>);
26 static_assert(std::copy_constructible<int&>);
27 static_assert(std::copy_constructible<const int>);
28 static_assert(std::copy_constructible<const int&>);
29 static_assert(std::copy_constructible<volatile int>);
30 static_assert(std::copy_constructible<volatile int&>);
31 static_assert(std::copy_constructible<int (*)()>);
32 static_assert(std::copy_constructible<int (&)()>);
33 static_assert(std::copy_constructible<HasDefaultOps>);
34 static_assert(std::copy_constructible<const CustomMoveCtor&>);
35 static_assert(std::copy_constructible<volatile CustomMoveCtor&>);
36 static_assert(std::copy_constructible<const CustomMoveAssign&>);
37 static_assert(std::copy_constructible<volatile CustomMoveAssign&>);
38 static_assert(std::copy_constructible<int HasDefaultOps::*>);
39 static_assert(std::copy_constructible<void (HasDefaultOps::*)(int)>);
40 static_assert(std::copy_constructible<MemberLvalueReference>);
41 
42 static_assert(!std::copy_constructible<void>);
43 static_assert(!std::copy_constructible<CustomMoveAssign>);
44 static_assert(!std::copy_constructible<const CustomMoveCtor>);
45 static_assert(!std::copy_constructible<volatile CustomMoveCtor>);
46 static_assert(!std::copy_constructible<const CustomMoveAssign>);
47 static_assert(!std::copy_constructible<volatile CustomMoveAssign>);
48 static_assert(!std::copy_constructible<int[10]>);
49 static_assert(!std::copy_constructible<DeletedMoveCtor>);
50 static_assert(!std::copy_constructible<ImplicitlyDeletedMoveCtor>);
51 static_assert(!std::copy_constructible<DeletedMoveAssign>);
52 static_assert(!std::copy_constructible<ImplicitlyDeletedMoveAssign>);
53 
54 static_assert(std::copy_constructible<DeletedMoveCtor&>);
55 static_assert(std::copy_constructible<const DeletedMoveCtor&>);
56 static_assert(std::copy_constructible<ImplicitlyDeletedMoveCtor&>);
57 static_assert(std::copy_constructible<const ImplicitlyDeletedMoveCtor&>);
58 static_assert(std::copy_constructible<DeletedMoveAssign&>);
59 static_assert(std::copy_constructible<const DeletedMoveAssign&>);
60 static_assert(std::copy_constructible<ImplicitlyDeletedMoveAssign&>);
61 static_assert(std::copy_constructible<const ImplicitlyDeletedMoveAssign&>);
62 
63 // different to moveconstructible.pass.cpp
64 static_assert(!std::copy_constructible<int&&>);
65 static_assert(!std::copy_constructible<const int&&>);
66 static_assert(!std::copy_constructible<volatile int&&>);
67 static_assert(!std::copy_constructible<CustomMoveCtor>);
68 static_assert(!std::copy_constructible<MoveOnly>);
69 static_assert(!std::copy_constructible<const CustomMoveCtor&&>);
70 static_assert(!std::copy_constructible<volatile CustomMoveCtor&&>);
71 static_assert(!std::copy_constructible<const CustomMoveAssign&&>);
72 static_assert(!std::copy_constructible<volatile CustomMoveAssign&&>);
73 static_assert(!std::copy_constructible<DeletedMoveCtor&&>);
74 static_assert(!std::copy_constructible<const DeletedMoveCtor&&>);
75 static_assert(!std::copy_constructible<ImplicitlyDeletedMoveCtor&&>);
76 static_assert(!std::copy_constructible<const ImplicitlyDeletedMoveCtor&&>);
77 static_assert(!std::copy_constructible<DeletedMoveAssign&&>);
78 static_assert(!std::copy_constructible<const DeletedMoveAssign&&>);
79 static_assert(!std::copy_constructible<ImplicitlyDeletedMoveAssign&&>);
80 static_assert(!std::copy_constructible<const ImplicitlyDeletedMoveAssign&&>);
81 static_assert(!std::copy_constructible<MemberRvalueReference>);
82 } // namespace MoveConstructibleTests
83 
84 namespace CopyConstructibleTests {
85 struct CopyCtorUserDefined {
86   CopyCtorUserDefined(CopyCtorUserDefined&&) noexcept = default;
87   CopyCtorUserDefined(const CopyCtorUserDefined&);
88 };
89 static_assert(std::copy_constructible<CopyCtorUserDefined>);
90 
91 struct CopyAssignUserDefined {
92   CopyAssignUserDefined& operator=(CopyAssignUserDefined&&) noexcept = default;
93   CopyAssignUserDefined& operator=(const CopyAssignUserDefined&);
94 };
95 static_assert(!std::copy_constructible<CopyAssignUserDefined>);
96 
97 struct CopyCtorAndAssignUserDefined {
98   CopyCtorAndAssignUserDefined(CopyCtorAndAssignUserDefined&&) noexcept =
99       default;
100   CopyCtorAndAssignUserDefined(const CopyCtorAndAssignUserDefined&);
101   CopyCtorAndAssignUserDefined&
102   operator=(CopyCtorAndAssignUserDefined&&) noexcept = default;
103   CopyCtorAndAssignUserDefined& operator=(const CopyCtorAndAssignUserDefined&);
104 };
105 static_assert(std::copy_constructible<CopyCtorAndAssignUserDefined>);
106 
107 struct CopyCtorDeleted {
108   CopyCtorDeleted(CopyCtorDeleted&&) noexcept = default;
109   CopyCtorDeleted(const CopyCtorDeleted&) = delete;
110 };
111 static_assert(!std::copy_constructible<CopyCtorDeleted>);
112 
113 struct CopyAssignDeleted {
114   CopyAssignDeleted(CopyAssignDeleted&&) noexcept = default;
115   CopyAssignDeleted(const CopyAssignDeleted&) = delete;
116 };
117 static_assert(!std::copy_constructible<CopyAssignDeleted>);
118 
119 struct CopyCtorHasMutableRef {
120   CopyCtorHasMutableRef(CopyCtorHasMutableRef&&) noexcept = default;
121   CopyCtorHasMutableRef(CopyCtorHasMutableRef&) = default;
122 };
123 static_assert(!std::copy_constructible<CopyCtorHasMutableRef>);
124 
125 struct CopyCtorProhibitsMutableRef {
126   CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&&) noexcept = default;
127   CopyCtorProhibitsMutableRef(const CopyCtorProhibitsMutableRef&) = default;
128   CopyCtorProhibitsMutableRef(CopyCtorProhibitsMutableRef&) = delete;
129 };
130 static_assert(!std::copy_constructible<CopyCtorProhibitsMutableRef>);
131 
132 struct CopyAssignHasMutableRef {
133   CopyAssignHasMutableRef&
134   operator=(CopyAssignHasMutableRef&&) noexcept = default;
135   CopyAssignHasMutableRef& operator=(CopyAssignHasMutableRef&) = default;
136 };
137 static_assert(!std::copy_constructible<CopyAssignHasMutableRef>);
138 
139 struct CopyAssignProhibitsMutableRef {
140   CopyAssignProhibitsMutableRef&
141   operator=(CopyAssignProhibitsMutableRef&&) noexcept = default;
142   CopyAssignProhibitsMutableRef&
143   operator=(const CopyAssignProhibitsMutableRef&) = default;
144   CopyAssignProhibitsMutableRef&
145   operator=(CopyAssignProhibitsMutableRef&) = delete;
146 };
147 static_assert(!std::copy_constructible<CopyAssignProhibitsMutableRef>);
148 
149 struct CopyCtorOnly {
150   CopyCtorOnly(CopyCtorOnly&&) noexcept = delete;
151   CopyCtorOnly(const CopyCtorOnly&) = default;
152 };
153 static_assert(!std::copy_constructible<CopyCtorOnly>);
154 
155 struct CopyAssignOnly {
156   CopyAssignOnly& operator=(CopyAssignOnly&&) noexcept = delete;
157   CopyAssignOnly& operator=(const CopyAssignOnly&) = default;
158 };
159 static_assert(!std::copy_constructible<CopyAssignOnly>);
160 
161 struct CopyOnly {
162   CopyOnly(CopyOnly&&) noexcept = delete;
163   CopyOnly(const CopyOnly&) = default;
164 
165   CopyOnly& operator=(CopyOnly&&) noexcept = delete;
166   CopyOnly& operator=(const CopyOnly&) = default;
167 };
168 static_assert(!std::copy_constructible<CopyOnly>);
169 
170 struct ExplicitlyCopyable {
171   ExplicitlyCopyable(ExplicitlyCopyable&&) = default;
172   explicit ExplicitlyCopyable(const ExplicitlyCopyable&);
173 };
174 static_assert(!std::copy_constructible<ExplicitlyCopyable>);
175 } // namespace CopyConstructibleTests
176 
177 int main(int, char**) { return 0; }
178