xref: /openbsd/gnu/llvm/libcxx/include/new (revision 4bdff4be)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_NEW
1146035553Spatrick#define _LIBCPP_NEW
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    new synopsis
1546035553Spatrick
1646035553Spatricknamespace std
1746035553Spatrick{
1846035553Spatrick
1946035553Spatrickclass bad_alloc
2046035553Spatrick    : public exception
2146035553Spatrick{
2246035553Spatrickpublic:
2346035553Spatrick    bad_alloc() noexcept;
2446035553Spatrick    bad_alloc(const bad_alloc&) noexcept;
2546035553Spatrick    bad_alloc& operator=(const bad_alloc&) noexcept;
2646035553Spatrick    virtual const char* what() const noexcept;
2746035553Spatrick};
2846035553Spatrick
2946035553Spatrickclass bad_array_new_length : public bad_alloc // C++14
3046035553Spatrick{
3146035553Spatrickpublic:
3246035553Spatrick    bad_array_new_length() noexcept;
3346035553Spatrick};
3446035553Spatrick
3546035553Spatrickenum class align_val_t : size_t {}; // C++17
3646035553Spatrick
3746035553Spatrickstruct destroying_delete_t { // C++20
3846035553Spatrick  explicit destroying_delete_t() = default;
3946035553Spatrick};
4046035553Spatrickinline constexpr destroying_delete_t destroying_delete{}; // C++20
4146035553Spatrick
4246035553Spatrickstruct nothrow_t { explicit nothrow_t() = default; };
4346035553Spatrickextern const nothrow_t nothrow;
4446035553Spatricktypedef void (*new_handler)();
4546035553Spatricknew_handler set_new_handler(new_handler new_p) noexcept;
4646035553Spatricknew_handler get_new_handler() noexcept;
4746035553Spatrick
4846035553Spatrick// 21.6.4, pointer optimization barrier
4946035553Spatricktemplate <class T> constexpr T* launder(T* p) noexcept; // C++17
5046035553Spatrick}  // std
5146035553Spatrick
5276d0caaeSpatrickvoid* operator new(std::size_t size);                                   // replaceable, nodiscard in C++20
5376d0caaeSpatrickvoid* operator new(std::size_t size, std::align_val_t alignment);       // replaceable, C++17, nodiscard in C++20
5476d0caaeSpatrickvoid* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable, nodiscard in C++20
5546035553Spatrickvoid* operator new(std::size_t size, std::align_val_t alignment,
5676d0caaeSpatrick                   const std::nothrow_t&) noexcept;                     // replaceable, C++17, nodiscard in C++20
5746035553Spatrickvoid  operator delete(void* ptr) noexcept;                              // replaceable
5846035553Spatrickvoid  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14
5946035553Spatrickvoid  operator delete(void* ptr, std::align_val_t alignment) noexcept;  // replaceable, C++17
6046035553Spatrickvoid  operator delete(void* ptr, std::size_t size,
6146035553Spatrick                      std::align_val_t alignment) noexcept;             // replaceable, C++17
6246035553Spatrickvoid  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
6346035553Spatrickvoid  operator delete(void* ptr, std:align_val_t alignment,
6446035553Spatrick                      const std::nothrow_t&) noexcept;                  // replaceable, C++17
6546035553Spatrick
6676d0caaeSpatrickvoid* operator new[](std::size_t size);                                 // replaceable, nodiscard in C++20
6746035553Spatrickvoid* operator new[](std::size_t size,
6876d0caaeSpatrick                     std::align_val_t alignment) noexcept;              // replaceable, C++17, nodiscard in C++20
6976d0caaeSpatrickvoid* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20
7046035553Spatrickvoid* operator new[](std::size_t size, std::align_val_t alignment,
7176d0caaeSpatrick                     const std::nothrow_t&) noexcept;                   // replaceable, C++17, nodiscard in C++20
7246035553Spatrickvoid  operator delete[](void* ptr) noexcept;                            // replaceable
7346035553Spatrickvoid  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14
7446035553Spatrickvoid  operator delete[](void* ptr,
7546035553Spatrick                        std::align_val_t alignment) noexcept;           // replaceable, C++17
7646035553Spatrickvoid  operator delete[](void* ptr, std::size_t size,
7746035553Spatrick                        std::align_val_t alignment) noexcept;           // replaceable, C++17
7846035553Spatrickvoid  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
7946035553Spatrickvoid  operator delete[](void* ptr, std::align_val_t alignment,
8046035553Spatrick                        const std::nothrow_t&) noexcept;                // replaceable, C++17
8146035553Spatrick
8276d0caaeSpatrickvoid* operator new  (std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
8376d0caaeSpatrickvoid* operator new[](std::size_t size, void* ptr) noexcept;             // nodiscard in C++20
8446035553Spatrickvoid  operator delete  (void* ptr, void*) noexcept;
8546035553Spatrickvoid  operator delete[](void* ptr, void*) noexcept;
8646035553Spatrick
8746035553Spatrick*/
8846035553Spatrick
89*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
9076d0caaeSpatrick#include <__availability>
9146035553Spatrick#include <__config>
92*4bdff4beSrobert#include <__type_traits/is_function.h>
93*4bdff4beSrobert#include <__type_traits/is_same.h>
94*4bdff4beSrobert#include <__type_traits/remove_cv.h>
9576d0caaeSpatrick#include <cstddef>
9676d0caaeSpatrick#include <cstdlib>
9746035553Spatrick#include <exception>
9846035553Spatrick#include <version>
9946035553Spatrick
10046035553Spatrick#if defined(_LIBCPP_ABI_VCRUNTIME)
10146035553Spatrick#include <new.h>
10246035553Spatrick#endif
10346035553Spatrick
10446035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10546035553Spatrick#  pragma GCC system_header
10646035553Spatrick#endif
10746035553Spatrick
10846035553Spatrick#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation  < 201309L
10946035553Spatrick#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION
11046035553Spatrick#endif
11146035553Spatrick
11246035553Spatrick#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \
11346035553Spatrick    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
11446035553Spatrick# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
11546035553Spatrick#endif
11646035553Spatrick
11746035553Spatrick#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
11846035553Spatrick    defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
11946035553Spatrick# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
12046035553Spatrick#endif
12146035553Spatrick
12246035553Spatricknamespace std  // purposefully not using versioning namespace
12346035553Spatrick{
12446035553Spatrick
12546035553Spatrick#if !defined(_LIBCPP_ABI_VCRUNTIME)
12646035553Spatrickstruct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
12746035553Spatrickextern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
12846035553Spatrick
12946035553Spatrickclass _LIBCPP_EXCEPTION_ABI bad_alloc
13046035553Spatrick    : public exception
13146035553Spatrick{
13246035553Spatrickpublic:
13346035553Spatrick    bad_alloc() _NOEXCEPT;
134*4bdff4beSrobert    ~bad_alloc() _NOEXCEPT override;
135*4bdff4beSrobert    const char* what() const _NOEXCEPT override;
13646035553Spatrick};
13746035553Spatrick
13846035553Spatrickclass _LIBCPP_EXCEPTION_ABI bad_array_new_length
13946035553Spatrick    : public bad_alloc
14046035553Spatrick{
14146035553Spatrickpublic:
14246035553Spatrick    bad_array_new_length() _NOEXCEPT;
143*4bdff4beSrobert    ~bad_array_new_length() _NOEXCEPT override;
144*4bdff4beSrobert    const char* what() const _NOEXCEPT override;
14546035553Spatrick};
14646035553Spatrick
14746035553Spatricktypedef void (*new_handler)();
14846035553Spatrick_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
14946035553Spatrick_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
15046035553Spatrick
151*4bdff4beSrobert#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
152*4bdff4beSrobert
153*4bdff4beSrobert// When _HAS_EXCEPTIONS == 0, these complete definitions are needed,
154*4bdff4beSrobert// since they would normally be provided in vcruntime_exception.h
155*4bdff4beSrobertclass bad_alloc : public exception {
156*4bdff4beSrobertpublic:
157*4bdff4beSrobert  bad_alloc() noexcept : exception("bad allocation") {}
158*4bdff4beSrobert
159*4bdff4beSrobertprivate:
160*4bdff4beSrobert  friend class bad_array_new_length;
161*4bdff4beSrobert
162*4bdff4beSrobert  bad_alloc(char const* const __message) noexcept : exception(__message) {}
163*4bdff4beSrobert};
164*4bdff4beSrobert
165*4bdff4beSrobertclass bad_array_new_length : public bad_alloc {
166*4bdff4beSrobertpublic:
167*4bdff4beSrobert  bad_array_new_length() noexcept : bad_alloc("bad array new length") {}
168*4bdff4beSrobert};
169*4bdff4beSrobert#endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
17046035553Spatrick
17146035553Spatrick_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
17246035553Spatrick
173*4bdff4beSrobert_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
174*4bdff4beSrobertvoid __throw_bad_array_new_length()
175*4bdff4beSrobert{
176*4bdff4beSrobert#ifndef _LIBCPP_NO_EXCEPTIONS
177*4bdff4beSrobert    throw bad_array_new_length();
178*4bdff4beSrobert#else
179*4bdff4beSrobert    _VSTD::abort();
180*4bdff4beSrobert#endif
181*4bdff4beSrobert}
182*4bdff4beSrobert
18346035553Spatrick#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \
18446035553Spatrick    !defined(_LIBCPP_ABI_VCRUNTIME)
18546035553Spatrick#ifndef _LIBCPP_CXX03_LANG
18646035553Spatrickenum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
18746035553Spatrick#else
18846035553Spatrickenum align_val_t { __zero = 0, __max = (size_t)-1 };
18946035553Spatrick#endif
19046035553Spatrick#endif
19146035553Spatrick
19246035553Spatrick#if _LIBCPP_STD_VER > 17
19346035553Spatrick// Enable the declaration even if the compiler doesn't support the language
19446035553Spatrick// feature.
19546035553Spatrickstruct destroying_delete_t {
19646035553Spatrick  explicit destroying_delete_t() = default;
19746035553Spatrick};
198*4bdff4beSrobertinline constexpr destroying_delete_t destroying_delete{};
19946035553Spatrick#endif // _LIBCPP_STD_VER > 17
20046035553Spatrick
201*4bdff4beSrobert} // namespace std
20246035553Spatrick
20346035553Spatrick#if defined(_LIBCPP_CXX03_LANG)
20446035553Spatrick#define _THROW_BAD_ALLOC throw(std::bad_alloc)
20546035553Spatrick#else
20646035553Spatrick#define _THROW_BAD_ALLOC
20746035553Spatrick#endif
20846035553Spatrick
20946035553Spatrick#if !defined(_LIBCPP_ABI_VCRUNTIME)
21046035553Spatrick
21146035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
21246035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
21346035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p) _NOEXCEPT;
21446035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
21546035553Spatrick#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
21646035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
21746035553Spatrick#endif
21846035553Spatrick
21946035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
22046035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS;
22146035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p) _NOEXCEPT;
22246035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
22346035553Spatrick#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
22446035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
22546035553Spatrick#endif
22646035553Spatrick
22746035553Spatrick#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
22846035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
22946035553Spatrick_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;
23046035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
23146035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
23246035553Spatrick#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
23346035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
23446035553Spatrick#endif
23546035553Spatrick
23646035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
23746035553Spatrick_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;
23846035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
23946035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
24046035553Spatrick#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION
24146035553Spatrick_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
24246035553Spatrick#endif
24346035553Spatrick#endif
24446035553Spatrick
24546035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
24646035553Spatrick_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
24746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
24846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}
24946035553Spatrick
25046035553Spatrick#endif // !_LIBCPP_ABI_VCRUNTIME
25146035553Spatrick
25246035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
25346035553Spatrick
25446035553Spatrick_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
25546035553Spatrick#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
25646035553Spatrick  return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
25746035553Spatrick#else
25846035553Spatrick  return __align > alignment_of<max_align_t>::value;
25946035553Spatrick#endif
26046035553Spatrick}
26146035553Spatrick
26276d0caaeSpatricktemplate <class ..._Args>
26376d0caaeSpatrick_LIBCPP_INLINE_VISIBILITY
26476d0caaeSpatrickvoid* __libcpp_operator_new(_Args ...__args) {
26576d0caaeSpatrick#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
26676d0caaeSpatrick  return __builtin_operator_new(__args...);
26746035553Spatrick#else
26876d0caaeSpatrick  return ::operator new(__args...);
26946035553Spatrick#endif
27046035553Spatrick}
27146035553Spatrick
27276d0caaeSpatricktemplate <class ..._Args>
27376d0caaeSpatrick_LIBCPP_INLINE_VISIBILITY
27476d0caaeSpatrickvoid __libcpp_operator_delete(_Args ...__args) {
27576d0caaeSpatrick#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
27676d0caaeSpatrick  __builtin_operator_delete(__args...);
27776d0caaeSpatrick#else
27876d0caaeSpatrick  ::operator delete(__args...);
27976d0caaeSpatrick#endif
28076d0caaeSpatrick}
28176d0caaeSpatrick
28276d0caaeSpatrickinline _LIBCPP_INLINE_VISIBILITY
28376d0caaeSpatrickvoid *__libcpp_allocate(size_t __size, size_t __align) {
28476d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
28576d0caaeSpatrick  if (__is_overaligned_for_new(__align)) {
28676d0caaeSpatrick    const align_val_t __align_val = static_cast<align_val_t>(__align);
28776d0caaeSpatrick    return __libcpp_operator_new(__size, __align_val);
28876d0caaeSpatrick  }
28976d0caaeSpatrick#endif
29076d0caaeSpatrick
29176d0caaeSpatrick  (void)__align;
29276d0caaeSpatrick  return __libcpp_operator_new(__size);
29376d0caaeSpatrick}
29476d0caaeSpatrick
29576d0caaeSpatricktemplate <class ..._Args>
29676d0caaeSpatrick_LIBCPP_INLINE_VISIBILITY
29776d0caaeSpatrickvoid __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
29876d0caaeSpatrick#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
29976d0caaeSpatrick  (void)__size;
300*4bdff4beSrobert  return std::__libcpp_operator_delete(__ptr, __args...);
30176d0caaeSpatrick#else
302*4bdff4beSrobert  return std::__libcpp_operator_delete(__ptr, __size, __args...);
30376d0caaeSpatrick#endif
30476d0caaeSpatrick}
30576d0caaeSpatrick
30676d0caaeSpatrickinline _LIBCPP_INLINE_VISIBILITY
30776d0caaeSpatrickvoid __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
30846035553Spatrick#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
30976d0caaeSpatrick    (void)__align;
31046035553Spatrick    return __do_deallocate_handle_size(__ptr, __size);
31146035553Spatrick#else
31246035553Spatrick    if (__is_overaligned_for_new(__align)) {
31346035553Spatrick      const align_val_t __align_val = static_cast<align_val_t>(__align);
31446035553Spatrick      return __do_deallocate_handle_size(__ptr, __size, __align_val);
31546035553Spatrick    } else {
31646035553Spatrick      return __do_deallocate_handle_size(__ptr, __size);
31746035553Spatrick    }
31846035553Spatrick#endif
31946035553Spatrick}
32046035553Spatrick
32176d0caaeSpatrickinline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
32246035553Spatrick#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
32376d0caaeSpatrick    (void)__align;
32476d0caaeSpatrick    return __libcpp_operator_delete(__ptr);
32546035553Spatrick#else
32646035553Spatrick    if (__is_overaligned_for_new(__align)) {
32746035553Spatrick      const align_val_t __align_val = static_cast<align_val_t>(__align);
32876d0caaeSpatrick      return __libcpp_operator_delete(__ptr, __align_val);
32946035553Spatrick    } else {
33076d0caaeSpatrick      return __libcpp_operator_delete(__ptr);
33146035553Spatrick    }
33246035553Spatrick#endif
33346035553Spatrick}
33446035553Spatrick
33576d0caaeSpatrick#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
33676d0caaeSpatrick// Low-level helpers to call the aligned allocation and deallocation functions
33776d0caaeSpatrick// on the target platform. This is used to implement libc++'s own memory
33876d0caaeSpatrick// allocation routines -- if you need to allocate memory inside the library,
33976d0caaeSpatrick// chances are that you want to use `__libcpp_allocate` instead.
34076d0caaeSpatrick//
34176d0caaeSpatrick// Returns the allocated memory, or `nullptr` on failure.
342*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
34376d0caaeSpatrick#  if defined(_LIBCPP_MSVCRT_LIKE)
34476d0caaeSpatrick    return ::_aligned_malloc(__size, __alignment);
345*4bdff4beSrobert#  elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
346*4bdff4beSrobert    // aligned_alloc() requires that __size is a multiple of __alignment,
347*4bdff4beSrobert    // but for C++ [new.delete.general], only states "if the value of an
348*4bdff4beSrobert    // alignment argument passed to any of these functions is not a valid
349*4bdff4beSrobert    // alignment value, the behavior is undefined".
350*4bdff4beSrobert    // To handle calls such as ::operator new(1, std::align_val_t(128)), we
351*4bdff4beSrobert    // round __size up to the next multiple of __alignment.
352*4bdff4beSrobert    size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
353*4bdff4beSrobert    // Rounding up could have wrapped around to zero, so we have to add another
354*4bdff4beSrobert    // max() ternary to the actual call site to avoid succeeded in that case.
355*4bdff4beSrobert    return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
35646035553Spatrick#  else
35776d0caaeSpatrick    void* __result = nullptr;
35876d0caaeSpatrick    (void)::posix_memalign(&__result, __alignment, __size);
35976d0caaeSpatrick    // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
36076d0caaeSpatrick    return __result;
36146035553Spatrick#  endif
36246035553Spatrick}
36346035553Spatrick
36476d0caaeSpatrickinline _LIBCPP_INLINE_VISIBILITY
36576d0caaeSpatrickvoid __libcpp_aligned_free(void* __ptr) {
36676d0caaeSpatrick#if defined(_LIBCPP_MSVCRT_LIKE)
36776d0caaeSpatrick  ::_aligned_free(__ptr);
36846035553Spatrick#else
36976d0caaeSpatrick  ::free(__ptr);
37046035553Spatrick#endif
37146035553Spatrick}
37276d0caaeSpatrick#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
37346035553Spatrick
37446035553Spatrick
37546035553Spatricktemplate <class _Tp>
376*4bdff4beSrobert_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
37746035553Spatrick_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
37846035553Spatrick{
37946035553Spatrick    static_assert (!(is_function<_Tp>::value), "can't launder functions" );
380*4bdff4beSrobert    static_assert (!(is_same<void, __remove_cv_t<_Tp> >::value), "can't launder cv-void" );
38146035553Spatrick    return __builtin_launder(__p);
38246035553Spatrick}
38346035553Spatrick
38446035553Spatrick#if _LIBCPP_STD_VER > 14
38546035553Spatricktemplate <class _Tp>
386*4bdff4beSrobert_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
38746035553Spatrickconstexpr _Tp* launder(_Tp* __p) noexcept
38846035553Spatrick{
38946035553Spatrick    return _VSTD::__launder(__p);
39046035553Spatrick}
39146035553Spatrick#endif
39246035553Spatrick
393*4bdff4beSrobert#if _LIBCPP_STD_VER > 14
394*4bdff4beSrobert
395*4bdff4beSrobert#if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
396*4bdff4beSrobert
397*4bdff4beSrobertinline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE;
398*4bdff4beSrobertinline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE;
399*4bdff4beSrobert
400*4bdff4beSrobert#endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
401*4bdff4beSrobert
402*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 14
403*4bdff4beSrobert
40446035553Spatrick_LIBCPP_END_NAMESPACE_STD
40546035553Spatrick
406*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
407*4bdff4beSrobert#  include <type_traits>
408*4bdff4beSrobert#endif
409*4bdff4beSrobert
41046035553Spatrick#endif // _LIBCPP_NEW
411