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 //===----------------------------------------------------------------------===//
9 #ifndef MIN_ALLOCATOR_H
10 #define MIN_ALLOCATOR_H
19 #include "test_macros.h"
27 bare_allocator() TEST_NOEXCEPT
{}
30 bare_allocator(bare_allocator
<U
>) TEST_NOEXCEPT
{}
32 T
* allocate(std::size_t n
)
34 return static_cast<T
*>(::operator new(n
*sizeof(T
)));
37 void deallocate(T
* p
, std::size_t)
39 return ::operator delete(static_cast<void*>(p
));
42 friend bool operator==(bare_allocator
, bare_allocator
) {return true;}
43 friend bool operator!=(bare_allocator x
, bare_allocator y
) {return !(x
== y
);}
48 class no_default_allocator
50 #if TEST_STD_VER >= 11
51 no_default_allocator() = delete;
53 no_default_allocator();
55 struct construct_tag
{};
56 explicit no_default_allocator(construct_tag
) {}
59 static no_default_allocator
create() {
61 return no_default_allocator(tag
);
68 no_default_allocator(no_default_allocator
<U
>) TEST_NOEXCEPT
{}
70 T
* allocate(std::size_t n
)
72 return static_cast<T
*>(::operator new(n
*sizeof(T
)));
75 void deallocate(T
* p
, std::size_t)
77 return ::operator delete(static_cast<void*>(p
));
80 friend bool operator==(no_default_allocator
, no_default_allocator
) {return true;}
81 friend bool operator!=(no_default_allocator x
, no_default_allocator y
) {return !(x
== y
);}
84 struct malloc_allocator_base
{
85 static size_t outstanding_bytes
;
86 static size_t alloc_count
;
87 static size_t dealloc_count
;
88 static bool disable_default_constructor
;
90 static size_t outstanding_alloc() {
91 assert(alloc_count
>= dealloc_count
);
92 return (alloc_count
- dealloc_count
);
96 assert(outstanding_alloc() == 0);
97 disable_default_constructor
= false;
98 outstanding_bytes
= 0;
104 size_t malloc_allocator_base::outstanding_bytes
= 0;
105 size_t malloc_allocator_base::alloc_count
= 0;
106 size_t malloc_allocator_base::dealloc_count
= 0;
107 bool malloc_allocator_base::disable_default_constructor
= false;
111 class malloc_allocator
: public malloc_allocator_base
114 typedef T value_type
;
116 malloc_allocator() TEST_NOEXCEPT
{ assert(!disable_default_constructor
); }
119 malloc_allocator(malloc_allocator
<U
>) TEST_NOEXCEPT
{}
121 T
* allocate(std::size_t n
)
123 const size_t nbytes
= n
*sizeof(T
);
125 outstanding_bytes
+= nbytes
;
126 return static_cast<T
*>(std::malloc(nbytes
));
129 void deallocate(T
* p
, std::size_t n
)
131 const size_t nbytes
= n
*sizeof(T
);
133 outstanding_bytes
-= nbytes
;
134 std::free(static_cast<void*>(p
));
137 friend bool operator==(malloc_allocator
, malloc_allocator
) {return true;}
138 friend bool operator!=(malloc_allocator x
, malloc_allocator y
) {return !(x
== y
);}
142 struct cpp03_allocator
: bare_allocator
<T
>
144 typedef T value_type
;
145 typedef value_type
* pointer
;
147 static bool construct_called
;
149 // Returned value is not used but it's not prohibited.
150 pointer
construct(pointer p
, const value_type
& val
)
152 ::new(p
) value_type(val
);
153 construct_called
= true;
157 std::size_t max_size() const
159 return UINT_MAX
/ sizeof(T
);
162 template <class T
> bool cpp03_allocator
<T
>::construct_called
= false;
165 struct cpp03_overload_allocator
: bare_allocator
<T
>
167 typedef T value_type
;
168 typedef value_type
* pointer
;
170 static bool construct_called
;
172 void construct(pointer p
, const value_type
& val
)
174 construct(p
, val
, std::is_class
<T
>());
176 void construct(pointer p
, const value_type
& val
, std::true_type
)
178 ::new(p
) value_type(val
);
179 construct_called
= true;
181 void construct(pointer p
, const value_type
& val
, std::false_type
)
183 ::new(p
) value_type(val
);
184 construct_called
= true;
187 std::size_t max_size() const
189 return UINT_MAX
/ sizeof(T
);
192 template <class T
> bool cpp03_overload_allocator
<T
>::construct_called
= false;
194 template <class T
, class = std::integral_constant
<size_t, 0> > class min_pointer
;
195 template <class T
, class ID
> class min_pointer
<const T
, ID
>;
196 template <class ID
> class min_pointer
<void, ID
>;
197 template <class ID
> class min_pointer
<const void, ID
>;
198 template <class T
> class min_allocator
;
201 class min_pointer
<const void, ID
>
205 min_pointer() TEST_NOEXCEPT
= default;
206 min_pointer(std::nullptr_t
) TEST_NOEXCEPT
: ptr_(nullptr) {}
208 min_pointer(min_pointer
<T
, ID
> p
) TEST_NOEXCEPT
: ptr_(p
.ptr_
) {}
210 explicit operator bool() const {return ptr_
!= nullptr;}
212 friend bool operator==(min_pointer x
, min_pointer y
) {return x
.ptr_
== y
.ptr_
;}
213 friend bool operator!=(min_pointer x
, min_pointer y
) {return !(x
== y
);}
214 template <class U
, class XID
> friend class min_pointer
;
218 class min_pointer
<void, ID
>
222 min_pointer() TEST_NOEXCEPT
= default;
223 TEST_CONSTEXPR_CXX14
min_pointer(std::nullptr_t
) TEST_NOEXCEPT
: ptr_(nullptr) {}
225 class = typename
std::enable_if
227 !std::is_const
<T
>::value
230 TEST_CONSTEXPR_CXX14
min_pointer(min_pointer
<T
, ID
> p
) TEST_NOEXCEPT
: ptr_(p
.ptr_
) {}
232 TEST_CONSTEXPR_CXX14
explicit operator bool() const {return ptr_
!= nullptr;}
234 TEST_CONSTEXPR_CXX14
friend bool operator==(min_pointer x
, min_pointer y
) {return x
.ptr_
== y
.ptr_
;}
235 TEST_CONSTEXPR_CXX14
friend bool operator!=(min_pointer x
, min_pointer y
) {return !(x
== y
);}
236 template <class U
, class XID
> friend class min_pointer
;
239 template <class T
, class ID
>
244 TEST_CONSTEXPR_CXX14
explicit min_pointer(T
* p
) TEST_NOEXCEPT
: ptr_(p
) {}
246 min_pointer() TEST_NOEXCEPT
= default;
247 TEST_CONSTEXPR_CXX14
min_pointer(std::nullptr_t
) TEST_NOEXCEPT
: ptr_(nullptr) {}
248 TEST_CONSTEXPR_CXX14
explicit min_pointer(min_pointer
<void, ID
> p
) TEST_NOEXCEPT
: ptr_(static_cast<T
*>(p
.ptr_
)) {}
250 TEST_CONSTEXPR_CXX14
explicit operator bool() const {return ptr_
!= nullptr;}
252 typedef std::ptrdiff_t difference_type
;
253 typedef T
& reference
;
255 typedef T value_type
;
256 typedef std::random_access_iterator_tag iterator_category
;
258 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *ptr_
;}
259 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return ptr_
;}
261 TEST_CONSTEXPR_CXX14 min_pointer
& operator++() {++ptr_
; return *this;}
262 TEST_CONSTEXPR_CXX14 min_pointer
operator++(int) {min_pointer
tmp(*this); ++ptr_
; return tmp
;}
264 TEST_CONSTEXPR_CXX14 min_pointer
& operator--() {--ptr_
; return *this;}
265 TEST_CONSTEXPR_CXX14 min_pointer
operator--(int) {min_pointer
tmp(*this); --ptr_
; return tmp
;}
267 TEST_CONSTEXPR_CXX14 min_pointer
& operator+=(difference_type n
) {ptr_
+= n
; return *this;}
268 TEST_CONSTEXPR_CXX14 min_pointer
& operator-=(difference_type n
) {ptr_
-= n
; return *this;}
270 TEST_CONSTEXPR_CXX14 min_pointer
operator+(difference_type n
) const
272 min_pointer
tmp(*this);
277 friend TEST_CONSTEXPR_CXX14 min_pointer
operator+(difference_type n
, min_pointer x
)
282 TEST_CONSTEXPR_CXX14 min_pointer
operator-(difference_type n
) const
284 min_pointer
tmp(*this);
289 friend TEST_CONSTEXPR_CXX14 difference_type
operator-(min_pointer x
, min_pointer y
)
291 return x
.ptr_
- y
.ptr_
;
294 TEST_CONSTEXPR_CXX14 reference
operator[](difference_type n
) const {return ptr_
[n
];}
296 friend TEST_CONSTEXPR_CXX14
bool operator< (min_pointer x
, min_pointer y
) {return x
.ptr_
< y
.ptr_
;}
297 friend TEST_CONSTEXPR_CXX14
bool operator> (min_pointer x
, min_pointer y
) {return y
< x
;}
298 friend TEST_CONSTEXPR_CXX14
bool operator<=(min_pointer x
, min_pointer y
) {return !(y
< x
);}
299 friend TEST_CONSTEXPR_CXX14
bool operator>=(min_pointer x
, min_pointer y
) {return !(x
< y
);}
301 static TEST_CONSTEXPR_CXX14 min_pointer
pointer_to(T
& t
) {return min_pointer(std::addressof(t
));}
303 friend TEST_CONSTEXPR_CXX14
bool operator==(min_pointer x
, min_pointer y
) {return x
.ptr_
== y
.ptr_
;}
304 friend TEST_CONSTEXPR_CXX14
bool operator!=(min_pointer x
, min_pointer y
) {return !(x
== y
);}
305 template <class U
, class XID
> friend class min_pointer
;
306 template <class U
> friend class min_allocator
;
309 template <class T
, class ID
>
310 class min_pointer
<const T
, ID
>
314 TEST_CONSTEXPR_CXX14
explicit min_pointer(const T
* p
) : ptr_(p
) {}
316 min_pointer() TEST_NOEXCEPT
= default;
317 TEST_CONSTEXPR_CXX14
min_pointer(std::nullptr_t
) : ptr_(nullptr) {}
318 TEST_CONSTEXPR_CXX14
min_pointer(min_pointer
<T
, ID
> p
) : ptr_(p
.ptr_
) {}
319 TEST_CONSTEXPR_CXX14
explicit min_pointer(min_pointer
<const void, ID
> p
) : ptr_(static_cast<const T
*>(p
.ptr_
)) {}
321 TEST_CONSTEXPR_CXX14
explicit operator bool() const {return ptr_
!= nullptr;}
323 typedef std::ptrdiff_t difference_type
;
324 typedef const T
& reference
;
325 typedef const T
* pointer
;
326 typedef const T value_type
;
327 typedef std::random_access_iterator_tag iterator_category
;
329 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *ptr_
;}
330 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return ptr_
;}
332 TEST_CONSTEXPR_CXX14 min_pointer
& operator++() {++ptr_
; return *this;}
333 TEST_CONSTEXPR_CXX14 min_pointer
operator++(int) {min_pointer
tmp(*this); ++ptr_
; return tmp
;}
335 TEST_CONSTEXPR_CXX14 min_pointer
& operator--() {--ptr_
; return *this;}
336 TEST_CONSTEXPR_CXX14 min_pointer
operator--(int) {min_pointer
tmp(*this); --ptr_
; return tmp
;}
338 TEST_CONSTEXPR_CXX14 min_pointer
& operator+=(difference_type n
) {ptr_
+= n
; return *this;}
339 TEST_CONSTEXPR_CXX14 min_pointer
& operator-=(difference_type n
) {ptr_
-= n
; return *this;}
341 TEST_CONSTEXPR_CXX14 min_pointer
operator+(difference_type n
) const
343 min_pointer
tmp(*this);
348 friend TEST_CONSTEXPR_CXX14 min_pointer
operator+(difference_type n
, min_pointer x
)
353 TEST_CONSTEXPR_CXX14 min_pointer
operator-(difference_type n
) const
355 min_pointer
tmp(*this);
360 friend TEST_CONSTEXPR_CXX14 difference_type
operator-(min_pointer x
, min_pointer y
)
362 return x
.ptr_
- y
.ptr_
;
365 TEST_CONSTEXPR_CXX14 reference
operator[](difference_type n
) const {return ptr_
[n
];}
367 friend TEST_CONSTEXPR_CXX14
bool operator< (min_pointer x
, min_pointer y
) {return x
.ptr_
< y
.ptr_
;}
368 friend TEST_CONSTEXPR_CXX14
bool operator> (min_pointer x
, min_pointer y
) {return y
< x
;}
369 friend TEST_CONSTEXPR_CXX14
bool operator<=(min_pointer x
, min_pointer y
) {return !(y
< x
);}
370 friend TEST_CONSTEXPR_CXX14
bool operator>=(min_pointer x
, min_pointer y
) {return !(x
< y
);}
372 static TEST_CONSTEXPR_CXX14 min_pointer
pointer_to(const T
& t
) {return min_pointer(std::addressof(t
));}
374 friend TEST_CONSTEXPR_CXX14
bool operator==(min_pointer x
, min_pointer y
) {return x
.ptr_
== y
.ptr_
;}
375 friend TEST_CONSTEXPR_CXX14
bool operator!=(min_pointer x
, min_pointer y
) {return !(x
== y
);}
376 template <class U
, class XID
> friend class min_pointer
;
379 template <class T
, class ID
>
380 TEST_CONSTEXPR_CXX14
inline
382 operator==(min_pointer
<T
, ID
> x
, std::nullptr_t
)
384 return !static_cast<bool>(x
);
387 template <class T
, class ID
>
388 TEST_CONSTEXPR_CXX14
inline
390 operator==(std::nullptr_t
, min_pointer
<T
, ID
> x
)
392 return !static_cast<bool>(x
);
395 template <class T
, class ID
>
396 TEST_CONSTEXPR_CXX14
inline
398 operator!=(min_pointer
<T
, ID
> x
, std::nullptr_t
)
400 return static_cast<bool>(x
);
403 template <class T
, class ID
>
404 TEST_CONSTEXPR_CXX14
inline
406 operator!=(std::nullptr_t
, min_pointer
<T
, ID
> x
)
408 return static_cast<bool>(x
);
415 typedef T value_type
;
416 typedef min_pointer
<T
> pointer
;
418 min_allocator() = default;
420 TEST_CONSTEXPR_CXX20
min_allocator(min_allocator
<U
>) {}
422 TEST_CONSTEXPR_CXX20 pointer
allocate(std::ptrdiff_t n
)
424 return pointer(std::allocator
<T
>().allocate(n
));
427 TEST_CONSTEXPR_CXX20
void deallocate(pointer p
, std::ptrdiff_t n
)
429 std::allocator
<T
>().deallocate(p
.ptr_
, n
);
432 TEST_CONSTEXPR_CXX20
friend bool operator==(min_allocator
, min_allocator
) {return true;}
433 TEST_CONSTEXPR_CXX20
friend bool operator!=(min_allocator x
, min_allocator y
) {return !(x
== y
);}
437 class explicit_allocator
440 typedef T value_type
;
442 TEST_CONSTEXPR_CXX20
explicit_allocator() TEST_NOEXCEPT
{}
445 TEST_CONSTEXPR_CXX20
explicit explicit_allocator(explicit_allocator
<U
>) TEST_NOEXCEPT
{}
447 TEST_CONSTEXPR_CXX20 T
* allocate(std::size_t n
)
449 return static_cast<T
*>(std::allocator
<T
>().allocate(n
));
452 TEST_CONSTEXPR_CXX20
void deallocate(T
* p
, std::size_t n
)
454 std::allocator
<T
>().deallocate(p
, n
);
457 TEST_CONSTEXPR_CXX20
friend bool operator==(explicit_allocator
, explicit_allocator
) {return true;}
458 TEST_CONSTEXPR_CXX20
friend bool operator!=(explicit_allocator x
, explicit_allocator y
) {return !(x
== y
);}
461 #endif // MIN_ALLOCATOR_H