| 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 |