17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------- new ------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_NEW 127a984708SDavid Chisnall#define _LIBCPP_NEW 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall new synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnallnamespace std 187a984708SDavid Chisnall{ 197a984708SDavid Chisnall 207a984708SDavid Chisnallclass bad_alloc 217a984708SDavid Chisnall : public exception 227a984708SDavid Chisnall{ 237a984708SDavid Chisnallpublic: 247a984708SDavid Chisnall bad_alloc() noexcept; 257a984708SDavid Chisnall bad_alloc(const bad_alloc&) noexcept; 267a984708SDavid Chisnall bad_alloc& operator=(const bad_alloc&) noexcept; 277a984708SDavid Chisnall virtual const char* what() const noexcept; 287a984708SDavid Chisnall}; 297a984708SDavid Chisnall 30aed8d94eSDimitry Andricclass bad_array_new_length : public bad_alloc // C++14 314f7ab58eSDimitry Andric{ 324f7ab58eSDimitry Andricpublic: 334f7ab58eSDimitry Andric bad_array_new_length() noexcept; 344f7ab58eSDimitry Andric}; 354f7ab58eSDimitry Andric 36aed8d94eSDimitry Andricenum class align_val_t : size_t {}; // C++17 377a984708SDavid Chisnallstruct nothrow_t {}; 387a984708SDavid Chisnallextern const nothrow_t nothrow; 397a984708SDavid Chisnalltypedef void (*new_handler)(); 407a984708SDavid Chisnallnew_handler set_new_handler(new_handler new_p) noexcept; 417a984708SDavid Chisnallnew_handler get_new_handler() noexcept; 427a984708SDavid Chisnall 43b2c7081bSDimitry Andric// 21.6.4, pointer optimization barrier 44b2c7081bSDimitry Andrictemplate <class T> constexpr T* launder(T* p) noexcept; // C++17 457a984708SDavid Chisnall} // std 467a984708SDavid Chisnall 47b2c7081bSDimitry Andricvoid* operator new(std::size_t size); // replaceable, nodiscard in C++2a 48b2c7081bSDimitry Andricvoid* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17, nodiscard in C++2a 49b2c7081bSDimitry Andricvoid* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a 50aed8d94eSDimitry Andricvoid* operator new(std::size_t size, std::align_val_t alignment, 51b2c7081bSDimitry Andric const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a 527a984708SDavid Chisnallvoid operator delete(void* ptr) noexcept; // replaceable 53854fa44bSDimitry Andricvoid operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14 54aed8d94eSDimitry Andricvoid operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17 55aed8d94eSDimitry Andricvoid operator delete(void* ptr, std::size_t size, 56aed8d94eSDimitry Andric std::align_val_t alignment) noexcept; // replaceable, C++17 577a984708SDavid Chisnallvoid operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable 58aed8d94eSDimitry Andricvoid operator delete(void* ptr, std:align_val_t alignment, 59aed8d94eSDimitry Andric const std::nothrow_t&) noexcept; // replaceable, C++17 607a984708SDavid Chisnall 61b2c7081bSDimitry Andricvoid* operator new[](std::size_t size); // replaceable, nodiscard in C++2a 62aed8d94eSDimitry Andricvoid* operator new[](std::size_t size, 63b2c7081bSDimitry Andric std::align_val_t alignment) noexcept; // replaceable, C++17, nodiscard in C++2a 64b2c7081bSDimitry Andricvoid* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a 65aed8d94eSDimitry Andricvoid* operator new[](std::size_t size, std::align_val_t alignment, 66b2c7081bSDimitry Andric const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a 677a984708SDavid Chisnallvoid operator delete[](void* ptr) noexcept; // replaceable 68854fa44bSDimitry Andricvoid operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14 69aed8d94eSDimitry Andricvoid operator delete[](void* ptr, 70aed8d94eSDimitry Andric std::align_val_t alignment) noexcept; // replaceable, C++17 71aed8d94eSDimitry Andricvoid operator delete[](void* ptr, std::size_t size, 72aed8d94eSDimitry Andric std::align_val_t alignment) noexcept; // replaceable, C++17 737a984708SDavid Chisnallvoid operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable 74aed8d94eSDimitry Andricvoid operator delete[](void* ptr, std::align_val_t alignment, 75aed8d94eSDimitry Andric const std::nothrow_t&) noexcept; // replaceable, C++17 767a984708SDavid Chisnall 77b2c7081bSDimitry Andricvoid* operator new (std::size_t size, void* ptr) noexcept; // nodiscard in C++2a 78b2c7081bSDimitry Andricvoid* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++2a 797a984708SDavid Chisnallvoid operator delete (void* ptr, void*) noexcept; 807a984708SDavid Chisnallvoid operator delete[](void* ptr, void*) noexcept; 817a984708SDavid Chisnall 827a984708SDavid Chisnall*/ 837a984708SDavid Chisnall 847a984708SDavid Chisnall#include <__config> 857a984708SDavid Chisnall#include <exception> 864ba319b5SDimitry Andric#include <type_traits> 877a984708SDavid Chisnall#include <cstddef> 88*b5893f02SDimitry Andric#include <version> 89aed8d94eSDimitry Andric#ifdef _LIBCPP_NO_EXCEPTIONS 90aed8d94eSDimitry Andric#include <cstdlib> 91aed8d94eSDimitry Andric#endif 927a984708SDavid Chisnall 93b2c7081bSDimitry Andric#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) 94540d2a8bSDimitry Andric#include <new.h> 95540d2a8bSDimitry Andric#endif 96540d2a8bSDimitry Andric 977a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 987a984708SDavid Chisnall#pragma GCC system_header 997a984708SDavid Chisnall#endif 1007a984708SDavid Chisnall 101*b5893f02SDimitry Andric#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L 102*b5893f02SDimitry Andric#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION 103*b5893f02SDimitry Andric#endif 104*b5893f02SDimitry Andric 105*b5893f02SDimitry Andric#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \ 106*b5893f02SDimitry Andric defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) 107*b5893f02SDimitry Andric# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION 108*b5893f02SDimitry Andric#endif 109*b5893f02SDimitry Andric 110*b5893f02SDimitry Andric#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \ 111*b5893f02SDimitry Andric defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) 112aed8d94eSDimitry Andric# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION 113aed8d94eSDimitry Andric#endif 114aed8d94eSDimitry Andric 1154ba319b5SDimitry Andric#if !__has_builtin(__builtin_operator_new) || \ 116*b5893f02SDimitry Andric __has_builtin(__builtin_operator_new) < 201802L 117*b5893f02SDimitry Andric#define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE 118aed8d94eSDimitry Andric#endif 119aed8d94eSDimitry Andric 1207a984708SDavid Chisnallnamespace std // purposefully not using versioning namespace 1217a984708SDavid Chisnall{ 1227a984708SDavid Chisnall 123b2c7081bSDimitry Andric#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME) 124540d2a8bSDimitry Andricstruct _LIBCPP_TYPE_VIS nothrow_t {}; 125540d2a8bSDimitry Andricextern _LIBCPP_FUNC_VIS const nothrow_t nothrow; 126540d2a8bSDimitry Andric 1277a984708SDavid Chisnallclass _LIBCPP_EXCEPTION_ABI bad_alloc 1287a984708SDavid Chisnall : public exception 1297a984708SDavid Chisnall{ 1307a984708SDavid Chisnallpublic: 1317a984708SDavid Chisnall bad_alloc() _NOEXCEPT; 1327a984708SDavid Chisnall virtual ~bad_alloc() _NOEXCEPT; 1337a984708SDavid Chisnall virtual const char* what() const _NOEXCEPT; 1347a984708SDavid Chisnall}; 1357a984708SDavid Chisnall 1367a984708SDavid Chisnallclass _LIBCPP_EXCEPTION_ABI bad_array_new_length 1377a984708SDavid Chisnall : public bad_alloc 1387a984708SDavid Chisnall{ 1397a984708SDavid Chisnallpublic: 1407a984708SDavid Chisnall bad_array_new_length() _NOEXCEPT; 1417a984708SDavid Chisnall virtual ~bad_array_new_length() _NOEXCEPT; 1427a984708SDavid Chisnall virtual const char* what() const _NOEXCEPT; 1437a984708SDavid Chisnall}; 1447a984708SDavid Chisnall 145540d2a8bSDimitry Andrictypedef void (*new_handler)(); 146540d2a8bSDimitry Andric_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT; 147540d2a8bSDimitry Andric_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT; 148540d2a8bSDimitry Andric 149b2c7081bSDimitry Andric#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME 150540d2a8bSDimitry Andric 151aed8d94eSDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec 152aed8d94eSDimitry Andric 153*b5893f02SDimitry Andric#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \ 154*b5893f02SDimitry Andric !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) 155aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 156aed8d94eSDimitry Andricenum class _LIBCPP_ENUM_VIS align_val_t : size_t { }; 157aed8d94eSDimitry Andric#else 158aed8d94eSDimitry Andricenum align_val_t { __zero = 0, __max = (size_t)-1 }; 159aed8d94eSDimitry Andric#endif 160aed8d94eSDimitry Andric#endif 1617a984708SDavid Chisnall 1627a984708SDavid Chisnall} // std 1637a984708SDavid Chisnall 164aed8d94eSDimitry Andric#if defined(_LIBCPP_CXX03_LANG) 165aed8d94eSDimitry Andric#define _THROW_BAD_ALLOC throw(std::bad_alloc) 1664f7ab58eSDimitry Andric#else 167aed8d94eSDimitry Andric#define _THROW_BAD_ALLOC 1684f7ab58eSDimitry Andric#endif 1694f7ab58eSDimitry Andric 170*b5893f02SDimitry Andric#if !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) 171540d2a8bSDimitry Andric 172b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC; 173b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; 174aed8d94eSDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT; 175aed8d94eSDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; 176*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION 1770f5676f4SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; 178854fa44bSDimitry Andric#endif 1797a984708SDavid Chisnall 180b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC; 181b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; 182aed8d94eSDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT; 183aed8d94eSDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; 184*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION 1850f5676f4SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; 1867a984708SDavid Chisnall#endif 187aed8d94eSDimitry Andric 188*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION 189b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; 190b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; 191a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT; 192a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; 193*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION 194a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; 195aed8d94eSDimitry Andric#endif 196aed8d94eSDimitry Andric 197b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; 198b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; 199a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT; 200a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; 201*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION 202a580b014SDimitry Andric_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; 203aed8d94eSDimitry Andric#endif 204854fa44bSDimitry Andric#endif 2057a984708SDavid Chisnall 206b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;} 207b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;} 2084f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {} 2094f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {} 2107a984708SDavid Chisnall 211*b5893f02SDimitry Andric#endif // !_LIBCPP_DEFER_NEW_TO_VCRUNTIME 212540d2a8bSDimitry Andric 213d72607e9SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 214d72607e9SDimitry Andric 2154ba319b5SDimitry Andric_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT { 2164ba319b5SDimitry Andric#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ 2174ba319b5SDimitry Andric return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__; 2184ba319b5SDimitry Andric#else 2194ba319b5SDimitry Andric return __align > alignment_of<max_align_t>::value; 2204ba319b5SDimitry Andric#endif 2214ba319b5SDimitry Andric} 2224ba319b5SDimitry Andric 2234ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t __align) { 2244ba319b5SDimitry Andric#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION 2254ba319b5SDimitry Andric if (__is_overaligned_for_new(__align)) { 2264ba319b5SDimitry Andric const align_val_t __align_val = static_cast<align_val_t>(__align); 227*b5893f02SDimitry Andric# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE 2284ba319b5SDimitry Andric return ::operator new(__size, __align_val); 2294ba319b5SDimitry Andric# else 2304ba319b5SDimitry Andric return __builtin_operator_new(__size, __align_val); 2314ba319b5SDimitry Andric# endif 2324ba319b5SDimitry Andric } 2334ba319b5SDimitry Andric#else 2344ba319b5SDimitry Andric ((void)__align); 2354ba319b5SDimitry Andric#endif 236d72607e9SDimitry Andric#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE 237d72607e9SDimitry Andric return ::operator new(__size); 238d72607e9SDimitry Andric#else 239d72607e9SDimitry Andric return __builtin_operator_new(__size); 240d72607e9SDimitry Andric#endif 241d72607e9SDimitry Andric} 242d72607e9SDimitry Andric 243*b5893f02SDimitry Andricstruct _DeallocateCaller { 244*b5893f02SDimitry Andric static inline _LIBCPP_INLINE_VISIBILITY 245*b5893f02SDimitry Andric void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) { 246*b5893f02SDimitry Andric#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 247*b5893f02SDimitry Andric ((void)__align); 248*b5893f02SDimitry Andric return __do_deallocate_handle_size(__ptr, __size); 249*b5893f02SDimitry Andric#else 2504ba319b5SDimitry Andric if (__is_overaligned_for_new(__align)) { 2514ba319b5SDimitry Andric const align_val_t __align_val = static_cast<align_val_t>(__align); 252*b5893f02SDimitry Andric return __do_deallocate_handle_size(__ptr, __size, __align_val); 253*b5893f02SDimitry Andric } else { 254*b5893f02SDimitry Andric return __do_deallocate_handle_size(__ptr, __size); 255*b5893f02SDimitry Andric } 2564ba319b5SDimitry Andric#endif 2574ba319b5SDimitry Andric } 258*b5893f02SDimitry Andric 259*b5893f02SDimitry Andric static inline _LIBCPP_INLINE_VISIBILITY 260*b5893f02SDimitry Andric void __do_deallocate_handle_align(void *__ptr, size_t __align) { 261*b5893f02SDimitry Andric#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 2624ba319b5SDimitry Andric ((void)__align); 263*b5893f02SDimitry Andric return __do_call(__ptr); 264*b5893f02SDimitry Andric#else 265*b5893f02SDimitry Andric if (__is_overaligned_for_new(__align)) { 266*b5893f02SDimitry Andric const align_val_t __align_val = static_cast<align_val_t>(__align); 267*b5893f02SDimitry Andric return __do_call(__ptr, __align_val); 268*b5893f02SDimitry Andric } else { 269*b5893f02SDimitry Andric return __do_call(__ptr); 270*b5893f02SDimitry Andric } 2714ba319b5SDimitry Andric#endif 272*b5893f02SDimitry Andric } 273*b5893f02SDimitry Andric 274*b5893f02SDimitry Andric private: 275*b5893f02SDimitry Andric static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) { 276*b5893f02SDimitry Andric#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION 277*b5893f02SDimitry Andric ((void)__size); 278*b5893f02SDimitry Andric return __do_call(__ptr); 279*b5893f02SDimitry Andric#else 280*b5893f02SDimitry Andric return __do_call(__ptr, __size); 281*b5893f02SDimitry Andric#endif 282*b5893f02SDimitry Andric } 283*b5893f02SDimitry Andric 284*b5893f02SDimitry Andric#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION 285*b5893f02SDimitry Andric static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) { 286*b5893f02SDimitry Andric#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION 287*b5893f02SDimitry Andric ((void)__size); 288*b5893f02SDimitry Andric return __do_call(__ptr, __align); 289*b5893f02SDimitry Andric#else 290*b5893f02SDimitry Andric return __do_call(__ptr, __size, __align); 291*b5893f02SDimitry Andric#endif 292*b5893f02SDimitry Andric } 293*b5893f02SDimitry Andric#endif 294*b5893f02SDimitry Andric 295*b5893f02SDimitry Andricprivate: 296*b5893f02SDimitry Andric template <class _A1, class _A2> 297*b5893f02SDimitry Andric static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) { 298*b5893f02SDimitry Andric#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ 299*b5893f02SDimitry Andric defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) 300*b5893f02SDimitry Andric return ::operator delete(__ptr, __a1, __a2); 301*b5893f02SDimitry Andric#else 302*b5893f02SDimitry Andric return __builtin_operator_delete(__ptr, __a1, __a2); 303*b5893f02SDimitry Andric#endif 304*b5893f02SDimitry Andric } 305*b5893f02SDimitry Andric 306*b5893f02SDimitry Andric template <class _A1> 307*b5893f02SDimitry Andric static inline void __do_call(void *__ptr, _A1 __a1) { 308*b5893f02SDimitry Andric#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ 309*b5893f02SDimitry Andric defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) 310*b5893f02SDimitry Andric return ::operator delete(__ptr, __a1); 311*b5893f02SDimitry Andric#else 312*b5893f02SDimitry Andric return __builtin_operator_delete(__ptr, __a1); 313*b5893f02SDimitry Andric#endif 314*b5893f02SDimitry Andric } 315*b5893f02SDimitry Andric 316*b5893f02SDimitry Andric static inline void __do_call(void *__ptr) { 3174ba319b5SDimitry Andric#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE 3184ba319b5SDimitry Andric return ::operator delete(__ptr); 3194ba319b5SDimitry Andric#else 3204ba319b5SDimitry Andric return __builtin_operator_delete(__ptr); 321d72607e9SDimitry Andric#endif 322d72607e9SDimitry Andric } 323*b5893f02SDimitry Andric}; 324d72607e9SDimitry Andric 325*b5893f02SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) { 326*b5893f02SDimitry Andric _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align); 327aed8d94eSDimitry Andric} 328*b5893f02SDimitry Andric 329*b5893f02SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) { 330*b5893f02SDimitry Andric _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align); 331*b5893f02SDimitry Andric} 332aed8d94eSDimitry Andric 333b2c7081bSDimitry Andrictemplate <class _Tp> 334b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline 335b2c7081bSDimitry Andric_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT 336b2c7081bSDimitry Andric{ 337b2c7081bSDimitry Andric static_assert (!(is_function<_Tp>::value), "can't launder functions" ); 338b2c7081bSDimitry Andric static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" ); 339b2c7081bSDimitry Andric#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER 340b2c7081bSDimitry Andric return __builtin_launder(__p); 341b2c7081bSDimitry Andric#else 342b2c7081bSDimitry Andric return __p; 343b2c7081bSDimitry Andric#endif 344b2c7081bSDimitry Andric} 345b2c7081bSDimitry Andric 346b2c7081bSDimitry Andric 347b2c7081bSDimitry Andric#if _LIBCPP_STD_VER > 14 348b2c7081bSDimitry Andrictemplate <class _Tp> 349b2c7081bSDimitry Andric_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY 350b2c7081bSDimitry Andricconstexpr _Tp* launder(_Tp* __p) noexcept 351b2c7081bSDimitry Andric{ 352b2c7081bSDimitry Andric return _VSTD::__launder(__p); 353b2c7081bSDimitry Andric} 354b2c7081bSDimitry Andric#endif 355b2c7081bSDimitry Andric 356d72607e9SDimitry Andric_LIBCPP_END_NAMESPACE_STD 357d72607e9SDimitry Andric 3587a984708SDavid Chisnall#endif // _LIBCPP_NEW 359