diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -231,6 +231,7 @@ __memory/concepts.h __memory/construct_at.h __memory/pointer_traits.h + __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h __memory/shared_ptr.h __memory/temporary_buffer.h diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -0,0 +1,209 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H + +#include <__config> +#include <__memory/concepts.h> +#include <__memory/uninitialized_algorithms.h> +#include <__ranges/dangling.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +// uninitialized_default_construct + +template <__nothrow_forward_iterator _Ip, __nothrow_sentinel_for<_Ip> _Sp> + requires default_initializable> +_Ip uninitialized_default_construct(_Ip __first, _Sp __last) { + using _ValueType = remove_reference_t>; + return __uninitialized_default_construct<_ValueType>(__first, __last); +} + +template <__nothrow_forward_range _Rp> + requires default_initializable> +borrowed_iterator_t<_Rp> uninitialized_default_construct(_Rp&& __r) { + return uninitialized_default_construct(__r.begin(), __r.end()); +} + +// uninitialized_default_construct_n + +template<__nothrow_forward_iterator _Ip> + requires default_initializable> +_Ip uninitialized_default_construct_n(_Ip __first, iter_difference_t<_Ip> __n) { + using _ValueType = remove_reference_t>; + return __uninitialized_default_construct_n<_ValueType>(__first, __n); +} + +// uninitialized_value_construct + +template<__nothrow_forward_iterator _Ip, __nothrow_sentinel_for<_Ip> _Sp> + requires default_initializable> +_Ip uninitialized_value_construct(_Ip __first, _Sp __last) { + using _ValueType = remove_reference_t>; + return __uninitialized_value_construct<_ValueType>(__first, __last); +} + +template<__nothrow_forward_range _Rp> + requires default_initializable> +borrowed_iterator_t<_Rp> uninitialized_value_construct(_Rp&& __r) { + return uninitialized_value_construct(__r.begin(), __r.end()); +} + +// uninitialized_value_construct_n + +template <__nothrow_forward_iterator _Ip> + requires default_initializable> +_Ip uninitialized_value_construct_n(_Ip __first, iter_difference_t<_Ip> __n) { + using _ValueType = remove_reference_t>; + return __uninitialized_value_construct_n<_ValueType>(__first, __n); +} + +// uninitialized_fill + +template <__nothrow_forward_iterator _Ip, __nothrow_sentinel_for<_Ip> _Sp, class _Tp> + requires constructible_from, const _Tp&> +_Ip uninitialized_fill(_Ip __first, _Sp __last, const _Tp& __x) { + using _ValueType = remove_reference_t>; + return __uninitialized_fill<_ValueType>(__first, __last, __x); +} + +template <__nothrow_forward_range _Rp, class _Tp> + requires constructible_from, const _Tp&> +borrowed_iterator_t<_Rp> uninitialized_fill(_Rp&& __r, const _Tp& __x) { + return uninitialized_fill(__r.begin(), __r.end(), __x); +} + +// uninitialized_fill_n + +template <__nothrow_forward_iterator _Ip, class _Tp> + requires constructible_from, const _Tp&> +_Ip uninitialized_fill_n(_Ip __first, iter_difference_t<_Ip> __n, const _Tp& __x) { +} + +// in_out_result + +template +struct in_out_result { + [[no_unique_address]] _Ip in; + [[no_unique_address]] _Op out; + // TODO: the rest +}; + +// uninitialized_copy + +template +using uninitialized_copy_result = in_out_result<_Ip, _Op>; + +template _Sp1, + __nothrow_forward_iterator _Op, __nothrow_sentinel_for<_Op> _Sp2> + requires constructible_from, iter_rvalue_reference_t<_Ip>> +uninitialized_copy_result<_Ip, _Op> uninitialized_copy(_Ip __ifirst, + _Sp1 __ilast, _Op __ofirst, _Sp2 __olast) { + using _ValueType = remove_reference_t>; + auto __first_res = __ifirst; + auto __idx = __ofirst; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void) ++__ifirst) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(*__ifirst); + return {_VSTD::move(__ifirst), __idx}; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first_res, __idx); + throw; + } +#endif +} + +template + requires constructible_from, range_rvalue_reference_t<_InputRange>> +uninitialized_copy_result, borrowed_iterator_t<_OutputRange>> +uninitialized_copy(_InputRange&& __in_range, _OutputRange&& __out_range) { + return uninitialized_copy(__in_range.begin(), __in_range.end(), + __out_range.begin(), __out_range.end()); +} + +// uninitialized_copy_n + +template +using uninitialized_copy_n_result = in_out_result<_Ip, _Op>; + +template _Sp> + requires constructible_from, iter_rvalue_reference_t<_Ip>> +uninitialized_copy_n_result<_Ip, _Op> +uninitialized_copy_n(_Ip __ifirst, iter_difference_t<_Ip> __n, _Op __ofirst, _Sp __olast) { + auto result = uninitialized_copy(counted_iterator(__ifirst, __n), + default_sentinel, __ofirst, __olast); + return {_VSTD::move(result.in).base(), result.out}; +} + +// uninitialized_move + +template +using uninitialized_move_result = in_out_result<_Ip, _Op>; + +template _Sp1, + __nothrow_forward_iterator _Op, __nothrow_sentinel_for<_Op> _Sp2> + requires constructible_from, iter_rvalue_reference_t<_Ip>> +uninitialized_move_result<_Ip, _Op> uninitialized_move(_Ip __ifirst, + _Sp1 __ilast, _Op __ofirst, _Sp2 __olast) { + using _ValueType = remove_reference_t>; + auto __first_res = __ifirst; + auto __idx = __ofirst; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void) ++__ifirst) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(_VSTD::ranges::iter_move(__ifirst)); + return {_VSTD::move(__ifirst), __idx}; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first_res, __idx); + throw; + } +#endif +} + +template + requires constructible_from, range_rvalue_reference_t<_InputRange>> +uninitialized_move_result, borrowed_iterator_t<_OutputRange>> +uninitialized_move(_InputRange&& __in_range, _OutputRange&& __out_range) { + return uninitialized_move(__in_range.begin(), __in_range.end(), + __out_range.begin(), __out_range.end()); +} + +// uninitialized_move_n + +template +using uninitialized_move_n_result = in_out_result<_Ip, _Op>; + +template _Sp> + requires constructible_from, iter_rvalue_reference_t<_Ip>> +uninitialized_move_n_result<_Ip, _Op> +uninitialized_move_n(_Ip __ifirst, iter_difference_t<_Ip> __n, _Op __ofirst, _Sp __olast) { + auto result = uninitialized_move(counted_iterator(__ifirst, __n), + default_sentinel, __ofirst, __olast); + return {_VSTD::move(result.in).base(), result.out}; +} + +} // namespace ranges +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H diff --git a/libcxx/include/__memory/uninitialized_algorithms.h b/libcxx/include/__memory/uninitialized_algorithms.h --- a/libcxx/include/__memory/uninitialized_algorithms.h +++ b/libcxx/include/__memory/uninitialized_algorithms.h @@ -22,189 +22,232 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_ForwardIterator -uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +#if _LIBCPP_STD_VER > 14 + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) { + auto __idx = __first; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __f != __l; ++__f, (void) ++__r) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __idx != __last; ++__idx) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType; + return __idx; #ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); +#endif +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + (void)__uninitialized_default_construct<_ValueType>(__first, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __n > 0; ++__idx, (void) --__n) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType; + return __idx; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); throw; } #endif - return __r; } -template -_ForwardIterator -uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + return __uninitialized_default_construct_n<_ValueType>(__first, __n); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) { + auto __idx = __first; #ifndef _LIBCPP_NO_EXCEPTIONS - _ForwardIterator __s = __r; - try - { + try { #endif - for (; __n > 0; ++__f, (void) ++__r, (void) --__n) - ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f); + for (; __idx != __last; ++__idx) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(); + return __idx; #ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; } - catch (...) - { - for (; __s != __r; ++__s) - __s->~value_type(); +#endif +} + +template +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + __uninitialized_value_construct<_ValueType>(__first, __last); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __n > 0; ++__idx, (void) --__n) + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(); + return __idx; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); throw; } #endif - return __r; } -template -void -uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) +template +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { + using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; + return __uninitialized_value_construct_n<_ValueType>(__first, __n); +} + +#endif // _LIBCPP_STD_VER > 14 + +template +_ForwardIterator +__uninitialized_fill(_ForwardIterator __f, _Sentinel __l, const _Tp& __x) { - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; #ifndef _LIBCPP_NO_EXCEPTIONS _ForwardIterator __s = __f; try { #endif for (; __f != __l; ++__f) - ::new ((void*)_VSTD::addressof(*__f)) value_type(__x); + ::new ((void*)_VSTD::addressof(*__f)) _ValueType(__x); + return __f; #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { for (; __s != __f; ++__s) - __s->~value_type(); + __s->~_ValueType(); throw; } #endif } -template +template +void +uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + __uninitialized_fill<_ValueType>(__f, __l, __x); +} + +template _ForwardIterator -uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) +__uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) { - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; #ifndef _LIBCPP_NO_EXCEPTIONS _ForwardIterator __s = __f; try { #endif for (; __n > 0; ++__f, (void) --__n) - ::new ((void*)_VSTD::addressof(*__f)) value_type(__x); + ::new ((void*)_VSTD::addressof(*__f)) _ValueType(__x); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { for (; __s != __f; ++__s) - __s->~value_type(); + __s->~_ValueType(); throw; } #endif return __f; } -#if _LIBCPP_STD_VER > 14 - -template -inline _LIBCPP_INLINE_VISIBILITY -void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { - using _Vt = typename iterator_traits<_ForwardIterator>::value_type; - auto __idx = __first; -#ifndef _LIBCPP_NO_EXCEPTIONS - try { -#endif - for (; __idx != __last; ++__idx) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt; -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first, __idx); - throw; - } -#endif +template +_ForwardIterator +uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + return __uninitialized_fill_n<_ValueType>(__f, __n, __x); } -template -inline _LIBCPP_INLINE_VISIBILITY -_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { - using _Vt = typename iterator_traits<_ForwardIterator>::value_type; - auto __idx = __first; +template +_ForwardIterator +uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + _ForwardIterator __s = __r; + try + { #endif - for (; __n > 0; ++__idx, (void) --__n) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt; - return __idx; + for (; __f != __l; ++__f, (void) ++__r) + ::new ((void*)_VSTD::addressof(*__r)) _ValueType(*__f); #ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first, __idx); - throw; } -#endif -} - - -template -inline _LIBCPP_INLINE_VISIBILITY -void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { - using _Vt = typename iterator_traits<_ForwardIterator>::value_type; - auto __idx = __first; -#ifndef _LIBCPP_NO_EXCEPTIONS - try { -#endif - for (; __idx != __last; ++__idx) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(); -#ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first, __idx); + catch (...) + { + for (; __s != __r; ++__s) + __s->~_ValueType(); throw; } #endif + return __r; } -template -inline _LIBCPP_INLINE_VISIBILITY -_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { - using _Vt = typename iterator_traits<_ForwardIterator>::value_type; - auto __idx = __first; +template +_ForwardIterator +uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) +{ + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; #ifndef _LIBCPP_NO_EXCEPTIONS - try { + _ForwardIterator __s = __r; + try + { #endif - for (; __n > 0; ++__idx, (void) --__n) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(); - return __idx; + for (; __n > 0; ++__f, (void) ++__r, (void) --__n) + ::new ((void*)_VSTD::addressof(*__r)) _ValueType(*__f); #ifndef _LIBCPP_NO_EXCEPTIONS - } catch (...) { - _VSTD::destroy(__first, __idx); + } + catch (...) + { + for (; __s != __r; ++__s) + __s->~_ValueType(); throw; } #endif + return __r; } +#if _LIBCPP_STD_VER > 14 template inline _LIBCPP_INLINE_VISIBILITY _ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; + using _ValueType = typename iterator_traits<_ForwardIt>::value_type; auto __idx = __first_res; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif for (; __first != __last; ++__idx, (void) ++__first) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(_VSTD::move(*__first)); return __idx; #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { @@ -218,13 +261,13 @@ inline _LIBCPP_INLINE_VISIBILITY pair<_InputIt, _ForwardIt> uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) { - using _Vt = typename iterator_traits<_ForwardIt>::value_type; + using _ValueType = typename iterator_traits<_ForwardIt>::value_type; auto __idx = __first_res; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif for (; __n > 0; ++__idx, (void) ++__first, --__n) - ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first)); + ::new ((void*)_VSTD::addressof(*__idx)) _ValueType(_VSTD::move(*__first)); return {__first, __idx}; #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -672,6 +672,7 @@ #include <__memory/concepts.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__memory/ranges_uninitialized_algorithms.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> #include <__memory/temporary_buffer.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -630,22 +630,23 @@ export * module __memory { - module addressof { private header "__memory/addressof.h" } - module allocation_guard { private header "__memory/allocation_guard.h" } - module allocator { private header "__memory/allocator.h" } - module allocator_arg_t { private header "__memory/allocator_arg_t.h" } - module allocator_traits { private header "__memory/allocator_traits.h" } - module auto_ptr { private header "__memory/auto_ptr.h" } - module compressed_pair { private header "__memory/compressed_pair.h" } - module concepts { private header "__memory/concepts.h" } - module construct_at { private header "__memory/construct_at.h" } - module pointer_traits { private header "__memory/pointer_traits.h" } - module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } - module shared_ptr { private header "__memory/shared_ptr.h" } - module temporary_buffer { private header "__memory/temporary_buffer.h" } - module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" } - module unique_ptr { private header "__memory/unique_ptr.h" } - module uses_allocator { private header "__memory/uses_allocator.h" } + module addressof { private header "__memory/addressof.h" } + module allocation_guard { private header "__memory/allocation_guard.h" } + module allocator { private header "__memory/allocator.h" } + module allocator_arg_t { private header "__memory/allocator_arg_t.h" } + module allocator_traits { private header "__memory/allocator_traits.h" } + module auto_ptr { private header "__memory/auto_ptr.h" } + module compressed_pair { private header "__memory/compressed_pair.h" } + module concepts { private header "__memory/concepts.h" } + module construct_at { private header "__memory/construct_at.h" } + module pointer_traits { private header "__memory/pointer_traits.h" } + module ranges_uninitialized_algorithms { private header "__memory/ranges_uninitialized_algorithms.h" } + module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } + module shared_ptr { private header "__memory/shared_ptr.h" } + module temporary_buffer { private header "__memory/temporary_buffer.h" } + module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" } + module unique_ptr { private header "__memory/unique_ptr.h" } + module uses_allocator { private header "__memory/uses_allocator.h" } } } module mutex {