comparison libcxx/include/new @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 1d019706d866
children c4bab56944e8
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
47 47
48 // 21.6.4, pointer optimization barrier 48 // 21.6.4, pointer optimization barrier
49 template <class T> constexpr T* launder(T* p) noexcept; // C++17 49 template <class T> constexpr T* launder(T* p) noexcept; // C++17
50 } // std 50 } // std
51 51
52 void* operator new(std::size_t size); // replaceable, nodiscard in C++2a 52 void* operator new(std::size_t size); // replaceable, nodiscard in C++20
53 void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17, nodiscard in C++2a 53 void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17, nodiscard in C++20
54 void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a 54 void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20
55 void* operator new(std::size_t size, std::align_val_t alignment, 55 void* operator new(std::size_t size, std::align_val_t alignment,
56 const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a 56 const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++20
57 void operator delete(void* ptr) noexcept; // replaceable 57 void operator delete(void* ptr) noexcept; // replaceable
58 void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14 58 void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14
59 void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17 59 void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17
60 void operator delete(void* ptr, std::size_t size, 60 void operator delete(void* ptr, std::size_t size,
61 std::align_val_t alignment) noexcept; // replaceable, C++17 61 std::align_val_t alignment) noexcept; // replaceable, C++17
62 void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable 62 void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable
63 void operator delete(void* ptr, std:align_val_t alignment, 63 void operator delete(void* ptr, std:align_val_t alignment,
64 const std::nothrow_t&) noexcept; // replaceable, C++17 64 const std::nothrow_t&) noexcept; // replaceable, C++17
65 65
66 void* operator new[](std::size_t size); // replaceable, nodiscard in C++2a 66 void* operator new[](std::size_t size); // replaceable, nodiscard in C++20
67 void* operator new[](std::size_t size, 67 void* operator new[](std::size_t size,
68 std::align_val_t alignment) noexcept; // replaceable, C++17, nodiscard in C++2a 68 std::align_val_t alignment) noexcept; // replaceable, C++17, nodiscard in C++20
69 void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a 69 void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20
70 void* operator new[](std::size_t size, std::align_val_t alignment, 70 void* operator new[](std::size_t size, std::align_val_t alignment,
71 const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a 71 const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++20
72 void operator delete[](void* ptr) noexcept; // replaceable 72 void operator delete[](void* ptr) noexcept; // replaceable
73 void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14 73 void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14
74 void operator delete[](void* ptr, 74 void operator delete[](void* ptr,
75 std::align_val_t alignment) noexcept; // replaceable, C++17 75 std::align_val_t alignment) noexcept; // replaceable, C++17
76 void operator delete[](void* ptr, std::size_t size, 76 void operator delete[](void* ptr, std::size_t size,
77 std::align_val_t alignment) noexcept; // replaceable, C++17 77 std::align_val_t alignment) noexcept; // replaceable, C++17
78 void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable 78 void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable
79 void operator delete[](void* ptr, std::align_val_t alignment, 79 void operator delete[](void* ptr, std::align_val_t alignment,
80 const std::nothrow_t&) noexcept; // replaceable, C++17 80 const std::nothrow_t&) noexcept; // replaceable, C++17
81 81
82 void* operator new (std::size_t size, void* ptr) noexcept; // nodiscard in C++2a 82 void* operator new (std::size_t size, void* ptr) noexcept; // nodiscard in C++20
83 void* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++2a 83 void* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++20
84 void operator delete (void* ptr, void*) noexcept; 84 void operator delete (void* ptr, void*) noexcept;
85 void operator delete[](void* ptr, void*) noexcept; 85 void operator delete[](void* ptr, void*) noexcept;
86 86
87 */ 87 */
88 88
89 #include <__availability>
89 #include <__config> 90 #include <__config>
91 #include <cstddef>
92 #include <cstdlib>
90 #include <exception> 93 #include <exception>
91 #include <type_traits> 94 #include <type_traits>
92 #include <cstddef>
93 #include <version> 95 #include <version>
94 #ifdef _LIBCPP_NO_EXCEPTIONS
95 #include <cstdlib>
96 #endif
97 96
98 #if defined(_LIBCPP_ABI_VCRUNTIME) 97 #if defined(_LIBCPP_ABI_VCRUNTIME)
99 #include <new.h> 98 #include <new.h>
100 #endif 99 #endif
101 100
113 #endif 112 #endif
114 113
115 #if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \ 114 #if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \
116 defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) 115 defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION)
117 # define _LIBCPP_HAS_NO_SIZED_DEALLOCATION 116 # define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
118 #endif
119
120 #if !__has_builtin(__builtin_operator_new) || \
121 __has_builtin(__builtin_operator_new) < 201802L
122 #define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
123 #endif 117 #endif
124 118
125 namespace std // purposefully not using versioning namespace 119 namespace std // purposefully not using versioning namespace
126 { 120 {
127 121
232 #else 226 #else
233 return __align > alignment_of<max_align_t>::value; 227 return __align > alignment_of<max_align_t>::value;
234 #endif 228 #endif
235 } 229 }
236 230
237 inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t __align) { 231 template <class ..._Args>
232 _LIBCPP_INLINE_VISIBILITY
233 void* __libcpp_operator_new(_Args ...__args) {
234 #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
235 return __builtin_operator_new(__args...);
236 #else
237 return ::operator new(__args...);
238 #endif
239 }
240
241 template <class ..._Args>
242 _LIBCPP_INLINE_VISIBILITY
243 void __libcpp_operator_delete(_Args ...__args) {
244 #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
245 __builtin_operator_delete(__args...);
246 #else
247 ::operator delete(__args...);
248 #endif
249 }
250
251 inline _LIBCPP_INLINE_VISIBILITY
252 void *__libcpp_allocate(size_t __size, size_t __align) {
238 #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION 253 #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
239 if (__is_overaligned_for_new(__align)) { 254 if (__is_overaligned_for_new(__align)) {
240 const align_val_t __align_val = static_cast<align_val_t>(__align); 255 const align_val_t __align_val = static_cast<align_val_t>(__align);
241 # ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE 256 return __libcpp_operator_new(__size, __align_val);
242 return ::operator new(__size, __align_val);
243 # else
244 return __builtin_operator_new(__size, __align_val);
245 # endif
246 } 257 }
247 #else 258 #endif
248 ((void)__align); 259
249 #endif 260 (void)__align;
250 #ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE 261 return __libcpp_operator_new(__size);
251 return ::operator new(__size); 262 }
252 #else 263
253 return __builtin_operator_new(__size); 264 template <class ..._Args>
254 #endif 265 _LIBCPP_INLINE_VISIBILITY
255 } 266 void __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
256 267 #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
257 struct _DeallocateCaller { 268 (void)__size;
258 static inline _LIBCPP_INLINE_VISIBILITY 269 return __libcpp_operator_delete(__ptr, __args...);
259 void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) { 270 #else
271 return __libcpp_operator_delete(__ptr, __size, __args...);
272 #endif
273 }
274
275 inline _LIBCPP_INLINE_VISIBILITY
276 void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
260 #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 277 #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
261 ((void)__align); 278 (void)__align;
262 return __do_deallocate_handle_size(__ptr, __size); 279 return __do_deallocate_handle_size(__ptr, __size);
263 #else 280 #else
264 if (__is_overaligned_for_new(__align)) { 281 if (__is_overaligned_for_new(__align)) {
265 const align_val_t __align_val = static_cast<align_val_t>(__align); 282 const align_val_t __align_val = static_cast<align_val_t>(__align);
266 return __do_deallocate_handle_size(__ptr, __size, __align_val); 283 return __do_deallocate_handle_size(__ptr, __size, __align_val);
267 } else { 284 } else {
268 return __do_deallocate_handle_size(__ptr, __size); 285 return __do_deallocate_handle_size(__ptr, __size);
269 } 286 }
270 #endif 287 #endif
271 } 288 }
272 289
273 static inline _LIBCPP_INLINE_VISIBILITY 290 inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
274 void __do_deallocate_handle_align(void *__ptr, size_t __align) {
275 #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 291 #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
276 ((void)__align); 292 (void)__align;
277 return __do_call(__ptr); 293 return __libcpp_operator_delete(__ptr);
278 #else 294 #else
279 if (__is_overaligned_for_new(__align)) { 295 if (__is_overaligned_for_new(__align)) {
280 const align_val_t __align_val = static_cast<align_val_t>(__align); 296 const align_val_t __align_val = static_cast<align_val_t>(__align);
281 return __do_call(__ptr, __align_val); 297 return __libcpp_operator_delete(__ptr, __align_val);
282 } else { 298 } else {
283 return __do_call(__ptr); 299 return __libcpp_operator_delete(__ptr);
284 } 300 }
285 #endif 301 #endif
286 } 302 }
287 303
288 private: 304 #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
289 static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) { 305 // Low-level helpers to call the aligned allocation and deallocation functions
290 #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION 306 // on the target platform. This is used to implement libc++'s own memory
291 ((void)__size); 307 // allocation routines -- if you need to allocate memory inside the library,
292 return __do_call(__ptr); 308 // chances are that you want to use `__libcpp_allocate` instead.
293 #else 309 //
294 return __do_call(__ptr, __size); 310 // Returns the allocated memory, or `nullptr` on failure.
295 #endif 311 inline _LIBCPP_INLINE_VISIBILITY
296 } 312 void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
297 313 #if defined(_LIBCPP_MSVCRT_LIKE)
298 #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION 314 return ::_aligned_malloc(__size, __alignment);
299 static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) { 315 #else
300 #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION 316 void* __result = nullptr;
301 ((void)__size); 317 (void)::posix_memalign(&__result, __alignment, __size);
302 return __do_call(__ptr, __align); 318 // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
303 #else 319 return __result;
304 return __do_call(__ptr, __size, __align); 320 #endif
305 #endif 321 }
306 } 322
307 #endif 323 inline _LIBCPP_INLINE_VISIBILITY
308 324 void __libcpp_aligned_free(void* __ptr) {
309 private: 325 #if defined(_LIBCPP_MSVCRT_LIKE)
310 template <class _A1, class _A2> 326 ::_aligned_free(__ptr);
311 static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) { 327 #else
312 #if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ 328 ::free(__ptr);
313 defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) 329 #endif
314 return ::operator delete(__ptr, __a1, __a2); 330 }
315 #else 331 #endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
316 return __builtin_operator_delete(__ptr, __a1, __a2); 332
317 #endif
318 }
319
320 template <class _A1>
321 static inline void __do_call(void *__ptr, _A1 __a1) {
322 #if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
323 defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
324 return ::operator delete(__ptr, __a1);
325 #else
326 return __builtin_operator_delete(__ptr, __a1);
327 #endif
328 }
329
330 static inline void __do_call(void *__ptr) {
331 #ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
332 return ::operator delete(__ptr);
333 #else
334 return __builtin_operator_delete(__ptr);
335 #endif
336 }
337 };
338
339 inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
340 _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align);
341 }
342
343 inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
344 _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
345 }
346 333
347 template <class _Tp> 334 template <class _Tp>
348 _LIBCPP_NODISCARD_AFTER_CXX17 inline 335 _LIBCPP_NODISCARD_AFTER_CXX17 inline
349 _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT 336 _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
350 { 337 {
367 } 354 }
368 #endif 355 #endif
369 356
370 _LIBCPP_END_NAMESPACE_STD 357 _LIBCPP_END_NAMESPACE_STD
371 358
372 #endif // _LIBCPP_NEW 359 #endif // _LIBCPP_NEW