xref: /freebsd-12.1/contrib/libc++/include/new (revision b5893f02)
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