xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/new (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
1*4d6fc14bSjoerg// -*- C++ -*-
2*4d6fc14bSjoerg//===----------------------------- new ------------------------------------===//
3*4d6fc14bSjoerg//
4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information.
6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4d6fc14bSjoerg//
8*4d6fc14bSjoerg//===----------------------------------------------------------------------===//
9*4d6fc14bSjoerg
10*4d6fc14bSjoerg#ifndef _LIBCPP_NEW
11*4d6fc14bSjoerg#define _LIBCPP_NEW
12*4d6fc14bSjoerg
13*4d6fc14bSjoerg/*
14*4d6fc14bSjoerg    new synopsis
15*4d6fc14bSjoerg
16*4d6fc14bSjoergnamespace std
17*4d6fc14bSjoerg{
18*4d6fc14bSjoerg
19*4d6fc14bSjoergclass bad_alloc
20*4d6fc14bSjoerg    : public exception
21*4d6fc14bSjoerg{
22*4d6fc14bSjoergpublic:
23*4d6fc14bSjoerg    bad_alloc() noexcept;
24*4d6fc14bSjoerg    bad_alloc(const bad_alloc&) noexcept;
25*4d6fc14bSjoerg    bad_alloc& operator=(const bad_alloc&) noexcept;
26*4d6fc14bSjoerg    virtual const char* what() const noexcept;
27*4d6fc14bSjoerg};
28*4d6fc14bSjoerg
29*4d6fc14bSjoergclass bad_array_new_length : public bad_alloc // C++14
30*4d6fc14bSjoerg{
31*4d6fc14bSjoergpublic:
32*4d6fc14bSjoerg    bad_array_new_length() noexcept;
33*4d6fc14bSjoerg};
34*4d6fc14bSjoerg
35*4d6fc14bSjoergenum class align_val_t : size_t {}; // C++17
36*4d6fc14bSjoerg
37*4d6fc14bSjoergstruct destroying_delete_t { // C++20
38*4d6fc14bSjoerg  explicit destroying_delete_t() = default;
39*4d6fc14bSjoerg};
40*4d6fc14bSjoerginline constexpr destroying_delete_t destroying_delete{}; // C++20
41*4d6fc14bSjoerg
42*4d6fc14bSjoergstruct nothrow_t { explicit nothrow_t() = default; };
43*4d6fc14bSjoergextern const nothrow_t nothrow;
44*4d6fc14bSjoergtypedef void (*new_handler)();
45*4d6fc14bSjoergnew_handler set_new_handler(new_handler new_p) noexcept;
46*4d6fc14bSjoergnew_handler get_new_handler() noexcept;
47*4d6fc14bSjoerg
48*4d6fc14bSjoerg// 21.6.4, pointer optimization barrier
49*4d6fc14bSjoergtemplate <class T> constexpr T* launder(T* p) noexcept; // C++17
50*4d6fc14bSjoerg}  // std
51*4d6fc14bSjoerg
52*4d6fc14bSjoergvoid* operator new(std::size_t size);                                   // replaceable, nodiscard in C++20
53*4d6fc14bSjoergvoid* operator new(std::size_t size, std::align_val_t alignment);       // replaceable, C++17, nodiscard in C++20
54*4d6fc14bSjoergvoid* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable, nodiscard in C++20
55*4d6fc14bSjoergvoid* operator new(std::size_t size, std::align_val_t alignment,
56*4d6fc14bSjoerg                   const std::nothrow_t&) noexcept;                     // replaceable, C++17, nodiscard in C++20
57*4d6fc14bSjoergvoid  operator delete(void* ptr) noexcept;                              // replaceable
58*4d6fc14bSjoergvoid  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14
59*4d6fc14bSjoergvoid  operator delete(void* ptr, std::align_val_t alignment) noexcept;  // replaceable, C++17
60*4d6fc14bSjoergvoid  operator delete(void* ptr, std::size_t size,
61*4d6fc14bSjoerg                      std::align_val_t alignment) noexcept;             // replaceable, C++17
62*4d6fc14bSjoergvoid  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
63*4d6fc14bSjoergvoid  operator delete(void* ptr, std:align_val_t alignment,
64*4d6fc14bSjoerg                      const std::nothrow_t&) noexcept;                  // replaceable, C++17
65*4d6fc14bSjoerg
66*4d6fc14bSjoergvoid* operator new[](std::size_t size);                                 // replaceable, nodiscard in C++20
67*4d6fc14bSjoergvoid* operator new[](std::size_t size,
68*4d6fc14bSjoerg                     std::align_val_t alignment) noexcept;              // replaceable, C++17, nodiscard in C++20
69*4d6fc14bSjoergvoid* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20
70*4d6fc14bSjoergvoid* operator new[](std::size_t size, std::align_val_t alignment,
71*4d6fc14bSjoerg                     const std::nothrow_t&) noexcept;                   // replaceable, C++17, nodiscard in C++20
72*4d6fc14bSjoergvoid  operator delete[](void* ptr) noexcept;                            // replaceable
73*4d6fc14bSjoergvoid  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14
74*4d6fc14bSjoergvoid  operator delete[](void* ptr,
75*4d6fc14bSjoerg                        std::align_val_t alignment) noexcept;           // replaceable, C++17
76*4d6fc14bSjoergvoid  operator delete[](void* ptr, std::size_t size,
77*4d6fc14bSjoerg                        std::align_val_t alignment) noexcept;           // replaceable, C++17
78*4d6fc14bSjoergvoid  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
79*4d6fc14bSjoergvoid  operator delete[](void* ptr, std::align_val_t alignment,
80*4d6fc14bSjoerg                        const std::nothrow_t&) noexcept;                // replaceable, C++17
81*4d6fc14bSjoerg
82*4d6fc14bSjoergvoid* operator new  (std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
83*4d6fc14bSjoergvoid* operator new[](std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
84*4d6fc14bSjoergvoid  operator delete  (void* ptr, void*) noexcept;
85*4d6fc14bSjoergvoid  operator delete[](void* ptr, void*) noexcept;
86*4d6fc14bSjoerg
87*4d6fc14bSjoerg*/
88*4d6fc14bSjoerg
89*4d6fc14bSjoerg#include <__config>
90*4d6fc14bSjoerg#include <__availability>
91*4d6fc14bSjoerg#include <cstddef>
92*4d6fc14bSjoerg#include <cstdlib>
93*4d6fc14bSjoerg#include <exception>
94*4d6fc14bSjoerg#include <type_traits>
95*4d6fc14bSjoerg#include <version>
96*4d6fc14bSjoerg
97*4d6fc14bSjoerg#if defined(_LIBCPP_ABI_VCRUNTIME)
98*4d6fc14bSjoerg#include <new.h>
99*4d6fc14bSjoerg#endif
100*4d6fc14bSjoerg
101*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
102*4d6fc14bSjoerg#pragma GCC system_header
103*4d6fc14bSjoerg#endif
104*4d6fc14bSjoerg
105*4d6fc14bSjoerg#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation  < 201309L
106*4d6fc14bSjoerg#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION
107*4d6fc14bSjoerg#endif
108*4d6fc14bSjoerg
109*4d6fc14bSjoerg#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \
110*4d6fc14bSjoerg    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
111*4d6fc14bSjoerg# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
112*4d6fc14bSjoerg#endif
113*4d6fc14bSjoerg
114*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
115*4d6fc14bSjoerg    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
116*4d6fc14bSjoerg# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
117*4d6fc14bSjoerg#endif
118*4d6fc14bSjoerg
119*4d6fc14bSjoergnamespace std  // purposefully not using versioning namespace
120*4d6fc14bSjoerg{
121*4d6fc14bSjoerg
122*4d6fc14bSjoerg#if !defined(_LIBCPP_ABI_VCRUNTIME)
123*4d6fc14bSjoergstruct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
124*4d6fc14bSjoergextern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
125*4d6fc14bSjoerg
126*4d6fc14bSjoergclass _LIBCPP_EXCEPTION_ABI bad_alloc
127*4d6fc14bSjoerg    : public exception
128*4d6fc14bSjoerg{
129*4d6fc14bSjoergpublic:
130*4d6fc14bSjoerg    bad_alloc() _NOEXCEPT;
131*4d6fc14bSjoerg    virtual ~bad_alloc() _NOEXCEPT;
132*4d6fc14bSjoerg    virtual const char* what() const _NOEXCEPT;
133*4d6fc14bSjoerg};
134*4d6fc14bSjoerg
135*4d6fc14bSjoergclass _LIBCPP_EXCEPTION_ABI bad_array_new_length
136*4d6fc14bSjoerg    : public bad_alloc
137*4d6fc14bSjoerg{
138*4d6fc14bSjoergpublic:
139*4d6fc14bSjoerg    bad_array_new_length() _NOEXCEPT;
140*4d6fc14bSjoerg    virtual ~bad_array_new_length() _NOEXCEPT;
141*4d6fc14bSjoerg    virtual const char* what() const _NOEXCEPT;
142*4d6fc14bSjoerg};
143*4d6fc14bSjoerg
144*4d6fc14bSjoergtypedef void (*new_handler)();
145*4d6fc14bSjoerg_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
146*4d6fc14bSjoerg_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
147*4d6fc14bSjoerg
148*4d6fc14bSjoerg#endif // !_LIBCPP_ABI_VCRUNTIME
149*4d6fc14bSjoerg
150*4d6fc14bSjoerg_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
151*4d6fc14bSjoerg
152*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
153*4d6fc14bSjoerg    !defined(_LIBCPP_ABI_VCRUNTIME)
154*4d6fc14bSjoerg#ifndef _LIBCPP_CXX03_LANG
155*4d6fc14bSjoergenum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
156*4d6fc14bSjoerg#else
157*4d6fc14bSjoergenum align_val_t { __zero = 0, __max = (size_t)-1 };
158*4d6fc14bSjoerg#endif
159*4d6fc14bSjoerg#endif
160*4d6fc14bSjoerg
161*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 17
162*4d6fc14bSjoerg// Enable the declaration even if the compiler doesn't support the language
163*4d6fc14bSjoerg// feature.
164*4d6fc14bSjoergstruct destroying_delete_t {
165*4d6fc14bSjoerg  explicit destroying_delete_t() = default;
166*4d6fc14bSjoerg};
167*4d6fc14bSjoerg_LIBCPP_INLINE_VAR constexpr destroying_delete_t destroying_delete{};
168*4d6fc14bSjoerg#endif // _LIBCPP_STD_VER > 17
169*4d6fc14bSjoerg
170*4d6fc14bSjoerg}  // std
171*4d6fc14bSjoerg
172*4d6fc14bSjoerg#if defined(_LIBCPP_CXX03_LANG)
173*4d6fc14bSjoerg#define _THROW_BAD_ALLOC throw(std::bad_alloc)
174*4d6fc14bSjoerg#else
175*4d6fc14bSjoerg#define _THROW_BAD_ALLOC
176*4d6fc14bSjoerg#endif
177*4d6fc14bSjoerg
178*4d6fc14bSjoerg#if !defined(_LIBCPP_ABI_VCRUNTIME)
179*4d6fc14bSjoerg
180*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
181*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
182*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p) _NOEXCEPT;
183*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
184*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
185*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
186*4d6fc14bSjoerg#endif
187*4d6fc14bSjoerg
188*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
189*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
190*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p) _NOEXCEPT;
191*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
192*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
193*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
194*4d6fc14bSjoerg#endif
195*4d6fc14bSjoerg
196*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
197*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
198*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
199*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
200*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
201*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
202*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
203*4d6fc14bSjoerg#endif
204*4d6fc14bSjoerg
205*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
206*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
207*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
208*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
209*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
210*4d6fc14bSjoerg_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
211*4d6fc14bSjoerg#endif
212*4d6fc14bSjoerg#endif
213*4d6fc14bSjoerg
214*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
215*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
216*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
217*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}
218*4d6fc14bSjoerg
219*4d6fc14bSjoerg#endif // !_LIBCPP_ABI_VCRUNTIME
220*4d6fc14bSjoerg
221*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD
222*4d6fc14bSjoerg
223*4d6fc14bSjoerg_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
224*4d6fc14bSjoerg#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
225*4d6fc14bSjoerg  return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
226*4d6fc14bSjoerg#else
227*4d6fc14bSjoerg  return __align > alignment_of<max_align_t>::value;
228*4d6fc14bSjoerg#endif
229*4d6fc14bSjoerg}
230*4d6fc14bSjoerg
231*4d6fc14bSjoergtemplate <class ..._Args>
232*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
233*4d6fc14bSjoergvoid* __libcpp_operator_new(_Args ...__args) {
234*4d6fc14bSjoerg#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
235*4d6fc14bSjoerg  return __builtin_operator_new(__args...);
236*4d6fc14bSjoerg#else
237*4d6fc14bSjoerg  return ::operator new(__args...);
238*4d6fc14bSjoerg#endif
239*4d6fc14bSjoerg}
240*4d6fc14bSjoerg
241*4d6fc14bSjoergtemplate <class ..._Args>
242*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
243*4d6fc14bSjoergvoid __libcpp_operator_delete(_Args ...__args) {
244*4d6fc14bSjoerg#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
245*4d6fc14bSjoerg  __builtin_operator_delete(__args...);
246*4d6fc14bSjoerg#else
247*4d6fc14bSjoerg  ::operator delete(__args...);
248*4d6fc14bSjoerg#endif
249*4d6fc14bSjoerg}
250*4d6fc14bSjoerg
251*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
252*4d6fc14bSjoergvoid *__libcpp_allocate(size_t __size, size_t __align) {
253*4d6fc14bSjoerg#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
254*4d6fc14bSjoerg  if (__is_overaligned_for_new(__align)) {
255*4d6fc14bSjoerg    const align_val_t __align_val = static_cast<align_val_t>(__align);
256*4d6fc14bSjoerg    return __libcpp_operator_new(__size, __align_val);
257*4d6fc14bSjoerg  }
258*4d6fc14bSjoerg#endif
259*4d6fc14bSjoerg
260*4d6fc14bSjoerg  (void)__align;
261*4d6fc14bSjoerg  return __libcpp_operator_new(__size);
262*4d6fc14bSjoerg}
263*4d6fc14bSjoerg
264*4d6fc14bSjoergtemplate <class ..._Args>
265*4d6fc14bSjoerg_LIBCPP_INLINE_VISIBILITY
266*4d6fc14bSjoergvoid __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
267*4d6fc14bSjoerg#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
268*4d6fc14bSjoerg  (void)__size;
269*4d6fc14bSjoerg  return __libcpp_operator_delete(__ptr, __args...);
270*4d6fc14bSjoerg#else
271*4d6fc14bSjoerg  return __libcpp_operator_delete(__ptr, __size, __args...);
272*4d6fc14bSjoerg#endif
273*4d6fc14bSjoerg}
274*4d6fc14bSjoerg
275*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
276*4d6fc14bSjoergvoid __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
277*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
278*4d6fc14bSjoerg    (void)__align;
279*4d6fc14bSjoerg    return __do_deallocate_handle_size(__ptr, __size);
280*4d6fc14bSjoerg#else
281*4d6fc14bSjoerg    if (__is_overaligned_for_new(__align)) {
282*4d6fc14bSjoerg      const align_val_t __align_val = static_cast<align_val_t>(__align);
283*4d6fc14bSjoerg      return __do_deallocate_handle_size(__ptr, __size, __align_val);
284*4d6fc14bSjoerg    } else {
285*4d6fc14bSjoerg      return __do_deallocate_handle_size(__ptr, __size);
286*4d6fc14bSjoerg    }
287*4d6fc14bSjoerg#endif
288*4d6fc14bSjoerg}
289*4d6fc14bSjoerg
290*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
291*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
292*4d6fc14bSjoerg    (void)__align;
293*4d6fc14bSjoerg    return __libcpp_operator_delete(__ptr);
294*4d6fc14bSjoerg#else
295*4d6fc14bSjoerg    if (__is_overaligned_for_new(__align)) {
296*4d6fc14bSjoerg      const align_val_t __align_val = static_cast<align_val_t>(__align);
297*4d6fc14bSjoerg      return __libcpp_operator_delete(__ptr, __align_val);
298*4d6fc14bSjoerg    } else {
299*4d6fc14bSjoerg      return __libcpp_operator_delete(__ptr);
300*4d6fc14bSjoerg    }
301*4d6fc14bSjoerg#endif
302*4d6fc14bSjoerg}
303*4d6fc14bSjoerg
304*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
305*4d6fc14bSjoerg// Low-level helpers to call the aligned allocation and deallocation functions
306*4d6fc14bSjoerg// on the target platform. This is used to implement libc++'s own memory
307*4d6fc14bSjoerg// allocation routines -- if you need to allocate memory inside the library,
308*4d6fc14bSjoerg// chances are that you want to use `__libcpp_allocate` instead.
309*4d6fc14bSjoerg//
310*4d6fc14bSjoerg// Returns the allocated memory, or `nullptr` on failure.
311*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
312*4d6fc14bSjoergvoid* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
313*4d6fc14bSjoerg#if defined(_LIBCPP_MSVCRT_LIKE)
314*4d6fc14bSjoerg  return ::_aligned_malloc(__size, __alignment);
315*4d6fc14bSjoerg#else
316*4d6fc14bSjoerg  void* __result = nullptr;
317*4d6fc14bSjoerg  (void)::posix_memalign(&__result, __alignment, __size);
318*4d6fc14bSjoerg  // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
319*4d6fc14bSjoerg  return __result;
320*4d6fc14bSjoerg#endif
321*4d6fc14bSjoerg}
322*4d6fc14bSjoerg
323*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY
324*4d6fc14bSjoergvoid __libcpp_aligned_free(void* __ptr) {
325*4d6fc14bSjoerg#if defined(_LIBCPP_MSVCRT_LIKE)
326*4d6fc14bSjoerg  ::_aligned_free(__ptr);
327*4d6fc14bSjoerg#else
328*4d6fc14bSjoerg  ::free(__ptr);
329*4d6fc14bSjoerg#endif
330*4d6fc14bSjoerg}
331*4d6fc14bSjoerg#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
332*4d6fc14bSjoerg
333*4d6fc14bSjoerg
334*4d6fc14bSjoergtemplate <class _Tp>
335*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 inline
336*4d6fc14bSjoerg_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
337*4d6fc14bSjoerg{
338*4d6fc14bSjoerg    static_assert (!(is_function<_Tp>::value), "can't launder functions" );
339*4d6fc14bSjoerg    static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
340*4d6fc14bSjoerg#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
341*4d6fc14bSjoerg    return __builtin_launder(__p);
342*4d6fc14bSjoerg#else
343*4d6fc14bSjoerg    return __p;
344*4d6fc14bSjoerg#endif
345*4d6fc14bSjoerg}
346*4d6fc14bSjoerg
347*4d6fc14bSjoerg
348*4d6fc14bSjoerg#if _LIBCPP_STD_VER > 14
349*4d6fc14bSjoergtemplate <class _Tp>
350*4d6fc14bSjoerg_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY
351*4d6fc14bSjoergconstexpr _Tp* launder(_Tp* __p) noexcept
352*4d6fc14bSjoerg{
353*4d6fc14bSjoerg    return _VSTD::__launder(__p);
354*4d6fc14bSjoerg}
355*4d6fc14bSjoerg#endif
356*4d6fc14bSjoerg
357*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD
358*4d6fc14bSjoerg
359*4d6fc14bSjoerg#endif // _LIBCPP_NEW
360