1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 11fe6060f1SDimitry Andric #define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include <__config> 1481ad6265SDimitry Andric #include <__utility/pair.h> 15fe6060f1SDimitry Andric #include <cstddef> 16fe6060f1SDimitry Andric #include <new> 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19fe6060f1SDimitry Andric # pragma GCC system_header 20fe6060f1SDimitry Andric #endif 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric template <class _Tp> 25*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t> 26cb14a3feSDimitry Andric get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { 27fe6060f1SDimitry Andric pair<_Tp*, ptrdiff_t> __r(0, 0); 28cb14a3feSDimitry Andric const ptrdiff_t __m = 29cb14a3feSDimitry Andric (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp); 30fe6060f1SDimitry Andric if (__n > __m) 31fe6060f1SDimitry Andric __n = __m; 32cb14a3feSDimitry Andric while (__n > 0) { 33fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) 34cb14a3feSDimitry Andric if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { 355f757f3fSDimitry Andric align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp)); 36cb14a3feSDimitry Andric __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al, nothrow)); 37fe6060f1SDimitry Andric } else { 38cb14a3feSDimitry Andric __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); 39fe6060f1SDimitry Andric } 40fe6060f1SDimitry Andric #else 41cb14a3feSDimitry Andric if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { 42fe6060f1SDimitry Andric // Since aligned operator new is unavailable, return an empty 43fe6060f1SDimitry Andric // buffer rather than one with invalid alignment. 44fe6060f1SDimitry Andric return __r; 45fe6060f1SDimitry Andric } 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); 48fe6060f1SDimitry Andric #endif 49fe6060f1SDimitry Andric 50cb14a3feSDimitry Andric if (__r.first) { 51fe6060f1SDimitry Andric __r.second = __n; 52fe6060f1SDimitry Andric break; 53fe6060f1SDimitry Andric } 54fe6060f1SDimitry Andric __n /= 2; 55fe6060f1SDimitry Andric } 56fe6060f1SDimitry Andric return __r; 57fe6060f1SDimitry Andric } 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric template <class _Tp> 60cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 void return_temporary_buffer(_Tp* __p) _NOEXCEPT { 615f757f3fSDimitry Andric std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric 64cb14a3feSDimitry Andric struct __return_temporary_buffer { 6581ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_PUSH 66fe6060f1SDimitry Andric template <class _Tp> 67cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const { 68cb14a3feSDimitry Andric std::return_temporary_buffer(__p); 69cb14a3feSDimitry Andric } 7081ad6265SDimitry Andric _LIBCPP_SUPPRESS_DEPRECATED_POP 71fe6060f1SDimitry Andric }; 72fe6060f1SDimitry Andric 73fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric #endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H 76