76 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H11#define _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H12 13#include <__cxx03/__config>14#include <__cxx03/__utility/pair.h>15#include <__cxx03/cstddef>16#include <__cxx03/new>17 18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)19# pragma GCC system_header20#endif21 22_LIBCPP_BEGIN_NAMESPACE_STD23 24template <class _Tp>25_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t>26get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {27 pair<_Tp*, ptrdiff_t> __r(0, 0);28 const ptrdiff_t __m =29 (~ptrdiff_t(0) ^ ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1))) / sizeof(_Tp);30 if (__n > __m)31 __n = __m;32 while (__n > 0) {33#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)34 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {35 align_val_t __al = align_val_t(_LIBCPP_ALIGNOF(_Tp));36 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al, nothrow));37 } else {38 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));39 }40#else41 if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) {42 // Since aligned operator new is unavailable, return an empty43 // buffer rather than one with invalid alignment.44 return __r;45 }46 47 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));48#endif49 50 if (__r.first) {51 __r.second = __n;52 break;53 }54 __n /= 2;55 }56 return __r;57}58 59template <class _Tp>60inline _LIBCPP_HIDE_FROM_ABI void return_temporary_buffer(_Tp* __p) _NOEXCEPT {61 std::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));62}63 64struct __return_temporary_buffer {65 _LIBCPP_SUPPRESS_DEPRECATED_PUSH66 template <class _Tp>67 _LIBCPP_HIDE_FROM_ABI void operator()(_Tp* __p) const {68 std::return_temporary_buffer(__p);69 }70 _LIBCPP_SUPPRESS_DEPRECATED_POP71};72 73_LIBCPP_END_NAMESPACE_STD74 75#endif // _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H76