| // Raw memory manipulators -*- C++ -*- | |
| // Copyright (C) 2020-2026 Free Software Foundation, Inc. | |
| // | |
| // This file is part of the GNU ISO C++ Library. This library is free | |
| // software; you can redistribute it and/or modify it under the | |
| // terms of the GNU General Public License as published by the | |
| // Free Software Foundation; either version 3, or (at your option) | |
| // any later version. | |
| // This library is distributed in the hope that it will be useful, | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| // GNU General Public License for more details. | |
| // Under Section 7 of GPL version 3, you are granted additional | |
| // permissions described in the GCC Runtime Library Exception, version | |
| // 3.1, as published by the Free Software Foundation. | |
| // You should have received a copy of the GNU General Public License and | |
| // a copy of the GCC Runtime Library Exception along with this program; | |
| // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
| // <http://www.gnu.org/licenses/>. | |
| /** @file bits/ranges_uninitialized.h | |
| * This is an internal header file, included by other library headers. | |
| * Do not attempt to use it directly. @headername{memory} | |
| */ | |
| #ifndef _RANGES_UNINITIALIZED_H | |
| #define _RANGES_UNINITIALIZED_H 1 | |
| #if __cplusplus > 201703L | |
| #if __cpp_lib_concepts | |
| #include <bits/ranges_algobase.h> | |
| namespace std _GLIBCXX_VISIBILITY(default) | |
| { | |
| _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
| namespace ranges | |
| { | |
| namespace __detail | |
| { | |
| template<typename _Tp> | |
| constexpr void* | |
| __voidify(_Tp& __obj) noexcept | |
| { | |
| return const_cast<void*> | |
| (static_cast<const volatile void*>(std::__addressof(__obj))); | |
| } | |
| template<typename _Iter> | |
| concept __nothrow_input_iterator | |
| = (input_iterator<_Iter> | |
| && is_lvalue_reference_v<iter_reference_t<_Iter>> | |
| && same_as<remove_cvref_t<iter_reference_t<_Iter>>, | |
| iter_value_t<_Iter>>); | |
| template<typename _Sent, typename _Iter> | |
| concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>; | |
| template<typename _Range> | |
| concept __nothrow_input_range | |
| = (range<_Range> | |
| && __nothrow_input_iterator<iterator_t<_Range>> | |
| && __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>); | |
| template<typename _Iter> | |
| concept __nothrow_forward_iterator | |
| = (__nothrow_input_iterator<_Iter> | |
| && forward_iterator<_Iter> | |
| && __nothrow_sentinel<_Iter, _Iter>); | |
| template<typename _Range> | |
| concept __nothrow_forward_range | |
| = (__nothrow_input_range<_Range> | |
| && __nothrow_forward_iterator<iterator_t<_Range>>); | |
| } // namespace __detail | |
| struct __destroy_fn | |
| { | |
| template<__detail::__nothrow_input_iterator _Iter, | |
| __detail::__nothrow_sentinel<_Iter> _Sent> | |
| requires destructible<iter_value_t<_Iter>> | |
| constexpr _Iter | |
| operator()(_Iter __first, _Sent __last) const noexcept; | |
| template<__detail::__nothrow_input_range _Range> | |
| requires destructible<range_value_t<_Range>> | |
| constexpr borrowed_iterator_t<_Range> | |
| operator()(_Range&& __r) const noexcept; | |
| }; | |
| inline constexpr __destroy_fn destroy{}; | |
| namespace __detail | |
| { | |
| template<typename _Iter> | |
| requires destructible<iter_value_t<_Iter>> | |
| struct _DestroyGuard | |
| { | |
| private: | |
| _Iter _M_first; | |
| const _Iter* _M_cur; | |
| public: | |
| constexpr | |
| explicit | |
| _DestroyGuard(const _Iter& __iter) | |
| : _M_first(__iter), _M_cur(std::__addressof(__iter)) | |
| { } | |
| constexpr | |
| void | |
| release() noexcept | |
| { _M_cur = nullptr; } | |
| constexpr | |
| ~_DestroyGuard() | |
| { | |
| if (_M_cur != nullptr) | |
| ranges::destroy(std::move(_M_first), *_M_cur); | |
| } | |
| }; | |
| template<typename _Iter> | |
| requires destructible<iter_value_t<_Iter>> | |
| && is_trivially_destructible_v<iter_value_t<_Iter>> | |
| struct _DestroyGuard<_Iter> | |
| { | |
| constexpr | |
| explicit | |
| _DestroyGuard(const _Iter&) | |
| { } | |
| constexpr | |
| void | |
| release() noexcept | |
| { } | |
| }; | |
| } // namespace __detail | |
| struct __uninitialized_default_construct_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter, | |
| __detail::__nothrow_sentinel<_Iter> _Sent> | |
| requires default_initializable<iter_value_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, _Sent __last) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_default_constructible_v<_ValueType>) | |
| return ranges::next(__first, __last); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __first != __last; ++__first) | |
| ::new (__detail::__voidify(*__first)) _ValueType; | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| template<__detail::__nothrow_forward_range _Range> | |
| requires default_initializable<range_value_t<_Range>> | |
| _GLIBCXX26_CONSTEXPR | |
| borrowed_iterator_t<_Range> | |
| operator()(_Range&& __r) const | |
| { | |
| return (*this)(ranges::begin(__r), ranges::end(__r)); | |
| } | |
| }; | |
| inline constexpr __uninitialized_default_construct_fn | |
| uninitialized_default_construct{}; | |
| struct __uninitialized_default_construct_n_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter> | |
| requires default_initializable<iter_value_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, iter_difference_t<_Iter> __n) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_default_constructible_v<_ValueType>) | |
| return ranges::next(__first, __n); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __n > 0; ++__first, (void) --__n) | |
| ::new (__detail::__voidify(*__first)) _ValueType; | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| }; | |
| inline constexpr __uninitialized_default_construct_n_fn | |
| uninitialized_default_construct_n; | |
| struct __uninitialized_value_construct_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter, | |
| __detail::__nothrow_sentinel<_Iter> _Sent> | |
| requires default_initializable<iter_value_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, _Sent __last) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_default_constructible_v<_ValueType> | |
| && is_trivially_copy_assignable_v<_ValueType>) | |
| return ranges::fill(__first, __last, _ValueType()); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __first != __last; ++__first) | |
| ::new (__detail::__voidify(*__first)) _ValueType(); | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| template<__detail::__nothrow_forward_range _Range> | |
| requires default_initializable<range_value_t<_Range>> | |
| _GLIBCXX26_CONSTEXPR | |
| borrowed_iterator_t<_Range> | |
| operator()(_Range&& __r) const | |
| { | |
| return (*this)(ranges::begin(__r), ranges::end(__r)); | |
| } | |
| }; | |
| inline constexpr __uninitialized_value_construct_fn | |
| uninitialized_value_construct{}; | |
| struct __uninitialized_value_construct_n_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter> | |
| requires default_initializable<iter_value_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, iter_difference_t<_Iter> __n) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_default_constructible_v<_ValueType> | |
| && is_trivially_copy_assignable_v<_ValueType>) | |
| return ranges::fill_n(__first, __n, _ValueType()); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __n > 0; ++__first, (void) --__n) | |
| ::new (__detail::__voidify(*__first)) _ValueType(); | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| }; | |
| inline constexpr __uninitialized_value_construct_n_fn | |
| uninitialized_value_construct_n; | |
| template<typename _Iter, typename _Out> | |
| using uninitialized_copy_result = in_out_result<_Iter, _Out>; | |
| struct __uninitialized_copy_fn | |
| { | |
| template<input_iterator _Iter, sentinel_for<_Iter> _ISent, | |
| __detail::__nothrow_forward_iterator _Out, | |
| __detail::__nothrow_sentinel<_Out> _OSent> | |
| requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_copy_result<_Iter, _Out> | |
| operator()(_Iter __ifirst, _ISent __ilast, | |
| _Out __ofirst, _OSent __olast) const | |
| { | |
| using _OutType = remove_reference_t<iter_reference_t<_Out>>; | |
| if constexpr (sized_sentinel_for<_ISent, _Iter> | |
| && sized_sentinel_for<_OSent, _Out> | |
| && is_trivially_constructible_v<_OutType, iter_reference_t<_Iter>> | |
| && is_trivially_default_constructible_v<_OutType> | |
| && is_trivially_assignable_v<_OutType&, | |
| iter_reference_t<_Iter>>) | |
| { | |
| auto __d = __ilast - __ifirst; | |
| if (auto __d2 = __olast - __ofirst; __d2 < __d) | |
| __d = static_cast<iter_difference_t<_Iter>>(__d2); | |
| return ranges::copy_n(std::move(__ifirst), __d, __ofirst); | |
| } | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__ofirst); | |
| for (; __ifirst != __ilast && __ofirst != __olast; | |
| ++__ofirst, (void)++__ifirst) | |
| ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst); | |
| __guard.release(); | |
| return {std::move(__ifirst), __ofirst}; | |
| } | |
| } | |
| template<input_range _IRange, __detail::__nothrow_forward_range _ORange> | |
| requires constructible_from<range_value_t<_ORange>, | |
| range_reference_t<_IRange>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_copy_result<borrowed_iterator_t<_IRange>, | |
| borrowed_iterator_t<_ORange>> | |
| operator()(_IRange&& __inr, _ORange&& __outr) const | |
| { | |
| return (*this)(ranges::begin(__inr), ranges::end(__inr), | |
| ranges::begin(__outr), ranges::end(__outr)); | |
| } | |
| }; | |
| inline constexpr __uninitialized_copy_fn uninitialized_copy{}; | |
| template<typename _Iter, typename _Out> | |
| using uninitialized_copy_n_result = in_out_result<_Iter, _Out>; | |
| struct __uninitialized_copy_n_fn | |
| { | |
| template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out, | |
| __detail::__nothrow_sentinel<_Out> _Sent> | |
| requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_copy_n_result<_Iter, _Out> | |
| operator()(_Iter __ifirst, iter_difference_t<_Iter> __n, | |
| _Out __ofirst, _Sent __olast) const | |
| { | |
| using _OutType = remove_reference_t<iter_reference_t<_Out>>; | |
| if constexpr (sized_sentinel_for<_Sent, _Out> | |
| && is_trivially_constructible_v<_OutType, iter_reference_t<_Iter>> | |
| && is_trivially_default_constructible_v<_OutType> | |
| && is_trivially_assignable_v<_OutType&, | |
| iter_reference_t<_Iter>>) | |
| { | |
| if (auto __d = __olast - __ofirst; __d < __n) | |
| __n = static_cast<iter_difference_t<_Iter>>(__d); | |
| return ranges::copy_n(std::move(__ifirst), __n, __ofirst); | |
| } | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__ofirst); | |
| for (; __n > 0 && __ofirst != __olast; | |
| ++__ofirst, (void)++__ifirst, (void)--__n) | |
| ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst); | |
| __guard.release(); | |
| return {std::move(__ifirst), __ofirst}; | |
| } | |
| } | |
| }; | |
| inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{}; | |
| template<typename _Iter, typename _Out> | |
| using uninitialized_move_result = in_out_result<_Iter, _Out>; | |
| struct __uninitialized_move_fn | |
| { | |
| template<input_iterator _Iter, sentinel_for<_Iter> _ISent, | |
| __detail::__nothrow_forward_iterator _Out, | |
| __detail::__nothrow_sentinel<_Out> _OSent> | |
| requires constructible_from<iter_value_t<_Out>, | |
| iter_rvalue_reference_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_move_result<_Iter, _Out> | |
| operator()(_Iter __ifirst, _ISent __ilast, | |
| _Out __ofirst, _OSent __olast) const | |
| { | |
| using _OutType = remove_reference_t<iter_reference_t<_Out>>; | |
| if constexpr (sized_sentinel_for<_ISent, _Iter> | |
| && sized_sentinel_for<_OSent, _Out> | |
| && is_trivially_constructible_v<_OutType, iter_rvalue_reference_t<_Iter>> | |
| && is_trivially_default_constructible_v<_OutType> | |
| && is_trivially_assignable_v<_OutType&, | |
| iter_rvalue_reference_t<_Iter>>) | |
| { | |
| auto __d = __ilast - __ifirst; | |
| if (auto __d2 = __olast - __ofirst; __d2 < __d) | |
| __d = static_cast<iter_difference_t<_Iter>>(__d2); | |
| auto [__in, __out] | |
| = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)), | |
| __d, __ofirst); | |
| return {std::move(__in).base(), __out}; | |
| } | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__ofirst); | |
| for (; __ifirst != __ilast && __ofirst != __olast; | |
| ++__ofirst, (void)++__ifirst) | |
| ::new (__detail::__voidify(*__ofirst)) | |
| _OutType(ranges::iter_move(__ifirst)); | |
| __guard.release(); | |
| return {std::move(__ifirst), __ofirst}; | |
| } | |
| } | |
| template<input_range _IRange, __detail::__nothrow_forward_range _ORange> | |
| requires constructible_from<range_value_t<_ORange>, | |
| range_rvalue_reference_t<_IRange>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_move_result<borrowed_iterator_t<_IRange>, | |
| borrowed_iterator_t<_ORange>> | |
| operator()(_IRange&& __inr, _ORange&& __outr) const | |
| { | |
| return (*this)(ranges::begin(__inr), ranges::end(__inr), | |
| ranges::begin(__outr), ranges::end(__outr)); | |
| } | |
| }; | |
| inline constexpr __uninitialized_move_fn uninitialized_move{}; | |
| template<typename _Iter, typename _Out> | |
| using uninitialized_move_n_result = in_out_result<_Iter, _Out>; | |
| struct __uninitialized_move_n_fn | |
| { | |
| template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out, | |
| __detail::__nothrow_sentinel<_Out> _Sent> | |
| requires constructible_from<iter_value_t<_Out>, | |
| iter_rvalue_reference_t<_Iter>> | |
| _GLIBCXX26_CONSTEXPR | |
| uninitialized_move_n_result<_Iter, _Out> | |
| operator()(_Iter __ifirst, iter_difference_t<_Iter> __n, | |
| _Out __ofirst, _Sent __olast) const | |
| { | |
| using _OutType = remove_reference_t<iter_reference_t<_Out>>; | |
| if constexpr (sized_sentinel_for<_Sent, _Out> | |
| && is_trivially_constructible_v<_OutType, iter_rvalue_reference_t<_Iter>> | |
| && is_trivially_default_constructible_v<_OutType> | |
| && is_trivially_assignable_v<_OutType&, | |
| iter_rvalue_reference_t<_Iter>>) | |
| { | |
| if (auto __d = __olast - __ofirst; __d < __n) | |
| __n = static_cast<iter_difference_t<_Iter>>(__d); | |
| auto [__in, __out] | |
| = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)), | |
| __n, __ofirst); | |
| return {std::move(__in).base(), __out}; | |
| } | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__ofirst); | |
| for (; __n > 0 && __ofirst != __olast; | |
| ++__ofirst, (void)++__ifirst, (void)--__n) | |
| ::new (__detail::__voidify(*__ofirst)) | |
| _OutType(ranges::iter_move(__ifirst)); | |
| __guard.release(); | |
| return {std::move(__ifirst), __ofirst}; | |
| } | |
| } | |
| }; | |
| inline constexpr __uninitialized_move_n_fn uninitialized_move_n{}; | |
| struct __uninitialized_fill_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter, | |
| __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp> | |
| requires constructible_from<iter_value_t<_Iter>, const _Tp&> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, _Sent __last, const _Tp& __x) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_constructible_v<_ValueType, const _Tp&> | |
| && is_trivially_assignable_v<_ValueType&, const _Tp&>) | |
| return ranges::fill(__first, __last, __x); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __first != __last; ++__first) | |
| ::new (__detail::__voidify(*__first)) _ValueType(__x); | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| template<__detail::__nothrow_forward_range _Range, typename _Tp> | |
| requires constructible_from<range_value_t<_Range>, const _Tp&> | |
| _GLIBCXX26_CONSTEXPR | |
| borrowed_iterator_t<_Range> | |
| operator()(_Range&& __r, const _Tp& __x) const | |
| { | |
| return (*this)(ranges::begin(__r), ranges::end(__r), __x); | |
| } | |
| }; | |
| inline constexpr __uninitialized_fill_fn uninitialized_fill{}; | |
| struct __uninitialized_fill_n_fn | |
| { | |
| template<__detail::__nothrow_forward_iterator _Iter, typename _Tp> | |
| requires constructible_from<iter_value_t<_Iter>, const _Tp&> | |
| _GLIBCXX26_CONSTEXPR | |
| _Iter | |
| operator()(_Iter __first, iter_difference_t<_Iter> __n, | |
| const _Tp& __x) const | |
| { | |
| using _ValueType = remove_reference_t<iter_reference_t<_Iter>>; | |
| if constexpr (is_trivially_constructible_v<_ValueType, const _Tp&> | |
| && is_trivially_assignable_v<_ValueType&, const _Tp&>) | |
| return ranges::fill_n(__first, __n, __x); | |
| else | |
| { | |
| auto __guard = __detail::_DestroyGuard(__first); | |
| for (; __n > 0; ++__first, (void)--__n) | |
| ::new (__detail::__voidify(*__first)) _ValueType(__x); | |
| __guard.release(); | |
| return __first; | |
| } | |
| } | |
| }; | |
| inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{}; | |
| struct __construct_at_fn | |
| { | |
| template<typename _Tp, typename... _Args> | |
| requires requires { | |
| ::new (std::declval<void*>()) _Tp(std::declval<_Args>()...); | |
| } | |
| constexpr _Tp* | |
| operator()(_Tp* __location, _Args&&... __args) const | |
| noexcept(noexcept(std::construct_at(__location, | |
| std::forward<_Args>(__args)...))) | |
| { | |
| return std::construct_at(__location, | |
| std::forward<_Args>(__args)...); | |
| } | |
| }; | |
| inline constexpr __construct_at_fn construct_at{}; | |
| struct __destroy_at_fn | |
| { | |
| template<destructible _Tp> | |
| constexpr void | |
| operator()(_Tp* __location) const noexcept | |
| { | |
| if constexpr (is_array_v<_Tp>) | |
| ranges::destroy(ranges::begin(*__location), ranges::end(*__location)); | |
| else | |
| __location->~_Tp(); | |
| } | |
| }; | |
| inline constexpr __destroy_at_fn destroy_at{}; | |
| template<__detail::__nothrow_input_iterator _Iter, | |
| __detail::__nothrow_sentinel<_Iter> _Sent> | |
| requires destructible<iter_value_t<_Iter>> | |
| constexpr _Iter | |
| __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept | |
| { | |
| if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>) | |
| if (!is_constant_evaluated()) | |
| return ranges::next(std::move(__first), __last); | |
| for (; __first != __last; ++__first) | |
| ranges::destroy_at(std::__addressof(*__first)); | |
| return __first; | |
| } | |
| template<__detail::__nothrow_input_range _Range> | |
| requires destructible<range_value_t<_Range>> | |
| constexpr borrowed_iterator_t<_Range> | |
| __destroy_fn::operator()(_Range&& __r) const noexcept | |
| { | |
| return (*this)(ranges::begin(__r), ranges::end(__r)); | |
| } | |
| struct __destroy_n_fn | |
| { | |
| template<__detail::__nothrow_input_iterator _Iter> | |
| requires destructible<iter_value_t<_Iter>> | |
| constexpr _Iter | |
| operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept | |
| { | |
| if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>) | |
| if (!is_constant_evaluated()) | |
| return ranges::next(std::move(__first), __n); | |
| for (; __n > 0; ++__first, (void)--__n) | |
| ranges::destroy_at(std::__addressof(*__first)); | |
| return __first; | |
| } | |
| }; | |
| inline constexpr __destroy_n_fn destroy_n{}; | |
| } | |
| _GLIBCXX_END_NAMESPACE_VERSION | |
| } // namespace std | |
| #endif // concepts | |
| #endif // C++20 | |
| #endif // _RANGES_UNINITIALIZED_H |