1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___NEW_ALLOCATE_H
10#define _LIBCPP___NEW_ALLOCATE_H
11
12#include <__config>
13#include <__cstddef/max_align_t.h>
14#include <__cstddef/size_t.h>
15#include <__new/align_val_t.h>
16#include <__type_traits/type_identity.h>
17#include <__utility/element_count.h>
18
19#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20# pragma GCC system_header
21#endif
22
23_LIBCPP_BEGIN_NAMESPACE_STD
24
25_LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
26#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
27 return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
28#else
29 return __align > _LIBCPP_ALIGNOF(max_align_t);
30#endif
31}
32
33template <class _Tp>
34inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp*
35__libcpp_allocate(__element_count __n, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) {
36 size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
37#if _LIBCPP_HAS_ALIGNED_ALLOCATION
38 if (__is_overaligned_for_new(__align))
39 return static_cast<_Tp*>(__builtin_operator_new(__size, static_cast<align_val_t>(__align)));
40#endif
41
42 return static_cast<_Tp*>(__builtin_operator_new(__size));
43}
44
45#if defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309L
46# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) __VA_ARGS__
47#else
48# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) /* nothing */
49#endif
50
51template <class _Tp>
52inline _LIBCPP_HIDE_FROM_ABI void
53__libcpp_deallocate(__type_identity_t<_Tp>* __ptr,
54 __element_count __n,
55 [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
56 [[__maybe_unused__]] size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
57#if _LIBCPP_HAS_ALIGNED_ALLOCATION
58 if (__is_overaligned_for_new(__align))
59 return __builtin_operator_delete(
60 __ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size), static_cast<align_val_t>(__align));
61#endif
62 return __builtin_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size));
63}
64
65#undef _LIBCPP_ONLY_IF_SIZED_DEALLOCATION
66
67template <class _Tp>
68inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate_unsized(
69 __type_identity_t<_Tp>* __ptr, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
70#if _LIBCPP_HAS_ALIGNED_ALLOCATION
71 if (__is_overaligned_for_new(__align))
72 return __builtin_operator_delete(__ptr, static_cast<align_val_t>(__align));
73#endif
74 return __builtin_operator_delete(__ptr);
75}
76_LIBCPP_END_NAMESPACE_STD
77
78#endif // _LIBCPP___NEW_ALLOCATE_H
79