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