OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | |
3 * Copyright (C) 2009, 2010 Google Inc. All rights reserved. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Library General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Library General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Library General Public License | |
16 * along with this library; see the file COPYING.LIB. If not, write to | |
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
18 * Boston, MA 02110-1301, USA. | |
19 * | |
20 */ | |
21 | |
22 #include "wtf/TypeTraits.h" | |
23 | |
24 #include "wtf/Noncopyable.h" | |
25 | |
26 // No gtest tests; only static_assert checks. | |
27 | |
28 namespace WTF { | |
29 | |
30 namespace { | |
31 | |
32 struct VirtualClass { | |
33 virtual void A() {} | |
34 }; | |
35 static_assert(!IsTriviallyMoveAssignable<VirtualClass>::value, | |
36 "VirtualClass should not be trivially move assignable"); | |
37 | |
38 struct DestructorClass { | |
39 ~DestructorClass() {} | |
40 }; | |
41 static_assert(IsTriviallyMoveAssignable<DestructorClass>::value, | |
42 "DestructorClass should be trivially move assignable"); | |
43 static_assert(IsTriviallyCopyAssignable<DestructorClass>::value, | |
44 "DestructorClass should be trivially copy assignable"); | |
45 static_assert(IsTriviallyDefaultConstructible<DestructorClass>::value, | |
46 "DestructorClass should have a trivial default constructor"); | |
47 | |
48 struct MixedPrivate { | |
49 int M2() { return m2; } | |
50 int m1; | |
51 | |
52 private: | |
53 int m2; | |
54 }; | |
55 static_assert(IsTriviallyMoveAssignable<MixedPrivate>::value, | |
56 "MixedPrivate should be trivially move assignable"); | |
57 static_assert(IsTriviallyCopyAssignable<MixedPrivate>::value, | |
58 "MixedPrivate should be trivially copy assignable"); | |
59 static_assert(IsTriviallyDefaultConstructible<MixedPrivate>::value, | |
60 "MixedPrivate should have a trivial default constructor"); | |
61 struct JustPrivate { | |
62 int M2() { return m2; } | |
63 | |
64 private: | |
65 int m2; | |
66 }; | |
67 static_assert(IsTriviallyMoveAssignable<JustPrivate>::value, | |
68 "JustPrivate should be trivially move assignable"); | |
69 static_assert(IsTriviallyCopyAssignable<JustPrivate>::value, | |
70 "JustPrivate should be trivially copy assignable"); | |
71 static_assert(IsTriviallyDefaultConstructible<JustPrivate>::value, | |
72 "JustPrivate should have a trivial default constructor"); | |
73 struct JustPublic { | |
74 int m2; | |
75 }; | |
76 static_assert(IsTriviallyMoveAssignable<JustPublic>::value, | |
77 "JustPublic should be trivially move assignable"); | |
78 static_assert(IsTriviallyCopyAssignable<JustPublic>::value, | |
79 "JustPublic should be trivially copy assignable"); | |
80 static_assert(IsTriviallyDefaultConstructible<JustPublic>::value, | |
81 "JustPublic should have a trivial default constructor"); | |
82 struct NestedInherited : public JustPublic, JustPrivate { | |
83 float m3; | |
84 }; | |
85 static_assert(IsTriviallyMoveAssignable<NestedInherited>::value, | |
86 "NestedInherited should be trivially move assignable"); | |
87 static_assert(IsTriviallyCopyAssignable<NestedInherited>::value, | |
88 "NestedInherited should be trivially copy assignable"); | |
89 static_assert(IsTriviallyDefaultConstructible<NestedInherited>::value, | |
90 "NestedInherited should have a trivial default constructor"); | |
91 struct NestedOwned { | |
92 JustPublic m1; | |
93 JustPrivate m2; | |
94 float m3; | |
95 }; | |
96 | |
97 static_assert(IsTriviallyMoveAssignable<NestedOwned>::value, | |
98 "NestedOwned should be trivially move assignable"); | |
99 static_assert(IsTriviallyCopyAssignable<NestedOwned>::value, | |
100 "NestedOwned should be trivially copy assignable"); | |
101 static_assert(IsTriviallyDefaultConstructible<NestedOwned>::value, | |
102 "NestedOwned should have a trivial default constructor"); | |
103 | |
104 class NonCopyableClass { | |
105 WTF_MAKE_NONCOPYABLE(NonCopyableClass); | |
106 }; | |
107 #if 0 // Compilers don't get this "right" yet if using = delete. | |
108 static_assert(!IsTriviallyMoveAssignable<NonCopyableClass>::value, "NonCopyableC
lass should not be trivially move assignable"); | |
109 static_assert(!IsTriviallyCopyAssignable<NonCopyableClass>::value, "NonCopyableC
lass should not be trivially copy assignable"); | |
110 static_assert(IsTriviallyDefaultConstructible<NonCopyableClass>::value, "NonCopy
ableClass should have a trivial default constructor"); | |
111 #endif // 0 | |
112 | |
113 template <typename T> | |
114 class TestBaseClass {}; | |
115 | |
116 class TestDerivedClass : public TestBaseClass<int> {}; | |
117 | |
118 static_assert((IsSubclass<TestDerivedClass, TestBaseClass<int>>::value), | |
119 "Derived class should be a subclass of its base"); | |
120 static_assert((!IsSubclass<TestBaseClass<int>, TestDerivedClass>::value), | |
121 "Base class should not be a sublass of a derived class"); | |
122 static_assert((IsSubclassOfTemplate<TestDerivedClass, TestBaseClass>::value), | |
123 "Derived class should be a subclass of template from its base"); | |
124 | |
125 typedef int IntArray[]; | |
126 typedef int IntArraySized[4]; | |
127 | |
128 #if !COMPILER(MSVC) || COMPILER(CLANG) | |
129 | |
130 class AssignmentDeleted final { | |
131 private: | |
132 AssignmentDeleted& operator=(const AssignmentDeleted&) = delete; | |
133 }; | |
134 | |
135 static_assert(!IsCopyAssignable<AssignmentDeleted>::value, | |
136 "AssignmentDeleted isn't copy assignable."); | |
137 static_assert(!IsMoveAssignable<AssignmentDeleted>::value, | |
138 "AssignmentDeleted isn't move assignable."); | |
139 | |
140 class AssignmentPrivate final { | |
141 private: | |
142 AssignmentPrivate& operator=(const AssignmentPrivate&); | |
143 }; | |
144 | |
145 static_assert(!IsCopyAssignable<AssignmentPrivate>::value, | |
146 "AssignmentPrivate isn't copy assignable."); | |
147 static_assert(!IsMoveAssignable<AssignmentPrivate>::value, | |
148 "AssignmentPrivate isn't move assignable."); | |
149 | |
150 class CopyAssignmentDeleted final { | |
151 public: | |
152 CopyAssignmentDeleted& operator=(CopyAssignmentDeleted&&); | |
153 | |
154 private: | |
155 CopyAssignmentDeleted& operator=(const CopyAssignmentDeleted&) = delete; | |
156 }; | |
157 | |
158 static_assert(!IsCopyAssignable<CopyAssignmentDeleted>::value, | |
159 "CopyAssignmentDeleted isn't copy assignable."); | |
160 static_assert(IsMoveAssignable<CopyAssignmentDeleted>::value, | |
161 "CopyAssignmentDeleted is move assignable."); | |
162 | |
163 class CopyAssignmentPrivate final { | |
164 public: | |
165 CopyAssignmentPrivate& operator=(CopyAssignmentPrivate&&); | |
166 | |
167 private: | |
168 CopyAssignmentPrivate& operator=(const CopyAssignmentPrivate&); | |
169 }; | |
170 | |
171 static_assert(!IsCopyAssignable<CopyAssignmentPrivate>::value, | |
172 "CopyAssignmentPrivate isn't copy assignable."); | |
173 static_assert(IsMoveAssignable<CopyAssignmentPrivate>::value, | |
174 "CopyAssignmentPrivate is move assignable."); | |
175 | |
176 class CopyAssignmentUndeclared final { | |
177 public: | |
178 CopyAssignmentUndeclared& operator=(CopyAssignmentUndeclared&&); | |
179 }; | |
180 | |
181 static_assert(!IsCopyAssignable<CopyAssignmentUndeclared>::value, | |
182 "CopyAssignmentUndeclared isn't copy assignable."); | |
183 static_assert(IsMoveAssignable<CopyAssignmentUndeclared>::value, | |
184 "CopyAssignmentUndeclared is move assignable."); | |
185 | |
186 class Assignable final { | |
187 public: | |
188 Assignable& operator=(const Assignable&); | |
189 }; | |
190 | |
191 static_assert(IsCopyAssignable<Assignable>::value, | |
192 "Assignable is copy assignable."); | |
193 static_assert(IsMoveAssignable<Assignable>::value, | |
194 "Assignable is move assignable."); | |
195 | |
196 class AssignableImplicit final {}; | |
197 | |
198 static_assert(IsCopyAssignable<AssignableImplicit>::value, | |
199 "AssignableImplicit is copy assignable."); | |
200 static_assert(IsMoveAssignable<AssignableImplicit>::value, | |
201 "AssignableImplicit is move assignable."); | |
202 | |
203 #endif // !COMPILER(MSVC) || COMPILER(CLANG) | |
204 | |
205 class DefaultConstructorDeleted final { | |
206 private: | |
207 DefaultConstructorDeleted() = delete; | |
208 }; | |
209 | |
210 class DestructorDeleted final { | |
211 private: | |
212 ~DestructorDeleted() = delete; | |
213 }; | |
214 | |
215 static_assert( | |
216 !IsTriviallyDefaultConstructible<DefaultConstructorDeleted>::value, | |
217 "DefaultConstructorDeleted must not be trivially default constructible."); | |
218 | |
219 static_assert(!IsTriviallyDestructible<DestructorDeleted>::value, | |
220 "DestructorDeleted must not be trivially destructible."); | |
221 | |
222 template <typename T> | |
223 class Wrapper { | |
224 public: | |
225 template <typename U> | |
226 Wrapper(const Wrapper<U>&, EnsurePtrConvertibleArgDecl(U, T)) {} | |
227 }; | |
228 | |
229 class ForwardDeclarationOnlyClass; | |
230 | |
231 static_assert(std::is_convertible<Wrapper<TestDerivedClass>, | |
232 Wrapper<TestDerivedClass>>::value, | |
233 "EnsurePtrConvertibleArgDecl<T, T> should pass"); | |
234 | |
235 static_assert(std::is_convertible<Wrapper<TestDerivedClass>, | |
236 Wrapper<const TestDerivedClass>>::value, | |
237 "EnsurePtrConvertibleArgDecl<T, const T> should pass"); | |
238 | |
239 static_assert(!std::is_convertible<Wrapper<const TestDerivedClass>, | |
240 Wrapper<TestDerivedClass>>::value, | |
241 "EnsurePtrConvertibleArgDecl<const T, T> should not pass"); | |
242 | |
243 static_assert(std::is_convertible<Wrapper<ForwardDeclarationOnlyClass>, | |
244 Wrapper<ForwardDeclarationOnlyClass>>::value, | |
245 "EnsurePtrConvertibleArgDecl<T, T> should pass if T is not a " | |
246 "complete type"); | |
247 | |
248 static_assert( | |
249 std::is_convertible<Wrapper<ForwardDeclarationOnlyClass>, | |
250 Wrapper<const ForwardDeclarationOnlyClass>>::value, | |
251 "EnsurePtrConvertibleArgDecl<T, const T> should pass if T is not a " | |
252 "complete type"); | |
253 | |
254 static_assert(!std::is_convertible<Wrapper<const ForwardDeclarationOnlyClass>, | |
255 Wrapper<ForwardDeclarationOnlyClass>>::value, | |
256 "EnsurePtrConvertibleArgDecl<const T, T> should not pass if T is " | |
257 "not a complete type"); | |
258 | |
259 static_assert( | |
260 std::is_convertible<Wrapper<TestDerivedClass>, | |
261 Wrapper<TestBaseClass<int>>>::value, | |
262 "EnsurePtrConvertibleArgDecl<U, T> should pass if U is a subclass of T"); | |
263 | |
264 static_assert(!std::is_convertible<Wrapper<TestBaseClass<int>>, | |
265 Wrapper<TestDerivedClass>>::value, | |
266 "EnsurePtrConvertibleArgDecl<U, T> should not pass if U is a " | |
267 "base class of T"); | |
268 | |
269 } // anonymous namespace | |
270 | |
271 } // namespace WTF | |
OLD | NEW |