xref: /llvm-project-15.0.7/libcxx/include/new (revision 56a33ba3)
13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_NEW
113e519524SHoward Hinnant#define _LIBCPP_NEW
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    new synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnantclass bad_alloc
203e519524SHoward Hinnant    : public exception
213e519524SHoward Hinnant{
223e519524SHoward Hinnantpublic:
23fafca58cSHoward Hinnant    bad_alloc() noexcept;
24fafca58cSHoward Hinnant    bad_alloc(const bad_alloc&) noexcept;
25fafca58cSHoward Hinnant    bad_alloc& operator=(const bad_alloc&) noexcept;
26fafca58cSHoward Hinnant    virtual const char* what() const noexcept;
273e519524SHoward Hinnant};
283e519524SHoward Hinnant
290ae4f23fSEric Fiselierclass bad_array_new_length : public bad_alloc // C++14
306e8ebb2cSMarshall Clow{
316e8ebb2cSMarshall Clowpublic:
326e8ebb2cSMarshall Clow    bad_array_new_length() noexcept;
336e8ebb2cSMarshall Clow};
346e8ebb2cSMarshall Clow
350ae4f23fSEric Fiselierenum class align_val_t : size_t {}; // C++17
36ae02e894SEric Fiselier
37ae02e894SEric Fiselierstruct destroying_delete_t { // C++20
38ae02e894SEric Fiselier  explicit destroying_delete_t() = default;
39ae02e894SEric Fiselier};
40ae02e894SEric Fiselierinline constexpr destroying_delete_t destroying_delete{}; // C++20
41ae02e894SEric Fiselier
42e16f2cb6SLouis Dionnestruct nothrow_t { explicit nothrow_t() = default; };
433e519524SHoward Hinnantextern const nothrow_t nothrow;
443e519524SHoward Hinnanttypedef void (*new_handler)();
45fafca58cSHoward Hinnantnew_handler set_new_handler(new_handler new_p) noexcept;
46fafca58cSHoward Hinnantnew_handler get_new_handler() noexcept;
473e519524SHoward Hinnant
489180eb1fSMarshall Clow// 21.6.4, pointer optimization barrier
499180eb1fSMarshall Clowtemplate <class T> constexpr T* launder(T* p) noexcept; // C++17
503e519524SHoward Hinnant}  // std
513e519524SHoward Hinnant
52044b892cSMarek Kurdejvoid* operator new(std::size_t size);                                   // replaceable, nodiscard in C++20
53044b892cSMarek Kurdejvoid* operator new(std::size_t size, std::align_val_t alignment);       // replaceable, C++17, nodiscard in C++20
54044b892cSMarek Kurdejvoid* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable, nodiscard in C++20
550ae4f23fSEric Fiseliervoid* operator new(std::size_t size, std::align_val_t alignment,
56044b892cSMarek Kurdej                   const std::nothrow_t&) noexcept;                     // replaceable, C++17, nodiscard in C++20
57fafca58cSHoward Hinnantvoid  operator delete(void* ptr) noexcept;                              // replaceable
58d36bd700SLarisse Voufovoid  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14
590ae4f23fSEric Fiseliervoid  operator delete(void* ptr, std::align_val_t alignment) noexcept;  // replaceable, C++17
600ae4f23fSEric Fiseliervoid  operator delete(void* ptr, std::size_t size,
610ae4f23fSEric Fiselier                      std::align_val_t alignment) noexcept;             // replaceable, C++17
62fafca58cSHoward Hinnantvoid  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
630ae4f23fSEric Fiseliervoid  operator delete(void* ptr, std:align_val_t alignment,
640ae4f23fSEric Fiselier                      const std::nothrow_t&) noexcept;                  // replaceable, C++17
653e519524SHoward Hinnant
66044b892cSMarek Kurdejvoid* operator new[](std::size_t size);                                 // replaceable, nodiscard in C++20
670ae4f23fSEric Fiseliervoid* operator new[](std::size_t size,
68044b892cSMarek Kurdej                     std::align_val_t alignment) noexcept;              // replaceable, C++17, nodiscard in C++20
69044b892cSMarek Kurdejvoid* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20
700ae4f23fSEric Fiseliervoid* operator new[](std::size_t size, std::align_val_t alignment,
71044b892cSMarek Kurdej                     const std::nothrow_t&) noexcept;                   // replaceable, C++17, nodiscard in C++20
72fafca58cSHoward Hinnantvoid  operator delete[](void* ptr) noexcept;                            // replaceable
73d36bd700SLarisse Voufovoid  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14
740ae4f23fSEric Fiseliervoid  operator delete[](void* ptr,
750ae4f23fSEric Fiselier                        std::align_val_t alignment) noexcept;           // replaceable, C++17
760ae4f23fSEric Fiseliervoid  operator delete[](void* ptr, std::size_t size,
770ae4f23fSEric Fiselier                        std::align_val_t alignment) noexcept;           // replaceable, C++17
78fafca58cSHoward Hinnantvoid  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
790ae4f23fSEric Fiseliervoid  operator delete[](void* ptr, std::align_val_t alignment,
800ae4f23fSEric Fiselier                        const std::nothrow_t&) noexcept;                // replaceable, C++17
813e519524SHoward Hinnant
82044b892cSMarek Kurdejvoid* operator new  (std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
83044b892cSMarek Kurdejvoid* operator new[](std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
84fafca58cSHoward Hinnantvoid  operator delete  (void* ptr, void*) noexcept;
85fafca58cSHoward Hinnantvoid  operator delete[](void* ptr, void*) noexcept;
863e519524SHoward Hinnant
873e519524SHoward Hinnant*/
883e519524SHoward Hinnant
89385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
902eadbc86SLouis Dionne#include <__availability>
91bfbd73f8SArthur O'Dwyer#include <__config>
92a78aaa1aSLouis Dionne#include <cstddef>
93a78aaa1aSLouis Dionne#include <cstdlib>
943e519524SHoward Hinnant#include <exception>
95f2918d1cSEric Fiselier#include <type_traits>
96f56972e2SMarshall Clow#include <version>
973e519524SHoward Hinnant
98e69290dcSEric Fiselier#if defined(_LIBCPP_ABI_VCRUNTIME)
99d22c9dc4SEric Fiselier#include <new.h>
100d22c9dc4SEric Fiselier#endif
101d22c9dc4SEric Fiselier
102073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1033e519524SHoward Hinnant#  pragma GCC system_header
104073458b1SHoward Hinnant#endif
1053e519524SHoward Hinnant
106f25b75b9SEric Fiselier#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation  < 201309L
107f25b75b9SEric Fiselier#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION
108f25b75b9SEric Fiselier#endif
109f25b75b9SEric Fiselier
110f25b75b9SEric Fiselier#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \
111f25b75b9SEric Fiselier    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
11242f9868cSEric Fiselier# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
11342f9868cSEric Fiselier#endif
11442f9868cSEric Fiselier
11542f9868cSEric Fiselier#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
116f25b75b9SEric Fiselier    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
1170ae4f23fSEric Fiselier# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
1180ae4f23fSEric Fiselier#endif
1190ae4f23fSEric Fiselier
1203e519524SHoward Hinnantnamespace std  // purposefully not using versioning namespace
1213e519524SHoward Hinnant{
1223e519524SHoward Hinnant
123e69290dcSEric Fiselier#if !defined(_LIBCPP_ABI_VCRUNTIME)
124e16f2cb6SLouis Dionnestruct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
125d22c9dc4SEric Fiselierextern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
126d22c9dc4SEric Fiselier
1273e519524SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI bad_alloc
1283e519524SHoward Hinnant    : public exception
1293e519524SHoward Hinnant{
1303e519524SHoward Hinnantpublic:
131fafca58cSHoward Hinnant    bad_alloc() _NOEXCEPT;
132fafca58cSHoward Hinnant    virtual ~bad_alloc() _NOEXCEPT;
133fafca58cSHoward Hinnant    virtual const char* what() const _NOEXCEPT;
1343e519524SHoward Hinnant};
1353e519524SHoward Hinnant
1363e519524SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI bad_array_new_length
1373e519524SHoward Hinnant    : public bad_alloc
1383e519524SHoward Hinnant{
1393e519524SHoward Hinnantpublic:
140fafca58cSHoward Hinnant    bad_array_new_length() _NOEXCEPT;
141fafca58cSHoward Hinnant    virtual ~bad_array_new_length() _NOEXCEPT;
142fafca58cSHoward Hinnant    virtual const char* what() const _NOEXCEPT;
1433e519524SHoward Hinnant};
1443e519524SHoward Hinnant
145d22c9dc4SEric Fiseliertypedef void (*new_handler)();
146d22c9dc4SEric Fiselier_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
147d22c9dc4SEric Fiselier_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
148d22c9dc4SEric Fiselier
149e69290dcSEric Fiselier#endif // !_LIBCPP_ABI_VCRUNTIME
150d22c9dc4SEric Fiselier
151d437fa5cSMarshall Clow_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
152d437fa5cSMarshall Clow
153be10b1f1SMikhail Maltsev_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
154be10b1f1SMikhail Maltsevvoid __throw_bad_array_new_length()
155be10b1f1SMikhail Maltsev{
156be10b1f1SMikhail Maltsev#ifndef _LIBCPP_NO_EXCEPTIONS
157be10b1f1SMikhail Maltsev    throw bad_array_new_length();
158be10b1f1SMikhail Maltsev#else
159be10b1f1SMikhail Maltsev    _VSTD::abort();
160be10b1f1SMikhail Maltsev#endif
161be10b1f1SMikhail Maltsev}
162be10b1f1SMikhail Maltsev
16342f9868cSEric Fiselier#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
164e69290dcSEric Fiselier    !defined(_LIBCPP_ABI_VCRUNTIME)
1650ae4f23fSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1660ae4f23fSEric Fiselierenum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
1670ae4f23fSEric Fiselier#else
1680ae4f23fSEric Fiselierenum align_val_t { __zero = 0, __max = (size_t)-1 };
1690ae4f23fSEric Fiselier#endif
1700ae4f23fSEric Fiselier#endif
1710ae4f23fSEric Fiselier
172ae02e894SEric Fiselier#if _LIBCPP_STD_VER > 17
173ae02e894SEric Fiselier// Enable the declaration even if the compiler doesn't support the language
174ae02e894SEric Fiselier// feature.
175ae02e894SEric Fiselierstruct destroying_delete_t {
176ae02e894SEric Fiselier  explicit destroying_delete_t() = default;
177ae02e894SEric Fiselier};
178cb793e1aSLouis Dionneinline constexpr destroying_delete_t destroying_delete{};
179ae02e894SEric Fiselier#endif // _LIBCPP_STD_VER > 17
180ae02e894SEric Fiselier
181d2b0df35SNikolas Klauser} // namespace std
1823e519524SHoward Hinnant
1839877c1e7SEric Fiselier#if defined(_LIBCPP_CXX03_LANG)
1840ae4f23fSEric Fiselier#define _THROW_BAD_ALLOC throw(std::bad_alloc)
1850ae4f23fSEric Fiselier#else
1860ae4f23fSEric Fiselier#define _THROW_BAD_ALLOC
187fafca58cSHoward Hinnant#endif
1880ae4f23fSEric Fiselier
189e69290dcSEric Fiselier#if !defined(_LIBCPP_ABI_VCRUNTIME)
190d22c9dc4SEric Fiselier
1915dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
1925d79eaa8SLouis Dionne_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
193dce4218dSShoaib Meenai_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p) _NOEXCEPT;
194dce4218dSShoaib Meenai_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
19542f9868cSEric Fiselier#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
196e9c66ad9SMehdi Amini_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
197e4864e0bSLarisse Voufo#endif
198f0544c20SHoward Hinnant
1995dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
2005d79eaa8SLouis Dionne_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
201dce4218dSShoaib Meenai_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p) _NOEXCEPT;
202dce4218dSShoaib Meenai_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
20342f9868cSEric Fiselier#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
204e9c66ad9SMehdi Amini_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
205e4864e0bSLarisse Voufo#endif
206f0544c20SHoward Hinnant
20742f9868cSEric Fiselier#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
2085dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
2095d79eaa8SLouis Dionne_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;
210539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
211539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
21242f9868cSEric Fiselier#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
213539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
2140ae4f23fSEric Fiselier#endif
2150ae4f23fSEric Fiselier
2165dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
2175d79eaa8SLouis Dionne_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;
218539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
219539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
22042f9868cSEric Fiselier#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
221539cb66bSAkira Hatanaka_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
2220ae4f23fSEric Fiselier#endif
2230ae4f23fSEric Fiselier#endif
2240ae4f23fSEric Fiselier
2255dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
2265dd92209SMarshall Clow_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
2273af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
2283af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}
2293e519524SHoward Hinnant
230e69290dcSEric Fiselier#endif // !_LIBCPP_ABI_VCRUNTIME
231d22c9dc4SEric Fiselier
232ff0aff3cSRichard Smith_LIBCPP_BEGIN_NAMESPACE_STD
233ff0aff3cSRichard Smith
234f2918d1cSEric Fiselier_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
235f2918d1cSEric Fiselier#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
236f2918d1cSEric Fiselier  return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
237f2918d1cSEric Fiselier#else
238f2918d1cSEric Fiselier  return __align > alignment_of<max_align_t>::value;
239f2918d1cSEric Fiselier#endif
240f2918d1cSEric Fiselier}
241f2918d1cSEric Fiselier
242c778f6c4SLouis Dionnetemplate <class ..._Args>
243c778f6c4SLouis Dionne_LIBCPP_INLINE_VISIBILITY
244c778f6c4SLouis Dionnevoid* __libcpp_operator_new(_Args ...__args) {
245c778f6c4SLouis Dionne#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
246c778f6c4SLouis Dionne  return __builtin_operator_new(__args...);
247c778f6c4SLouis Dionne#else
248c778f6c4SLouis Dionne  return ::operator new(__args...);
249c778f6c4SLouis Dionne#endif
250c778f6c4SLouis Dionne}
251c778f6c4SLouis Dionne
252c778f6c4SLouis Dionnetemplate <class ..._Args>
253c778f6c4SLouis Dionne_LIBCPP_INLINE_VISIBILITY
254c778f6c4SLouis Dionnevoid __libcpp_operator_delete(_Args ...__args) {
255c778f6c4SLouis Dionne#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
256c778f6c4SLouis Dionne  __builtin_operator_delete(__args...);
257c778f6c4SLouis Dionne#else
258c778f6c4SLouis Dionne  ::operator delete(__args...);
259c778f6c4SLouis Dionne#endif
260c778f6c4SLouis Dionne}
261c778f6c4SLouis Dionne
262d092c912SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
2630724f8bfSLouis Dionnevoid *__libcpp_allocate(size_t __size, size_t __align) {
264f2918d1cSEric Fiselier#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
265f2918d1cSEric Fiselier  if (__is_overaligned_for_new(__align)) {
266f2918d1cSEric Fiselier    const align_val_t __align_val = static_cast<align_val_t>(__align);
267c778f6c4SLouis Dionne    return __libcpp_operator_new(__size, __align_val);
268f2918d1cSEric Fiselier  }
269f2918d1cSEric Fiselier#endif
270c778f6c4SLouis Dionne
271c778f6c4SLouis Dionne  (void)__align;
272c778f6c4SLouis Dionne  return __libcpp_operator_new(__size);
273ff0aff3cSRichard Smith}
274ff0aff3cSRichard Smith
275c778f6c4SLouis Dionnetemplate <class ..._Args>
276c778f6c4SLouis Dionne_LIBCPP_INLINE_VISIBILITY
277c778f6c4SLouis Dionnevoid __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
2780724f8bfSLouis Dionne#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
279c778f6c4SLouis Dionne  (void)__size;
280c778f6c4SLouis Dionne  return __libcpp_operator_delete(__ptr, __args...);
2810724f8bfSLouis Dionne#else
282c778f6c4SLouis Dionne  return __libcpp_operator_delete(__ptr, __size, __args...);
2830724f8bfSLouis Dionne#endif
2840724f8bfSLouis Dionne}
2850724f8bfSLouis Dionne
286c778f6c4SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
287c778f6c4SLouis Dionnevoid __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
288f25b75b9SEric Fiselier#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
289c778f6c4SLouis Dionne    (void)__align;
290f25b75b9SEric Fiselier    return __do_deallocate_handle_size(__ptr, __size);
291f25b75b9SEric Fiselier#else
2929bbee38dSEric Christopher    if (__is_overaligned_for_new(__align)) {
2939bbee38dSEric Christopher      const align_val_t __align_val = static_cast<align_val_t>(__align);
294f25b75b9SEric Fiselier      return __do_deallocate_handle_size(__ptr, __size, __align_val);
295f25b75b9SEric Fiselier    } else {
296f25b75b9SEric Fiselier      return __do_deallocate_handle_size(__ptr, __size);
297f25b75b9SEric Fiselier    }
2987e6448bbSEric Fiselier#endif
2997e6448bbSEric Fiselier}
300f25b75b9SEric Fiselier
301c778f6c4SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
302f25b75b9SEric Fiselier#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
303c778f6c4SLouis Dionne    (void)__align;
304c778f6c4SLouis Dionne    return __libcpp_operator_delete(__ptr);
305f25b75b9SEric Fiselier#else
306f25b75b9SEric Fiselier    if (__is_overaligned_for_new(__align)) {
307f25b75b9SEric Fiselier      const align_val_t __align_val = static_cast<align_val_t>(__align);
308c778f6c4SLouis Dionne      return __libcpp_operator_delete(__ptr, __align_val);
309f25b75b9SEric Fiselier    } else {
310c778f6c4SLouis Dionne      return __libcpp_operator_delete(__ptr);
311f25b75b9SEric Fiselier    }
3127e6448bbSEric Fiselier#endif
313f25b75b9SEric Fiselier}
314ff0aff3cSRichard Smith
315a78aaa1aSLouis Dionne#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
316a78aaa1aSLouis Dionne// Low-level helpers to call the aligned allocation and deallocation functions
317a78aaa1aSLouis Dionne// on the target platform. This is used to implement libc++'s own memory
318a78aaa1aSLouis Dionne// allocation routines -- if you need to allocate memory inside the library,
319a78aaa1aSLouis Dionne// chances are that you want to use `__libcpp_allocate` instead.
320a78aaa1aSLouis Dionne//
321a78aaa1aSLouis Dionne// Returns the allocated memory, or `nullptr` on failure.
322a78aaa1aSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
323a78aaa1aSLouis Dionnevoid* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
324a78aaa1aSLouis Dionne#if defined(_LIBCPP_MSVCRT_LIKE)
325a78aaa1aSLouis Dionne  return ::_aligned_malloc(__size, __alignment);
326a78aaa1aSLouis Dionne#else
327a78aaa1aSLouis Dionne  void* __result = nullptr;
3283744ba24SVitaly Buka  (void)::posix_memalign(&__result, __alignment, __size);
329a78aaa1aSLouis Dionne  // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
330a78aaa1aSLouis Dionne  return __result;
331a78aaa1aSLouis Dionne#endif
332a78aaa1aSLouis Dionne}
333a78aaa1aSLouis Dionne
334a78aaa1aSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
335a78aaa1aSLouis Dionnevoid __libcpp_aligned_free(void* __ptr) {
336a78aaa1aSLouis Dionne#if defined(_LIBCPP_MSVCRT_LIKE)
337a78aaa1aSLouis Dionne  ::_aligned_free(__ptr);
338a78aaa1aSLouis Dionne#else
339a78aaa1aSLouis Dionne  ::free(__ptr);
340a78aaa1aSLouis Dionne#endif
341a78aaa1aSLouis Dionne}
342a78aaa1aSLouis Dionne#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
343a78aaa1aSLouis Dionne
344a78aaa1aSLouis Dionne
3459180eb1fSMarshall Clowtemplate <class _Tp>
346e79474d3SLouis Dionne_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
3479180eb1fSMarshall Clow_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
3489180eb1fSMarshall Clow{
3499180eb1fSMarshall Clow    static_assert (!(is_function<_Tp>::value), "can't launder functions" );
3509180eb1fSMarshall Clow    static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
3519180eb1fSMarshall Clow    return __builtin_launder(__p);
3529180eb1fSMarshall Clow}
3539180eb1fSMarshall Clow
3549180eb1fSMarshall Clow#if _LIBCPP_STD_VER > 14
3559180eb1fSMarshall Clowtemplate <class _Tp>
356e79474d3SLouis Dionne_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
3579180eb1fSMarshall Clowconstexpr _Tp* launder(_Tp* __p) noexcept
3589180eb1fSMarshall Clow{
359b6ad844eSMarshall Clow    return _VSTD::__launder(__p);
3609180eb1fSMarshall Clow}
3619180eb1fSMarshall Clow#endif
3629180eb1fSMarshall Clow
363*56a33ba3SNikolas Klauser#if _LIBCPP_STD_VER > 14
364*56a33ba3SNikolas Klauser
365*56a33ba3SNikolas Klauser#if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
366*56a33ba3SNikolas Klauser
367*56a33ba3SNikolas Klauserinline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE;
368*56a33ba3SNikolas Klauserinline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE;
369*56a33ba3SNikolas Klauser
370*56a33ba3SNikolas Klauser#endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
371*56a33ba3SNikolas Klauser
372*56a33ba3SNikolas Klauser#endif // _LIBCPP_STD_VER > 14
373*56a33ba3SNikolas Klauser
374ff0aff3cSRichard Smith_LIBCPP_END_NAMESPACE_STD
375ff0aff3cSRichard Smith
3763e519524SHoward Hinnant#endif // _LIBCPP_NEW
377