xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/__memory/allocator.h (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___MEMORY_ALLOCATOR_H
11 #define _LIBCPP___MEMORY_ALLOCATOR_H
12 
13 #include <__config>
14 #include <__memory/allocator_traits.h>
15 #include <cstddef>
16 #include <new>
17 #include <stdexcept>
18 #include <type_traits>
19 
20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #pragma GCC system_header
22 #endif
23 
24 _LIBCPP_PUSH_MACROS
25 #include <__undef_macros>
26 
27 _LIBCPP_BEGIN_NAMESPACE_STD
28 
29 template <class _Tp> class allocator;
30 
31 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
32 template <>
33 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>
34 {
35 public:
36     typedef void*             pointer;
37     typedef const void*       const_pointer;
38     typedef void              value_type;
39 
40     template <class _Up> struct rebind {typedef allocator<_Up> other;};
41 };
42 
43 template <>
44 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>
45 {
46 public:
47     typedef const void*       pointer;
48     typedef const void*       const_pointer;
49     typedef const void        value_type;
50 
51     template <class _Up> struct rebind {typedef allocator<_Up> other;};
52 };
53 #endif
54 
55 // allocator
56 
57 template <class _Tp>
58 class _LIBCPP_TEMPLATE_VIS allocator
59 {
60 public:
61     typedef size_t      size_type;
62     typedef ptrdiff_t   difference_type;
63     typedef _Tp         value_type;
64     typedef true_type   propagate_on_container_move_assignment;
65     typedef true_type   is_always_equal;
66 
67     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator()68     allocator() _NOEXCEPT { }
69 
70     template <class _Up>
71     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up> &)72     allocator(const allocator<_Up>&) _NOEXCEPT { }
73 
74     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocate(size_t __n)75     _Tp* allocate(size_t __n) {
76         if (__n > allocator_traits<allocator>::max_size(*this))
77             __throw_length_error("allocator<T>::allocate(size_t n)"
78                                  " 'n' exceeds maximum supported size");
79         if (__libcpp_is_constant_evaluated()) {
80             return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
81         } else {
82             return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
83         }
84     }
85 
86     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
deallocate(_Tp * __p,size_t __n)87     void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
88         if (__libcpp_is_constant_evaluated()) {
89             ::operator delete(__p);
90         } else {
91             _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
92         }
93     }
94 
95     // C++20 Removed members
96 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
97     _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp*       pointer;
98     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
99     _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp&       reference;
100     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
101 
102     template <class _Up>
103     struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
104         typedef allocator<_Up> other;
105     };
106 
107     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
address(reference __x)108     pointer address(reference __x) const _NOEXCEPT {
109         return _VSTD::addressof(__x);
110     }
111     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
address(const_reference __x)112     const_pointer address(const_reference __x) const _NOEXCEPT {
113         return _VSTD::addressof(__x);
114     }
115 
116     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
allocate(size_t __n,const void *)117     _Tp* allocate(size_t __n, const void*) {
118         return allocate(__n);
119     }
120 
max_size()121     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
122         return size_type(~0) / sizeof(_Tp);
123     }
124 
125     template <class _Up, class... _Args>
126     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
construct(_Up * __p,_Args &&...__args)127     void construct(_Up* __p, _Args&&... __args) {
128         ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
129     }
130 
131     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
destroy(pointer __p)132     void destroy(pointer __p) {
133         __p->~_Tp();
134     }
135 #endif
136 };
137 
138 template <class _Tp>
139 class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
140 {
141 public:
142     typedef size_t      size_type;
143     typedef ptrdiff_t   difference_type;
144     typedef const _Tp   value_type;
145     typedef true_type   propagate_on_container_move_assignment;
146     typedef true_type   is_always_equal;
147 
148     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator()149     allocator() _NOEXCEPT { }
150 
151     template <class _Up>
152     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up> &)153     allocator(const allocator<_Up>&) _NOEXCEPT { }
154 
155     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocate(size_t __n)156     const _Tp* allocate(size_t __n) {
157         if (__n > allocator_traits<allocator>::max_size(*this))
158             __throw_length_error("allocator<const T>::allocate(size_t n)"
159                                  " 'n' exceeds maximum supported size");
160         if (__libcpp_is_constant_evaluated()) {
161             return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
162         } else {
163             return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
164         }
165     }
166 
167     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
deallocate(const _Tp * __p,size_t __n)168     void deallocate(const _Tp* __p, size_t __n) {
169         if (__libcpp_is_constant_evaluated()) {
170             ::operator delete(const_cast<_Tp*>(__p));
171         } else {
172             _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
173         }
174     }
175 
176     // C++20 Removed members
177 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
178     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
179     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
180     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
181     _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
182 
183     template <class _Up>
184     struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
185         typedef allocator<_Up> other;
186     };
187 
188     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
address(const_reference __x)189     const_pointer address(const_reference __x) const _NOEXCEPT {
190         return _VSTD::addressof(__x);
191     }
192 
193     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
allocate(size_t __n,const void *)194     const _Tp* allocate(size_t __n, const void*) {
195         return allocate(__n);
196     }
197 
max_size()198     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
199         return size_type(~0) / sizeof(_Tp);
200     }
201 
202     template <class _Up, class... _Args>
203     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
construct(_Up * __p,_Args &&...__args)204     void construct(_Up* __p, _Args&&... __args) {
205         ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
206     }
207 
208     _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
destroy(pointer __p)209     void destroy(pointer __p) {
210         __p->~_Tp();
211     }
212 #endif
213 };
214 
215 template <class _Tp, class _Up>
216 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
217 bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
218 
219 template <class _Tp, class _Up>
220 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
221 bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
222 
223 _LIBCPP_END_NAMESPACE_STD
224 
225 _LIBCPP_POP_MACROS
226 
227 #endif // _LIBCPP___MEMORY_ALLOCATOR_H
228