1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
12 #include <type_traits>
15 #include "test_macros.h"
17 #if TEST_STD_VER >= 11
24 explicit A1(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
28 int id() const {return id_
;}
30 static bool copy_called
;
31 static bool move_called
;
32 static bool allocate_called
;
33 static std::pair
<T
*, std::size_t> deallocate_called
;
35 A1(const A1
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
36 A1(A1
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
37 A1
& operator=(const A1
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
38 A1
& operator=(A1
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
41 A1(const A1
<U
>& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
43 A1(A1
<U
>&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
45 T
* allocate(std::size_t n
)
47 allocate_called
= true;
51 void deallocate(T
* p
, std::size_t n
)
53 deallocate_called
= std::pair
<T
*, std::size_t>(p
, n
);
56 std::size_t max_size() const {return id_
;}
59 template <class T
> bool A1
<T
>::copy_called
= false;
60 template <class T
> bool A1
<T
>::move_called
= false;
61 template <class T
> bool A1
<T
>::allocate_called
= false;
62 template <class T
> std::pair
<T
*, std::size_t> A1
<T
>::deallocate_called
;
64 template <class T
, class U
>
66 bool operator==(const A1
<T
>& x
, const A1
<U
>& y
)
68 return x
.id() == y
.id();
71 template <class T
, class U
>
73 bool operator!=(const A1
<T
>& x
, const A1
<U
>& y
)
83 explicit A2(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
87 typedef unsigned size_type
;
88 typedef int difference_type
;
90 typedef std::true_type propagate_on_container_move_assignment
;
92 int id() const {return id_
;}
94 static bool copy_called
;
95 static bool move_called
;
96 static bool allocate_called
;
98 A2(const A2
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
99 A2(A2
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
100 A2
& operator=(const A2
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
101 A2
& operator=(A2
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
103 T
* allocate(std::size_t, const void* hint
)
105 allocate_called
= true;
106 return (T
*) const_cast<void *>(hint
);
110 template <class T
> bool A2
<T
>::copy_called
= false;
111 template <class T
> bool A2
<T
>::move_called
= false;
112 template <class T
> bool A2
<T
>::allocate_called
= false;
114 template <class T
, class U
>
116 bool operator==(const A2
<T
>& x
, const A2
<U
>& y
)
118 return x
.id() == y
.id();
121 template <class T
, class U
>
123 bool operator!=(const A2
<T
>& x
, const A2
<U
>& y
)
133 explicit A3(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
135 typedef T value_type
;
137 typedef std::true_type propagate_on_container_copy_assignment
;
138 typedef std::true_type propagate_on_container_swap
;
140 int id() const {return id_
;}
142 static bool copy_called
;
143 static bool move_called
;
144 static bool constructed
;
145 static bool destroy_called
;
147 A3(const A3
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
148 A3(A3
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
149 A3
& operator=(const A3
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
150 A3
& operator=(A3
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
152 template <class U
, class ...Args
>
153 void construct(U
* p
, Args
&& ...args
)
155 ::new (p
) U(std::forward
<Args
>(args
)...);
163 destroy_called
= true;
166 A3
select_on_container_copy_construction() const {return A3(-1);}
169 template <class T
> bool A3
<T
>::copy_called
= false;
170 template <class T
> bool A3
<T
>::move_called
= false;
171 template <class T
> bool A3
<T
>::constructed
= false;
172 template <class T
> bool A3
<T
>::destroy_called
= false;
174 template <class T
, class U
>
176 bool operator==(const A3
<T
>& x
, const A3
<U
>& y
)
178 return x
.id() == y
.id();
181 template <class T
, class U
>
183 bool operator!=(const A3
<T
>& x
, const A3
<U
>& y
)
188 template <class T
, bool POCCAValue
>
189 class MaybePOCCAAllocator
{
191 bool* copy_assigned_into_
= nullptr;
193 typedef std::integral_constant
<bool, POCCAValue
> propagate_on_container_copy_assignment
;
194 typedef T value_type
;
196 MaybePOCCAAllocator() = default;
197 MaybePOCCAAllocator(int id
, bool* copy_assigned_into
)
198 : id_(id
), copy_assigned_into_(copy_assigned_into
) {}
200 MaybePOCCAAllocator(const MaybePOCCAAllocator
&) = default;
201 MaybePOCCAAllocator
& operator=(const MaybePOCCAAllocator
& a
)
204 if (copy_assigned_into_
)
205 *copy_assigned_into_
= true;
209 T
* allocate(std::size_t n
)
211 return static_cast<T
*>(::operator new(n
* sizeof(T
)));
214 void deallocate(T
* ptr
, std::size_t)
216 ::operator delete(ptr
);
219 int id() const { return id_
; }
221 friend bool operator==(const MaybePOCCAAllocator
& lhs
, const MaybePOCCAAllocator
& rhs
)
223 return lhs
.id() == rhs
.id();
226 friend bool operator!=(const MaybePOCCAAllocator
& lhs
, const MaybePOCCAAllocator
& rhs
)
228 return !(lhs
== rhs
);
233 using POCCAAllocator
= MaybePOCCAAllocator
<T
, /*POCCAValue = */true>;
235 using NonPOCCAAllocator
= MaybePOCCAAllocator
<T
, /*POCCAValue = */false>;
237 #endif // TEST_STD_VER >= 11
239 #endif // ALLOCATORS_H