[flang][runtime] Make defined formatted I/O process format elementally (#74150)
[llvm-project.git] / libcxx / test / support / min_allocator.h
blob13ee98289c36b7ac11374fe24d5d065175e5a0f4
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef MIN_ALLOCATOR_H
10 #define MIN_ALLOCATOR_H
12 #include <cassert>
13 #include <climits>
14 #include <cstddef>
15 #include <cstdlib>
16 #include <iterator>
17 #include <memory>
18 #include <new>
19 #include <type_traits>
20 #include <cstring>
22 #include "test_macros.h"
24 template <class T>
25 class bare_allocator
27 public:
28 typedef T value_type;
30 bare_allocator() TEST_NOEXCEPT {}
32 template <class U>
33 bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
35 T* allocate(std::size_t n)
37 return static_cast<T*>(::operator new(n*sizeof(T)));
40 void deallocate(T* p, std::size_t)
42 return ::operator delete(static_cast<void*>(p));
45 friend bool operator==(bare_allocator, bare_allocator) {return true;}
46 friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);}
50 template <class T>
51 class no_default_allocator
53 #if TEST_STD_VER >= 11
54 no_default_allocator() = delete;
55 #else
56 no_default_allocator();
57 #endif
58 struct construct_tag {};
59 explicit no_default_allocator(construct_tag) {}
61 public:
62 static no_default_allocator create() {
63 construct_tag tag;
64 return no_default_allocator(tag);
67 public:
68 typedef T value_type;
70 template <class U>
71 no_default_allocator(no_default_allocator<U>) TEST_NOEXCEPT {}
73 T* allocate(std::size_t n)
75 return static_cast<T*>(::operator new(n*sizeof(T)));
78 void deallocate(T* p, std::size_t)
80 return ::operator delete(static_cast<void*>(p));
83 friend bool operator==(no_default_allocator, no_default_allocator) {return true;}
84 friend bool operator!=(no_default_allocator x, no_default_allocator y) {return !(x == y);}
87 struct malloc_allocator_base {
88 static std::size_t outstanding_bytes;
89 static std::size_t alloc_count;
90 static std::size_t dealloc_count;
91 static bool disable_default_constructor;
93 static std::size_t outstanding_alloc() {
94 assert(alloc_count >= dealloc_count);
95 return (alloc_count - dealloc_count);
98 static void reset() {
99 assert(outstanding_alloc() == 0);
100 disable_default_constructor = false;
101 outstanding_bytes = 0;
102 alloc_count = 0;
103 dealloc_count = 0;
107 size_t malloc_allocator_base::outstanding_bytes = 0;
108 size_t malloc_allocator_base::alloc_count = 0;
109 size_t malloc_allocator_base::dealloc_count = 0;
110 bool malloc_allocator_base::disable_default_constructor = false;
113 template <class T>
114 class malloc_allocator : public malloc_allocator_base
116 public:
117 typedef T value_type;
119 malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); }
121 template <class U>
122 malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {}
124 T* allocate(std::size_t n)
126 const std::size_t nbytes = n*sizeof(T);
127 ++alloc_count;
128 outstanding_bytes += nbytes;
129 return static_cast<T*>(std::malloc(nbytes));
132 void deallocate(T* p, std::size_t n)
134 const std::size_t nbytes = n*sizeof(T);
135 ++dealloc_count;
136 outstanding_bytes -= nbytes;
137 std::free(static_cast<void*>(p));
140 friend bool operator==(malloc_allocator, malloc_allocator) {return true;}
141 friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);}
144 template <class T>
145 struct cpp03_allocator : bare_allocator<T>
147 typedef T value_type;
148 typedef value_type* pointer;
150 static bool construct_called;
152 // Returned value is not used but it's not prohibited.
153 pointer construct(pointer p, const value_type& val)
155 ::new(p) value_type(val);
156 construct_called = true;
157 return p;
160 std::size_t max_size() const
162 return UINT_MAX / sizeof(T);
165 template <class T> bool cpp03_allocator<T>::construct_called = false;
167 template <class T>
168 struct cpp03_overload_allocator : bare_allocator<T>
170 typedef T value_type;
171 typedef value_type* pointer;
173 static bool construct_called;
175 void construct(pointer p, const value_type& val)
177 construct(p, val, std::is_class<T>());
179 void construct(pointer p, const value_type& val, std::true_type)
181 ::new(p) value_type(val);
182 construct_called = true;
184 void construct(pointer p, const value_type& val, std::false_type)
186 ::new(p) value_type(val);
187 construct_called = true;
190 std::size_t max_size() const
192 return UINT_MAX / sizeof(T);
195 template <class T> bool cpp03_overload_allocator<T>::construct_called = false;
197 template <class T, class = std::integral_constant<std::size_t, 0> > class min_pointer;
198 template <class T, class ID> class min_pointer<const T, ID>;
199 template <class ID> class min_pointer<void, ID>;
200 template <class ID> class min_pointer<const void, ID>;
201 template <class T> class min_allocator;
203 template <class ID>
204 class min_pointer<const void, ID>
206 const void* ptr_;
207 public:
208 min_pointer() TEST_NOEXCEPT = default;
209 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
210 template <class T>
211 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
213 explicit operator bool() const {return ptr_ != nullptr;}
215 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
216 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
217 template <class U, class XID> friend class min_pointer;
220 template <class ID>
221 class min_pointer<void, ID>
223 void* ptr_;
224 public:
225 min_pointer() TEST_NOEXCEPT = default;
226 TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
227 template <class T,
228 class = typename std::enable_if
230 !std::is_const<T>::value
231 >::type
233 TEST_CONSTEXPR_CXX14 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
235 TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;}
237 TEST_CONSTEXPR_CXX14 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
238 TEST_CONSTEXPR_CXX14 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
239 template <class U, class XID> friend class min_pointer;
242 template <class T, class ID>
243 class min_pointer
245 T* ptr_;
247 TEST_CONSTEXPR_CXX14 explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
248 public:
249 min_pointer() TEST_NOEXCEPT = default;
250 TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
251 TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer<void, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
253 TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;}
255 typedef std::ptrdiff_t difference_type;
256 typedef T& reference;
257 typedef T* pointer;
258 typedef T value_type;
259 typedef std::random_access_iterator_tag iterator_category;
261 TEST_CONSTEXPR_CXX14 reference operator*() const {return *ptr_;}
262 TEST_CONSTEXPR_CXX14 pointer operator->() const {return ptr_;}
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--() {--ptr_; return *this;}
268 TEST_CONSTEXPR_CXX14 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
270 TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
271 TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
273 TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const
275 min_pointer tmp(*this);
276 tmp += n;
277 return tmp;
280 friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x)
282 return x + n;
285 TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const
287 min_pointer tmp(*this);
288 tmp -= n;
289 return tmp;
292 friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y)
294 return x.ptr_ - y.ptr_;
297 TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return ptr_[n];}
299 friend TEST_CONSTEXPR_CXX14 bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
300 friend TEST_CONSTEXPR_CXX14 bool operator> (min_pointer x, min_pointer y) {return y < x;}
301 friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
302 friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
304 static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
306 friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
307 friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
308 template <class U, class XID> friend class min_pointer;
309 template <class U> friend class min_allocator;
312 template <class T, class ID>
313 class min_pointer<const T, ID>
315 const T* ptr_;
317 TEST_CONSTEXPR_CXX14 explicit min_pointer(const T* p) : ptr_(p) {}
318 public:
319 min_pointer() TEST_NOEXCEPT = default;
320 TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) : ptr_(nullptr) {}
321 TEST_CONSTEXPR_CXX14 min_pointer(min_pointer<T, ID> p) : ptr_(p.ptr_) {}
322 TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer<const void, ID> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
324 TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;}
326 typedef std::ptrdiff_t difference_type;
327 typedef const T& reference;
328 typedef const T* pointer;
329 typedef const T value_type;
330 typedef std::random_access_iterator_tag iterator_category;
332 TEST_CONSTEXPR_CXX14 reference operator*() const {return *ptr_;}
333 TEST_CONSTEXPR_CXX14 pointer operator->() const {return ptr_;}
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--() {--ptr_; return *this;}
339 TEST_CONSTEXPR_CXX14 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
341 TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
342 TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
344 TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const
346 min_pointer tmp(*this);
347 tmp += n;
348 return tmp;
351 friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x)
353 return x + n;
356 TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const
358 min_pointer tmp(*this);
359 tmp -= n;
360 return tmp;
363 friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y)
365 return x.ptr_ - y.ptr_;
368 TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return ptr_[n];}
370 friend TEST_CONSTEXPR_CXX14 bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
371 friend TEST_CONSTEXPR_CXX14 bool operator> (min_pointer x, min_pointer y) {return y < x;}
372 friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
373 friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
375 static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
377 friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
378 friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) {return x.ptr_ != y.ptr_;}
379 friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, std::nullptr_t) {return x.ptr_ == nullptr;}
380 friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, std::nullptr_t) {return x.ptr_ != nullptr;}
381 friend TEST_CONSTEXPR_CXX14 bool operator==(std::nullptr_t, min_pointer x) {return x.ptr_ == nullptr;}
382 friend TEST_CONSTEXPR_CXX14 bool operator!=(std::nullptr_t, min_pointer x) {return x.ptr_ != nullptr;}
383 template <class U, class XID> friend class min_pointer;
386 template <class T>
387 class min_allocator
389 public:
390 typedef T value_type;
391 typedef min_pointer<T> pointer;
393 min_allocator() = default;
394 template <class U>
395 TEST_CONSTEXPR_CXX20 min_allocator(min_allocator<U>) {}
397 TEST_CONSTEXPR_CXX20 pointer allocate(std::ptrdiff_t n)
399 return pointer(std::allocator<T>().allocate(n));
402 TEST_CONSTEXPR_CXX20 void deallocate(pointer p, std::ptrdiff_t n)
404 std::allocator<T>().deallocate(p.ptr_, n);
407 TEST_CONSTEXPR_CXX20 friend bool operator==(min_allocator, min_allocator) {return true;}
408 TEST_CONSTEXPR_CXX20 friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}
411 template <class T>
412 class explicit_allocator
414 public:
415 typedef T value_type;
417 TEST_CONSTEXPR_CXX20 explicit_allocator() TEST_NOEXCEPT {}
419 template <class U>
420 TEST_CONSTEXPR_CXX20 explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {}
422 TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n)
424 return static_cast<T*>(std::allocator<T>().allocate(n));
427 TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n)
429 std::allocator<T>().deallocate(p, n);
432 TEST_CONSTEXPR_CXX20 friend bool operator==(explicit_allocator, explicit_allocator) {return true;}
433 TEST_CONSTEXPR_CXX20 friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);}
436 template <class T>
437 class unaligned_allocator {
438 public:
439 static_assert(TEST_ALIGNOF(T) == 1, "Type T cannot be created on unaligned address (UB)");
440 typedef T value_type;
442 TEST_CONSTEXPR_CXX20 unaligned_allocator() TEST_NOEXCEPT {}
444 template <class U>
445 TEST_CONSTEXPR_CXX20 explicit unaligned_allocator(unaligned_allocator<U>) TEST_NOEXCEPT {}
447 TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return std::allocator<T>().allocate(n + 1) + 1; }
449 TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { std::allocator<T>().deallocate(p - 1, n + 1); }
451 TEST_CONSTEXPR_CXX20 friend bool operator==(unaligned_allocator, unaligned_allocator) { return true; }
452 TEST_CONSTEXPR_CXX20 friend bool operator!=(unaligned_allocator x, unaligned_allocator y) { return !(x == y); }
455 template <class T>
456 class safe_allocator {
457 public:
458 typedef T value_type;
460 TEST_CONSTEXPR_CXX20 safe_allocator() TEST_NOEXCEPT {}
462 template <class U>
463 TEST_CONSTEXPR_CXX20 safe_allocator(safe_allocator<U>) TEST_NOEXCEPT {}
465 TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) {
466 T* memory = std::allocator<T>().allocate(n);
467 if (!TEST_IS_CONSTANT_EVALUATED)
468 std::memset(memory, 0, sizeof(T) * n);
470 return memory;
473 TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) {
474 if (!TEST_IS_CONSTANT_EVALUATED)
475 DoNotOptimize(std::memset(p, 0, sizeof(T) * n));
476 std::allocator<T>().deallocate(p, n);
479 TEST_CONSTEXPR_CXX20 friend bool operator==(safe_allocator, safe_allocator) { return true; }
480 TEST_CONSTEXPR_CXX20 friend bool operator!=(safe_allocator x, safe_allocator y) { return !(x == y); }
483 #endif // MIN_ALLOCATOR_H