1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 11 #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 12 13 #include <__config> 14 #include <__type_traits/alignment_of.h> 15 #include <__utility/pair.h> 16 #include <cstddef> 17 #include <new> 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 template <class _Tp> 26 _LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 27 pair<_Tp*, ptrdiff_t> 28 get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT 29 { 30 pair<_Tp*, ptrdiff_t> __r(0, 0); 31 const ptrdiff_t __m = (~ptrdiff_t(0) ^ 32 ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) 33 / sizeof(_Tp); 34 if (__n > __m) 35 __n = __m; 36 while (__n > 0) 37 { 38 #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 39 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) 40 { 41 align_val_t __al = 42 align_val_t(alignment_of<_Tp>::value); 43 __r.first = static_cast<_Tp*>(::operator new( 44 __n * sizeof(_Tp), __al, nothrow)); 45 } else { 46 __r.first = static_cast<_Tp*>(::operator new( 47 __n * sizeof(_Tp), nothrow)); 48 } 49 #else 50 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) 51 { 52 // Since aligned operator new is unavailable, return an empty 53 // buffer rather than one with invalid alignment. 54 return __r; 55 } 56 57 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); 58 #endif 59 60 if (__r.first) 61 { 62 __r.second = __n; 63 break; 64 } 65 __n /= 2; 66 } 67 return __r; 68 } 69 70 template <class _Tp> 71 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 72 void return_temporary_buffer(_Tp* __p) _NOEXCEPT 73 { 74 _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); 75 } 76 77 struct __return_temporary_buffer 78 { 79 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 80 template <class _Tp> 81 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);} 82 _LIBCPP_SUPPRESS_DEPRECATED_POP 83 }; 84 85 _LIBCPP_END_NAMESPACE_STD 86 87 #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 88