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