67 typedef _Tp value_type;
68 typedef std::size_t size_type;
69 typedef std::ptrdiff_t difference_type;
70#if __cplusplus <= 201703L
72 typedef const _Tp* const_pointer;
73 typedef _Tp& reference;
74 typedef const _Tp& const_reference;
76 template<
typename _Tp1>
78 {
typedef __new_allocator<_Tp1> other; };
81#if __cplusplus >= 201103L
87 __attribute__((__always_inline__))
89 __new_allocator() _GLIBCXX_USE_NOEXCEPT { }
91 __attribute__((__always_inline__))
93 __new_allocator(
const __new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
95 template<
typename _Tp1>
96 __attribute__((__always_inline__))
98 __new_allocator(
const __new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
100#if __cplusplus >= 201103L
101 __new_allocator& operator=(
const __new_allocator&) =
default;
104#if __cplusplus <= 201703L
105 ~__new_allocator() _GLIBCXX_USE_NOEXCEPT { }
108 address(reference __x)
const _GLIBCXX_NOEXCEPT
112 address(const_reference __x)
const _GLIBCXX_NOEXCEPT
116#if __has_builtin(__builtin_operator_new) >= 201802L
117# define _GLIBCXX_OPERATOR_NEW __builtin_operator_new
118# define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete
120# define _GLIBCXX_OPERATOR_NEW ::operator new
121# define _GLIBCXX_OPERATOR_DELETE ::operator delete
124#pragma GCC diagnostic push
125#pragma GCC diagnostic ignored "-Wc++17-extensions"
127 __attribute__((__always_inline__))
128 _GLIBCXX20_CONSTEXPR
static void
129 _S_check_allocation_limit(
size_t __n)
131 if (__builtin_expect(__n > _S_max_size(),
false))
135 if (__n > (std::size_t(-1) /
sizeof(_Tp)))
136 std::__throw_bad_array_new_length();
137 std::__throw_bad_alloc();
143 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR _Tp*
144 allocate(size_type __n,
const void* =
static_cast<const void*
>(0))
146#if __cplusplus >= 201103L
150 static_assert(
sizeof(_Tp) != 0,
"cannot allocate incomplete types");
152 static_assert(
requires {
sizeof(_Tp); },
153 "cannot allocate incomplete types");
155 if constexpr (!
requires {
sizeof(_Tp); })
161 _S_check_allocation_limit(__n);
162#if __cpp_aligned_new && __cplusplus >= 201103L
163 if constexpr (
alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
165 std::align_val_t __al = std::align_val_t(
alignof(_Tp));
166 return static_cast<_Tp*
>(
167 _GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp), __al));
171 return static_cast<_Tp*
>(
172 _GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
176#ifdef __glibcxx_allocate_at_least
177 [[nodiscard]]
constexpr std::allocation_result<_Tp*, size_t>
178 allocate_at_least(
size_t __n)
182 if constexpr (
requires {
sizeof(_Tp); })
183 if constexpr (
alignof(_Tp) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__)
184 if constexpr (
sizeof(_Tp) < __STDCPP_DEFAULT_NEW_ALIGNMENT__)
186 _S_check_allocation_limit(__n);
187 const size_t __need = __n *
sizeof(_Tp);
188 const size_t __mask = __STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1;
189 size_t __ask = (__need + __mask) & ~__mask;
191 __ask -= __ask >> (__SIZE_WIDTH__ - 1);
192 auto* __p =
static_cast<_Tp*
>(_GLIBCXX_OPERATOR_NEW(__ask));
193 using _U8 =
const unsigned char;
194 static_assert(
sizeof(_Tp) <= ~_U8());
196 _U8 __spare = __ask - __need, __size =
sizeof(_Tp);
197 return { __p , __n + __spare / __size };
200 return { allocate(__n), __n };
205 _GLIBCXX20_CONSTEXPR
void
206 deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__)))
208#if __cpp_sized_deallocation
209# define _GLIBCXX_SIZED_DEALLOC(p, n) (p), (n) * sizeof(_Tp)
211# define _GLIBCXX_SIZED_DEALLOC(p, n) (p)
214#if __cpp_aligned_new && __cplusplus >= 201103L
215 if constexpr (
alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
217 _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n),
218 std::align_val_t(
alignof(_Tp)));
222 _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n));
225#pragma GCC diagnostic pop
226#undef _GLIBCXX_SIZED_DEALLOC
227#undef _GLIBCXX_OPERATOR_DELETE
228#undef _GLIBCXX_OPERATOR_NEW
230#if __cplusplus <= 201703L
231 __attribute__((__always_inline__))
233 max_size()
const _GLIBCXX_USE_NOEXCEPT
234 {
return _S_max_size(); }
236#if __cplusplus >= 201103L
237 template<
typename _Up,
typename... _Args>
238 __attribute__((__always_inline__))
240 construct(_Up* __p, _Args&&... __args)
241 noexcept(__is_nothrow_new_constructible<_Up, _Args...>)
244 template<
typename _Up>
245 __attribute__((__always_inline__))
253 __attribute__((__always_inline__))
255 construct(pointer __p,
const _Tp& __val)
256 { ::new((
void *)__p) _Tp(__val); }
258 __attribute__((__always_inline__))
260 destroy(pointer __p) { __p->~_Tp(); }
264 template<
typename _Up>
265 friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
266 operator==(
const __new_allocator&,
const __new_allocator<_Up>&)
270#if __cpp_impl_three_way_comparison < 201907L
271 template<
typename _Up>
272 friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
273 operator!=(
const __new_allocator&,
const __new_allocator<_Up>&)
279 __attribute__((__always_inline__))
280 _GLIBCXX_CONSTEXPR
static size_type
281 _S_max_size() _GLIBCXX_USE_NOEXCEPT
283#if __PTRDIFF_MAX__ < __SIZE_MAX__
284 return std::size_t(__PTRDIFF_MAX__) /
sizeof(_Tp);
286 return std::size_t(-1) /
sizeof(_Tp);