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_CONSTRUCT_AT_H 11 #define _LIBCPP___MEMORY_CONSTRUCT_AT_H 12 13 #include <__config> 14 #include <__debug> 15 #include <__iterator/access.h> 16 #include <__memory/addressof.h> 17 #include <__memory/voidify.h> 18 #include <__utility/forward.h> 19 #include <type_traits> 20 #include <utility> 21 22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 23 #pragma GCC system_header 24 #endif 25 26 _LIBCPP_BEGIN_NAMESPACE_STD 27 28 // construct_at 29 30 #if _LIBCPP_STD_VER > 17 31 32 template<class _Tp, class ..._Args, class = decltype( 33 ::new (declval<void*>()) _Tp(declval<_Args>()...) 34 )> 35 _LIBCPP_HIDE_FROM_ABI 36 constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) { 37 _LIBCPP_ASSERT(__location, "null pointer given to construct_at"); 38 return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...); 39 } 40 41 #endif 42 43 // destroy_at 44 45 // The internal functions are available regardless of the language version (with the exception of the `__destroy_at` 46 // taking an array). 47 48 template <class _ForwardIterator> 49 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 50 _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator); 51 52 template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0> 53 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 54 void __destroy_at(_Tp* __loc) { 55 _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at"); 56 __loc->~_Tp(); 57 } 58 59 #if _LIBCPP_STD_VER > 17 60 template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0> 61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 62 void __destroy_at(_Tp* __loc) { 63 _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at"); 64 _VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc)); 65 } 66 #endif 67 68 template <class _ForwardIterator> 69 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 70 _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) { 71 for (; __first != __last; ++__first) 72 _VSTD::__destroy_at(_VSTD::addressof(*__first)); 73 return __first; 74 } 75 76 #if _LIBCPP_STD_VER > 14 77 78 template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0> 79 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 80 void destroy_at(_Tp* __loc) { 81 _VSTD::__destroy_at(__loc); 82 } 83 84 #if _LIBCPP_STD_VER > 17 85 template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0> 86 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 87 void destroy_at(_Tp* __loc) { 88 _VSTD::__destroy_at(__loc); 89 } 90 #endif 91 92 template <class _ForwardIterator> 93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 94 void destroy(_ForwardIterator __first, _ForwardIterator __last) { 95 (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); 96 } 97 98 template <class _ForwardIterator, class _Size> 99 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 100 _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) { 101 for (; __n > 0; (void)++__first, --__n) 102 _VSTD::__destroy_at(_VSTD::addressof(*__first)); 103 return __first; 104 } 105 106 #endif // _LIBCPP_STD_VER > 14 107 108 _LIBCPP_END_NAMESPACE_STD 109 110 #endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H 111