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 //===----------------------------------------------------------------------===//
15 #include <type_traits>
18 #include "test_macros.h"
20 #if TEST_STD_VER >= 11
27 explicit A1(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
31 int id() const {return id_
;}
33 static bool copy_called
;
34 static bool move_called
;
35 static bool allocate_called
;
36 static std::pair
<T
*, std::size_t> deallocate_called
;
38 A1(const A1
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
39 A1(A1
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
40 A1
& operator=(const A1
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
41 A1
& operator=(A1
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
44 A1(const A1
<U
>& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
46 A1(A1
<U
>&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
48 T
* allocate(std::size_t n
)
50 allocate_called
= true;
54 void deallocate(T
* p
, std::size_t n
)
56 deallocate_called
= std::pair
<T
*, std::size_t>(p
, n
);
59 std::size_t max_size() const {return id_
;}
62 template <class T
> bool A1
<T
>::copy_called
= false;
63 template <class T
> bool A1
<T
>::move_called
= false;
64 template <class T
> bool A1
<T
>::allocate_called
= false;
65 template <class T
> std::pair
<T
*, std::size_t> A1
<T
>::deallocate_called
;
67 template <class T
, class U
>
69 bool operator==(const A1
<T
>& x
, const A1
<U
>& y
)
71 return x
.id() == y
.id();
74 template <class T
, class U
>
76 bool operator!=(const A1
<T
>& x
, const A1
<U
>& y
)
86 explicit A2(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
90 typedef unsigned size_type
;
91 typedef int difference_type
;
93 typedef std::true_type propagate_on_container_move_assignment
;
95 int id() const {return id_
;}
97 static bool copy_called
;
98 static bool move_called
;
99 static bool allocate_called
;
101 A2(const A2
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
102 A2(A2
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
103 A2
& operator=(const A2
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
104 A2
& operator=(A2
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
106 T
* allocate(std::size_t, const void* hint
)
108 allocate_called
= true;
109 return (T
*) const_cast<void *>(hint
);
113 template <class T
> bool A2
<T
>::copy_called
= false;
114 template <class T
> bool A2
<T
>::move_called
= false;
115 template <class T
> bool A2
<T
>::allocate_called
= false;
117 template <class T
, class U
>
119 bool operator==(const A2
<T
>& x
, const A2
<U
>& y
)
121 return x
.id() == y
.id();
124 template <class T
, class U
>
126 bool operator!=(const A2
<T
>& x
, const A2
<U
>& y
)
136 explicit A3(int id
= 0) TEST_NOEXCEPT
: id_(id
) {}
138 typedef T value_type
;
140 typedef std::true_type propagate_on_container_copy_assignment
;
141 typedef std::true_type propagate_on_container_swap
;
143 int id() const {return id_
;}
145 static bool copy_called
;
146 static bool move_called
;
147 static bool constructed
;
148 static bool destroy_called
;
150 A3(const A3
& a
) TEST_NOEXCEPT
: id_(a
.id()) {copy_called
= true;}
151 A3(A3
&& a
) TEST_NOEXCEPT
: id_(a
.id()) {move_called
= true;}
152 A3
& operator=(const A3
& a
) TEST_NOEXCEPT
{ id_
= a
.id(); copy_called
= true; return *this;}
153 A3
& operator=(A3
&& a
) TEST_NOEXCEPT
{ id_
= a
.id(); move_called
= true; return *this;}
155 template <class U
, class ...Args
>
156 void construct(U
* p
, Args
&& ...args
)
158 ::new (p
) U(std::forward
<Args
>(args
)...);
166 destroy_called
= true;
169 A3
select_on_container_copy_construction() const {return A3(-1);}
172 template <class T
> bool A3
<T
>::copy_called
= false;
173 template <class T
> bool A3
<T
>::move_called
= false;
174 template <class T
> bool A3
<T
>::constructed
= false;
175 template <class T
> bool A3
<T
>::destroy_called
= false;
177 template <class T
, class U
>
179 bool operator==(const A3
<T
>& x
, const A3
<U
>& y
)
181 return x
.id() == y
.id();
184 template <class T
, class U
>
186 bool operator!=(const A3
<T
>& x
, const A3
<U
>& y
)
191 template <class T
, bool POCCAValue
>
192 class MaybePOCCAAllocator
{
194 bool* copy_assigned_into_
= nullptr;
196 template<class, bool> friend class MaybePOCCAAllocator
;
199 typedef std::integral_constant
<bool, POCCAValue
> propagate_on_container_copy_assignment
;
200 typedef T value_type
;
204 typedef MaybePOCCAAllocator
<U
, POCCAValue
> other
;
207 TEST_CONSTEXPR
MaybePOCCAAllocator() = default;
208 TEST_CONSTEXPR
MaybePOCCAAllocator(int id
, bool* copy_assigned_into
)
209 : id_(id
), copy_assigned_into_(copy_assigned_into
) {}
212 MaybePOCCAAllocator(const MaybePOCCAAllocator
<U
, POCCAValue
>& that
)
213 : id_(that
.id_
), copy_assigned_into_(that
.copy_assigned_into_
) {}
215 MaybePOCCAAllocator(const MaybePOCCAAllocator
&) = default;
216 TEST_CONSTEXPR_CXX14 MaybePOCCAAllocator
& operator=(const MaybePOCCAAllocator
& a
)
219 if (copy_assigned_into_
)
220 *copy_assigned_into_
= true;
224 TEST_CONSTEXPR_CXX20 T
* allocate(std::size_t n
)
226 return std::allocator
<T
>().allocate(n
);
229 TEST_CONSTEXPR_CXX20
void deallocate(T
* ptr
, std::size_t n
)
231 std::allocator
<T
>().deallocate(ptr
, n
);
234 TEST_CONSTEXPR
int id() const { return id_
; }
237 TEST_CONSTEXPR
friend bool operator==(const MaybePOCCAAllocator
& lhs
, const MaybePOCCAAllocator
<U
, POCCAValue
>& rhs
)
239 return lhs
.id() == rhs
.id();
243 TEST_CONSTEXPR
friend bool operator!=(const MaybePOCCAAllocator
& lhs
, const MaybePOCCAAllocator
<U
, POCCAValue
>& rhs
)
245 return !(lhs
== rhs
);
250 using POCCAAllocator
= MaybePOCCAAllocator
<T
, /*POCCAValue = */true>;
252 using NonPOCCAAllocator
= MaybePOCCAAllocator
<T
, /*POCCAValue = */false>;
254 #endif // TEST_STD_VER >= 11
256 #endif // ALLOCATORS_H