56 #ifndef _STL_CONSTRUCT_H
57 #define _STL_CONSTRUCT_H 1
73 namespace std _GLIBCXX_VISIBILITY(default)
75 _GLIBCXX_BEGIN_NAMESPACE_VERSION
77 #if __glibcxx_raw_memory_algorithms // >= C++17
78 template <
typename _Tp>
79 _GLIBCXX20_CONSTEXPR
inline void
80 destroy_at(_Tp* __location)
82 if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
84 for (
auto& __x : *__location)
91 #if __cpp_constexpr_dynamic_alloc // >= C++20
92 template<
typename _Tp,
typename... _Args>
93 requires (!is_unbounded_array_v<_Tp>)
94 && requires { ::new((
void*)0) _Tp(std::declval<_Args>()...); }
96 construct_at(_Tp* __location, _Args&&... __args)
97 noexcept(noexcept(::
new((
void*)0) _Tp(std::declval<_Args>()...)))
99 void* __loc = __location;
102 if constexpr (is_array_v<_Tp>)
104 static_assert(
sizeof...(_Args) == 0,
"std::construct_at for array "
105 "types must not use any arguments to initialize the "
107 return ::new(__loc) _Tp[1]();
110 return ::new(__loc) _Tp(std::forward<_Args>(__args)...);
119 #if __cplusplus >= 201103L
120 template<
typename _Tp,
typename... _Args>
125 #if __cpp_constexpr_dynamic_alloc // >= C++20
126 if (std::is_constant_evaluated())
129 std::construct_at(__p, std::forward<_Args>(__args)...);
133 ::new(
static_cast<void*
>(__p)) _Tp(std::forward<_Args>(__args)...);
136 template<
typename _T1,
typename _T2>
142 ::new(
static_cast<void*
>(__p)) _T1(__value);
146 template<
typename _T1>
149 _Construct_novalue(_T1* __p)
150 { ::new(
static_cast<void*
>(__p)) _T1; }
152 template<
typename _ForwardIterator>
153 _GLIBCXX20_CONSTEXPR
void
154 _Destroy(_ForwardIterator __first, _ForwardIterator __last);
159 template<
typename _Tp>
160 _GLIBCXX14_CONSTEXPR
inline void
163 #if __cpp_constexpr_dynamic_alloc // >= C++20
164 std::destroy_at(__pointer);
170 #pragma GCC diagnostic push
171 #pragma GCC diagnostic ignored "-Wc++17-extensions" // for if-constexpr
173 #if __cplusplus < 201103L
177 template<
typename _ForwardIterator>
178 static _GLIBCXX20_CONSTEXPR
void
179 __destroy(_ForwardIterator __first, _ForwardIterator __last)
181 for (; __first != __last; ++__first)
185 template<
typename _ForwardIterator,
typename _Size>
186 static _GLIBCXX20_CONSTEXPR _ForwardIterator
187 __destroy_n(_ForwardIterator __first, _Size __count)
189 for (; __count > 0; (void)++__first, --__count)
196 struct _Destroy_aux<true>
198 template<
typename _ForwardIterator>
200 __destroy(_ForwardIterator, _ForwardIterator) { }
202 template<
typename _ForwardIterator,
typename _Size>
203 static _ForwardIterator
204 __destroy_n(_ForwardIterator __first, _Size __count)
217 template<
typename _ForwardIterator>
218 _GLIBCXX20_CONSTEXPR
inline void
219 _Destroy(_ForwardIterator __first, _ForwardIterator __last)
223 #if __cplusplus >= 201103L
225 for (; __first != __last; ++__first)
227 #if __cpp_constexpr_dynamic_alloc // >= C++20
228 else if (std::is_constant_evaluated())
229 for (; __first != __last; ++__first)
233 std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
234 __destroy(__first, __last);
243 template<
typename _ForwardIterator,
typename _Size>
244 _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
245 _Destroy_n(_ForwardIterator __first, _Size __count)
249 #if __cplusplus >= 201103L
251 for (; __count > 0; (void)++__first, --__count)
253 #if __cpp_constexpr_dynamic_alloc // >= C++20
254 else if (std::is_constant_evaluated())
255 for (; __count > 0; (void)++__first, --__count)
262 return std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
263 __destroy_n(__first, __count);
266 #pragma GCC diagnostic pop
268 #if __glibcxx_raw_memory_algorithms // >= C++17
269 template <
typename _ForwardIterator>
270 _GLIBCXX20_CONSTEXPR
inline void
271 destroy(_ForwardIterator __first, _ForwardIterator __last)
276 template <
typename _ForwardIterator,
typename _Size>
277 _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
278 destroy_n(_ForwardIterator __first, _Size __count)
284 #if __glibcxx_start_lifetime_as >= 202207L // C++ >= 23
285 template<
typename _Tp>
286 [[__gnu__::__always_inline__]]
288 start_lifetime_as(
void* __p) noexcept
290 #if __glibcxx_is_implicit_lifetime >= 202302L
291 static_assert(is_implicit_lifetime_v<_Tp>);
293 auto __q =
reinterpret_cast<_Tp*
>(__p);
294 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__q)
295 :
"0" (__q),
"m" (*__q));
299 template<
typename _Tp>
300 [[__gnu__::__always_inline__]]
302 start_lifetime_as(
const void* __p) noexcept
304 #if __glibcxx_is_implicit_lifetime >= 202302L
305 static_assert(is_implicit_lifetime_v<_Tp>);
307 auto __q =
reinterpret_cast<const _Tp*
>(__p);
308 auto __r =
reinterpret_cast<_Tp*
>(
const_cast<void*
>(__p));
309 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__r)
310 :
"0" (__q),
"m" (*__q));
314 template<
typename _Tp>
315 [[__gnu__::__always_inline__]]
317 start_lifetime_as(
volatile void* __p) noexcept
319 #if __glibcxx_is_implicit_lifetime >= 202302L
320 static_assert(is_implicit_lifetime_v<_Tp>);
322 auto __q =
reinterpret_cast<volatile _Tp*
>(__p);
323 auto __r =
reinterpret_cast<_Tp*
>(
const_cast<void*
>(__p));
324 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__r)
325 :
"0" (__q),
"m" (*__q));
329 template<
typename _Tp>
330 [[__gnu__::__always_inline__]]
331 inline const volatile _Tp*
332 start_lifetime_as(
const volatile void* __p) noexcept
334 #if __glibcxx_is_implicit_lifetime >= 202302L
335 static_assert(is_implicit_lifetime_v<_Tp>);
337 auto __q =
reinterpret_cast<const volatile _Tp*
>(__p);
338 auto __r =
reinterpret_cast<_Tp*
>(
const_cast<void*
>(__p));
339 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__r)
340 :
"0" (__q),
"m" (*__q));
344 template<
typename _Tp>
345 [[__gnu__::__always_inline__]]
347 start_lifetime_as_array(
void* __p,
size_t __n) noexcept
349 auto __q =
reinterpret_cast<_Tp*
>(__p);
352 auto __r = (__extension__
reinterpret_cast<_Tp(*)[__n]
>(__p));
353 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__r)
354 :
"0" (__q),
"m" (*__r));
358 template<
typename _Tp>
359 [[__gnu__::__always_inline__]]
361 start_lifetime_as_array(
const void* __p,
size_t __n) noexcept
363 auto __q =
reinterpret_cast<const _Tp*
>(__p);
366 auto __r = (__extension__
reinterpret_cast<const _Tp(*)[__n]
>(__p));
367 auto __s = (__extension__
368 reinterpret_cast<_Tp(*)[__n]
>(
const_cast<void*
>(__p)));
369 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__s)
370 :
"0" (__q),
"m" (*__r));
374 template<
typename _Tp>
375 [[__gnu__::__always_inline__]]
377 start_lifetime_as_array(
volatile void* __p,
size_t __n) noexcept
379 auto __q =
reinterpret_cast<volatile _Tp*
>(__p);
382 auto __r = (__extension__
reinterpret_cast<volatile _Tp(*)[__n]
>(__p));
383 auto __s = (__extension__
384 reinterpret_cast<_Tp(*)[__n]
>(
const_cast<void*
>(__p)));
385 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__s)
386 :
"0" (__q),
"m" (*__r));
390 template<
typename _Tp>
391 [[__gnu__::__always_inline__]]
392 inline const volatile _Tp*
393 start_lifetime_as_array(
const volatile void* __p,
size_t __n) noexcept
395 auto __q =
reinterpret_cast<const volatile _Tp*
>(__p);
398 auto __r = (__extension__
reinterpret_cast<const volatile _Tp(*)[__n]
>(__p));
399 auto __s = (__extension__
400 reinterpret_cast<_Tp(*)[__n]
>(
const_cast<void*
>(__p)));
401 __asm__ __volatile__(
"" :
"=g" (__q),
"=m" (*__s)
402 :
"0" (__q),
"m" (*__r));
407 _GLIBCXX_END_NAMESPACE_VERSION