master
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
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
34template <class _Tp>
35inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp*
36__libcpp_allocate(__element_count __n, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) {
37 size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
38#if _LIBCPP_HAS_ALIGNED_ALLOCATION
39 if (__is_overaligned_for_new(__align))
40 return static_cast<_Tp*>(__builtin_operator_new(__size, static_cast<align_val_t>(__align)));
41#endif
42
43 return static_cast<_Tp*>(__builtin_operator_new(__size));
44}
45
46#if _LIBCPP_HAS_SIZED_DEALLOCATION
47# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) __VA_ARGS__
48#else
49# define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) /* nothing */
50#endif
51
52template <class _Tp>
53inline _LIBCPP_HIDE_FROM_ABI void
54__libcpp_deallocate(__type_identity_t<_Tp>* __ptr,
55 __element_count __n,
56 [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
57 [[__maybe_unused__]] size_t __size = static_cast<size_t>(__n) * sizeof(_Tp);
58#if _LIBCPP_HAS_ALIGNED_ALLOCATION
59 if (__is_overaligned_for_new(__align))
60 return __builtin_operator_delete(
61 __ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size), static_cast<align_val_t>(__align));
62#endif
63 return __builtin_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size));
64}
65
66#undef _LIBCPP_ONLY_IF_SIZED_DEALLOCATION
67
68template <class _Tp>
69inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate_unsized(
70 __type_identity_t<_Tp>* __ptr, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT {
71#if _LIBCPP_HAS_ALIGNED_ALLOCATION
72 if (__is_overaligned_for_new(__align))
73 return __builtin_operator_delete(__ptr, static_cast<align_val_t>(__align));
74#endif
75 return __builtin_operator_delete(__ptr);
76}
77_LIBCPP_END_NAMESPACE_STD
78
79#endif // _LIBCPP___NEW_ALLOCATE_H