xref: /freebsd/contrib/llvm-project/libcxx/include/__new/allocate.h (revision ad1f6ee5d7230a63c216cd9ad3b89d5b7d1c4a3a)
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 <__new/global_new_delete.h> // for _LIBCPP_HAS_SIZED_DEALLOCATION
17 #include <__type_traits/type_identity.h>
18 #include <__utility/element_count.h>
19 
20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #  pragma GCC system_header
22 #endif
23 
24 _LIBCPP_BEGIN_NAMESPACE_STD
25 
__is_overaligned_for_new(size_t __align)26 _LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
27 #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
28   return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
29 #else
30   return __align > _LIBCPP_ALIGNOF(max_align_t);
31 #endif
32 }
33 
34 template <class... _Args>
__libcpp_operator_new(_Args...__args)35 _LIBCPP_HIDE_FROM_ABI void* __libcpp_operator_new(_Args... __args) {
36 #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
37   return __builtin_operator_new(__args...);
38 #else
39   return ::operator new(__args...);
40 #endif
41 }
42 
43 template <class... _Args>
__libcpp_operator_delete(_Args...__args)44 _LIBCPP_HIDE_FROM_ABI void __libcpp_operator_delete(_Args... __args) _NOEXCEPT {
45 #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
46   __builtin_operator_delete(__args...);
47 #else
48   ::operator delete(__args...);
49 #endif
50 }
51 
52 template <class _Tp>
53 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp*
54 __libcpp_allocate(__element_count __n, size_t __align = _LIBCPP_ALIGNOF(_Tp)) {
55   size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
56 #if _LIBCPP_HAS_ALIGNED_ALLOCATION
57   if (__is_overaligned_for_new(__align)) {
58     const align_val_t __align_val = static_cast<align_val_t>(__align);
59     return static_cast<_Tp*>(std::__libcpp_operator_new(__size, __align_val));
60   }
61 #endif
62 
63   (void)__align;
64   return static_cast<_Tp*>(std::__libcpp_operator_new(__size));
65 }
66 
67 #if _LIBCPP_HAS_SIZED_DEALLOCATION
68 #  define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) __VA_ARGS__
69 #else
70 #  define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) /* nothing */
71 #endif
72 
73 template <class _Tp>
74 inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate(
75     __type_identity_t<_Tp>* __ptr, __element_count __n, size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
76   size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
77   (void)__size;
78 #if !_LIBCPP_HAS_ALIGNED_ALLOCATION
79   (void)__align;
80   return std::__libcpp_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size));
81 #else
82   if (__is_overaligned_for_new(__align)) {
83     const align_val_t __align_val = static_cast<align_val_t>(__align);
84     return std::__libcpp_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size), __align_val);
85   } else {
86     return std::__libcpp_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size));
87   }
88 #endif
89 }
90 
91 #undef _LIBCPP_ONLY_IF_SIZED_DEALLOCATION
92 
93 template <class _Tp>
94 inline _LIBCPP_HIDE_FROM_ABI void
95 __libcpp_deallocate_unsized(__type_identity_t<_Tp>* __ptr, size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
96 #if !_LIBCPP_HAS_ALIGNED_ALLOCATION
97   (void)__align;
98   return std::__libcpp_operator_delete(__ptr);
99 #else
100   if (__is_overaligned_for_new(__align)) {
101     const align_val_t __align_val = static_cast<align_val_t>(__align);
102     return std::__libcpp_operator_delete(__ptr, __align_val);
103   } else {
104     return std::__libcpp_operator_delete(__ptr);
105   }
106 #endif
107 }
108 _LIBCPP_END_NAMESPACE_STD
109 
110 #endif // _LIBCPP___NEW_ALLOCATE_H
111