1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) Electronic Arts Inc. All rights reserved.
3 /////////////////////////////////////////////////////////////////////////////
4 
5 #ifndef CONCEPTSIMPLS_H
6 #define CONCEPTSIMPLS_H
7 
8 #include <EASTL/type_traits.h>
9 
10 #if !defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) && !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
11 
12 #define EASTL_TEST_CONCEPT_IMPLS
13 
14 // This header provides a variety of helper classes that have interfaces corresponding to the concepts used to specify
15 // requirements of many STL containers and algorithms. These helper classes are used in tests to verify that containers
16 // and algorithms do not impose stricter requirements than specified by the standard on their arguments.
17 
18 // Destructible - only valid operation on this class is to destroy it.
19 
20 class Destructible
21 {
22 public:
23 	~Destructible() = default;
24 
25 	Destructible() = delete;
26 	Destructible(const Destructible&) = delete;
27 	Destructible(Destructible&&) = delete;
28 	Destructible& operator=(const Destructible&) = delete;
29 	Destructible& operator=(Destructible&&) = delete;
30 };
31 
32 // Unfortunately not all compilers handle type_traits reliably correctly currently so we can't straightforwardly
33 // static_assert everything that should be true of this class
34 static_assert(eastl::is_destructible<Destructible>::value, "eastl::is_destructible<Destructible>::value");
35 // static_assert(!eastl::is_default_constructible<Destructible>::value,
36 // "!eastl::is_default_constructible<Destructible>::value");
37 // static_assert(!is_copy_constructible<Destructible>::value, "!eastl::is_copy_constructible<Destructible>::value");
38 static_assert(!eastl::is_copy_assignable<Destructible>::value, "!eastl::is_copy_assignable<Destructible>::value");
39 // static_assert(!eastl::is_move_constructible<Destructible>::value,
40 // "!eastl::is_move_constructible<Destructible>::value");
41 static_assert(!eastl::is_move_assignable<Destructible>::value, "!eastl::is_move_assignable<Destructible>::value");
42 
43 class DefaultConstructible
44 {
45 public:
46 	static const int defaultValue = 42;
47 
DefaultConstructible()48 	DefaultConstructible() : value(defaultValue) {}
49 	~DefaultConstructible() = default;
50 
51 	DefaultConstructible(const DefaultConstructible&) = delete;
52 	DefaultConstructible(DefaultConstructible&&) = delete;
53 	DefaultConstructible& operator=(const DefaultConstructible&) = delete;
54 	DefaultConstructible& operator=(DefaultConstructible&&) = delete;
55 
56 	const int value;
57 };
58 
59 
60 struct NotDefaultConstructible
61 {
62 	NotDefaultConstructible() = delete;
63 };
64 static_assert(!eastl::is_default_constructible<NotDefaultConstructible>::value, "'NotDefaultConstructible' is default constructible.");
65 
66 
67 class CopyConstructible
68 {
69 public:
70 	static const int defaultValue = 42;
Create()71 	static CopyConstructible Create()
72 	{
73 		CopyConstructible x;
74 		return x;
75 	}
76 
77 	CopyConstructible(const CopyConstructible&) = default;
78 	~CopyConstructible() = default;
79 
80 	CopyConstructible& operator=(const CopyConstructible&) = delete;
81 	CopyConstructible& operator=(CopyConstructible&&) = delete;
82 
83 	const int value;
84 
85 private:
CopyConstructible()86 	CopyConstructible() : value(defaultValue) {}
87 };
88 
89 // Unfortunately not all compilers handle type_traits reliably correctly currently so we can't straightforwardly
90 // static_assert everything that should be true of this class
91 static_assert(eastl::is_destructible<CopyConstructible>::value, "eastl::is_destructible<CopyConstructible>::value");
92 // static_assert(!eastl::is_default_constructible<CopyConstructible>::value,
93 // "!eastl::is_default_constructible<CopyConstructible>::value");
94 // static_assert(is_copy_constructible<CopyConstructible>::value, "is_copy_constructible<CopyConstructible>::value");
95 static_assert(eastl::is_copy_constructible<CopyConstructible>::value,
96 			  "eastl::is_copy_constructible<CopyConstructible>::value");
97 static_assert(!eastl::is_copy_assignable<CopyConstructible>::value,
98 			  "!eastl::is_copy_assignable<CopyConstructible>::value");
99 // static_assert(!eastl::is_move_constructible<CopyConstructible>::value,
100 // "!eastl::is_move_constructible<CopyConstructible>::value");
101 static_assert(!eastl::is_move_assignable<CopyConstructible>::value,
102 			  "!eastl::is_move_assignable<CopyConstructible>::value");
103 
104 class MoveConstructible
105 {
106 public:
107 	static const int defaultValue = 42;
Create()108 	static MoveConstructible Create()
109 	{
110 		return MoveConstructible{};
111 	}
112 
MoveConstructible(MoveConstructible && x)113 	MoveConstructible(MoveConstructible&& x) : value(x.value) {}
114 	~MoveConstructible() = default;
115 
116 	MoveConstructible(const MoveConstructible&) = delete;
117 	MoveConstructible& operator=(const MoveConstructible&) = delete;
118 	MoveConstructible& operator=(MoveConstructible&&) = delete;
119 
120 	const int value;
121 
122 private:
MoveConstructible()123 	MoveConstructible() : value(defaultValue) {}
124 };
125 
126 class MoveAssignable
127 {
128 public:
129 	static const int defaultValue = 42;
Create()130 	static MoveAssignable Create()
131 	{
132 		return MoveAssignable{};
133 	}
134 
MoveAssignable(MoveAssignable && x)135 	MoveAssignable(MoveAssignable&& x) : value(x.value) {}
136 	MoveAssignable& operator=(MoveAssignable&& x)
137 	{
138 		value = x.value;
139 		return *this;
140 	}
141 	~MoveAssignable() = default;
142 
143 	MoveAssignable(const MoveAssignable&) = delete;
144 	MoveAssignable& operator=(const MoveAssignable&) = delete;
145 
146 	int value;
147 
148 private:
MoveAssignable()149 	MoveAssignable() : value(defaultValue) {}
150 };
151 
152 struct MoveAndDefaultConstructible
153 {
154 	static const int defaultValue = 42;
155 
MoveAndDefaultConstructibleMoveAndDefaultConstructible156 	MoveAndDefaultConstructible() : value(defaultValue) {}
MoveAndDefaultConstructibleMoveAndDefaultConstructible157 	MoveAndDefaultConstructible(MoveAndDefaultConstructible&& x) : value(x.value) {}
158 	~MoveAndDefaultConstructible() = default;
159 
160 	MoveAndDefaultConstructible(const MoveAndDefaultConstructible&) = delete;
161 	MoveAndDefaultConstructible& operator=(const MoveAndDefaultConstructible&) = delete;
162 	MoveAndDefaultConstructible& operator=(MoveAndDefaultConstructible&&) = delete;
163 
164 	const int value;
165 };
166 
167 struct MissingMoveConstructor
168 {
MissingMoveConstructorMissingMoveConstructor169 	MissingMoveConstructor() {}
MissingMoveConstructorMissingMoveConstructor170 	MissingMoveConstructor(const MissingMoveConstructor&) {}
171 	MissingMoveConstructor& operator=(MissingMoveConstructor&&) { return *this; }
172 	MissingMoveConstructor& operator=(const MissingMoveConstructor&) { return *this; }
173 	bool operator<(const MissingMoveConstructor&) const { return true; }
174 };
175 
176 struct MissingMoveAssignable
177 {
MissingMoveAssignableMissingMoveAssignable178 	MissingMoveAssignable() {}
MissingMoveAssignableMissingMoveAssignable179 	MissingMoveAssignable(const MissingMoveAssignable&) {}
MissingMoveAssignableMissingMoveAssignable180 	MissingMoveAssignable(MissingMoveAssignable&&) {}
181 	MissingMoveAssignable& operator=(const MissingMoveAssignable&) { return *this; }
182 	bool operator<(const MissingMoveAssignable&) const { return true; }
183 };
184 
185 struct MissingEquality
186 {
187 	MissingEquality& operator==(const MissingEquality&) = delete;
188 };
189 
190 #endif  // !defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) && !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
191 
192 #endif  // CONCEPTSIMPLS_H
193