Skip to content

[libc++] Extract destroy algorithms into separate headers #126449

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,14 @@ set(files
__memory/compressed_pair.h
__memory/concepts.h
__memory/construct_at.h
__memory/destroy.h
__memory/destruct_n.h
__memory/inout_ptr.h
__memory/noexcept_move_assign_container.h
__memory/out_ptr.h
__memory/pointer_traits.h
__memory/ranges_construct_at.h
__memory/ranges_destroy.h
__memory/ranges_uninitialized_algorithms.h
__memory/raw_storage_iterator.h
__memory/shared_count.h
Expand Down
7 changes: 3 additions & 4 deletions libcxx/include/__format/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <__algorithm/max.h>
#include <__algorithm/min.h>
#include <__algorithm/ranges_copy.h>
#include <__algorithm/ranges_copy_n.h>
#include <__algorithm/transform.h>
#include <__algorithm/unwrap_iter.h>
#include <__concepts/same_as.h>
Expand All @@ -33,7 +32,7 @@
#include <__memory/allocator.h>
#include <__memory/allocator_traits.h>
#include <__memory/construct_at.h>
#include <__memory/ranges_construct_at.h>
#include <__memory/destroy.h>
#include <__memory/uninitialized_algorithms.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/conditional.h>
Expand Down Expand Up @@ -621,7 +620,7 @@ class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
}

_LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() {
ranges::destroy_n(__ptr_, __size_);
std::destroy_n(__ptr_, __size_);
allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);
}

Expand Down Expand Up @@ -686,7 +685,7 @@ class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
// guard is optimized away so there is no runtime overhead.
std::uninitialized_move_n(__ptr_, __size_, __result.ptr);
__guard.__complete();
ranges::destroy_n(__ptr_, __size_);
std::destroy_n(__ptr_, __size_);
allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_);

__ptr_ = __result.ptr;
Expand Down
37 changes: 3 additions & 34 deletions libcxx/include/__memory/construct_at.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* __construct_at(_Tp* __l
// The internal functions are available regardless of the language version (with the exception of the `__destroy_at`
// taking an array).

template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);

template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy_at(_Tp* __loc) {
_LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
Expand All @@ -70,28 +67,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy_at(_Tp* __loc
template <class _Tp, __enable_if_t<is_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy_at(_Tp* __loc) {
_LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
std::__destroy(std::begin(*__loc), std::end(*__loc));
auto const __end = std::end(*__loc);
for (auto __it = std::begin(*__loc); __it != __end; ++__it)
std::__destroy_at(__it);
Comment on lines +70 to +72
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to note: the previous implementation was based on the standard wording. I think this is simple enough that the change in implementation is fine.

}
#endif

template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
__destroy(_ForwardIterator __first, _ForwardIterator __last) {
for (; __first != __last; ++__first)
std::__destroy_at(std::addressof(*__first));
return __first;
}

template <class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator
__reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last) {
while (__last != __first) {
--__last;
std::__destroy_at(std::addressof(*__last));
}
return __last;
}

#if _LIBCPP_STD_VER >= 17

template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0>
Expand All @@ -106,18 +87,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy_at(_Tp* __loc)
}
# endif

template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy(_ForwardIterator __first, _ForwardIterator __last) {
(void)std::__destroy(std::move(__first), std::move(__last));
}

template <class _ForwardIterator, class _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
for (; __n > 0; (void)++__first, --__n)
std::__destroy_at(std::addressof(*__first));
return __first;
}

#endif // _LIBCPP_STD_VER >= 17

_LIBCPP_END_NAMESPACE_STD
Expand Down
71 changes: 71 additions & 0 deletions libcxx/include/__memory/destroy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//===----------------------------------------------------------------------===//
//
// 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_DESTROY_H
#define _LIBCPP___MEMORY_DESTROY_H

#include <__config>
#include <__memory/addressof.h>
#include <__memory/allocator_traits.h>
#include <__memory/construct_at.h>
#include <__utility/move.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
__destroy(_ForwardIterator __first, _ForwardIterator __last) {
for (; __first != __last; ++__first)
std::__destroy_at(std::addressof(*__first));
return __first;
}

template <class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator
__reverse_destroy(_BidirectionalIterator __first, _BidirectionalIterator __last) {
while (__last != __first) {
--__last;
std::__destroy_at(std::addressof(*__last));
}
return __last;
}

// Destroy all elements in [__first, __last) from left to right using allocator destruction.
template <class _Alloc, class _Iter, class _Sent>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) {
for (; __first != __last; ++__first)
allocator_traits<_Alloc>::destroy(__alloc, std::addressof(*__first));
}

#if _LIBCPP_STD_VER >= 17
template <class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy(_ForwardIterator __first, _ForwardIterator __last) {
(void)std::__destroy(std::move(__first), std::move(__last));
}

template <class _ForwardIterator, class _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
for (; __n > 0; (void)++__first, --__n)
std::__destroy_at(std::addressof(*__first));
return __first;
}
#endif

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___MEMORY_DESTROY_H
35 changes: 0 additions & 35 deletions libcxx/include/__memory/ranges_construct_at.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,41 +61,6 @@ inline namespace __cpo {
inline constexpr auto destroy_at = __destroy_at{};
} // namespace __cpo

// destroy

struct __destroy {
template <__nothrow_input_iterator _InputIterator, __nothrow_sentinel_for<_InputIterator> _Sentinel>
requires destructible<iter_value_t<_InputIterator>>
_LIBCPP_HIDE_FROM_ABI constexpr _InputIterator operator()(_InputIterator __first, _Sentinel __last) const noexcept {
return std::__destroy(std::move(__first), std::move(__last));
}

template <__nothrow_input_range _InputRange>
requires destructible<range_value_t<_InputRange>>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_InputRange> operator()(_InputRange&& __range) const noexcept {
return (*this)(ranges::begin(__range), ranges::end(__range));
}
};

inline namespace __cpo {
inline constexpr auto destroy = __destroy{};
} // namespace __cpo

// destroy_n

struct __destroy_n {
template <__nothrow_input_iterator _InputIterator>
requires destructible<iter_value_t<_InputIterator>>
_LIBCPP_HIDE_FROM_ABI constexpr _InputIterator
operator()(_InputIterator __first, iter_difference_t<_InputIterator> __n) const noexcept {
return std::destroy_n(std::move(__first), __n);
}
};

inline namespace __cpo {
inline constexpr auto destroy_n = __destroy_n{};
} // namespace __cpo

} // namespace ranges

#endif // _LIBCPP_STD_VER >= 20
Expand Down
79 changes: 79 additions & 0 deletions libcxx/include/__memory/ranges_destroy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// -*- 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_DESTROY_H
#define _LIBCPP___MEMORY_RANGES_DESTROY_H

#include <__concepts/destructible.h>
#include <__config>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__memory/concepts.h>
#include <__memory/destroy.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
#include <__utility/move.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER >= 20
namespace ranges {

// destroy

struct __destroy {
template <__nothrow_input_iterator _InputIterator, __nothrow_sentinel_for<_InputIterator> _Sentinel>
requires destructible<iter_value_t<_InputIterator>>
_LIBCPP_HIDE_FROM_ABI constexpr _InputIterator operator()(_InputIterator __first, _Sentinel __last) const noexcept {
return std::__destroy(std::move(__first), std::move(__last));
}

template <__nothrow_input_range _InputRange>
requires destructible<range_value_t<_InputRange>>
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_InputRange> operator()(_InputRange&& __range) const noexcept {
return (*this)(ranges::begin(__range), ranges::end(__range));
}
};

inline namespace __cpo {
inline constexpr auto destroy = __destroy{};
} // namespace __cpo

// destroy_n

struct __destroy_n {
template <__nothrow_input_iterator _InputIterator>
requires destructible<iter_value_t<_InputIterator>>
_LIBCPP_HIDE_FROM_ABI constexpr _InputIterator
operator()(_InputIterator __first, iter_difference_t<_InputIterator> __n) const noexcept {
return std::destroy_n(std::move(__first), __n);
}
};

inline namespace __cpo {
inline constexpr auto destroy_n = __destroy_n{};
} // namespace __cpo

} // namespace ranges

#endif // _LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___MEMORY_RANGES_DESTROY_H
1 change: 1 addition & 0 deletions libcxx/include/__memory/shared_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
#include <__memory/construct_at.h>
#include <__memory/destroy.h>
#include <__memory/pointer_traits.h>
#include <__memory/shared_count.h>
#include <__memory/uninitialized_algorithms.h>
Expand Down
9 changes: 1 addition & 8 deletions libcxx/include/__memory/uninitialized_algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <__memory/addressof.h>
#include <__memory/allocator_traits.h>
#include <__memory/construct_at.h>
#include <__memory/destroy.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/extent.h>
Expand Down Expand Up @@ -511,14 +512,6 @@ __uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _B

#endif // _LIBCPP_STD_VER >= 17

// Destroy all elements in [__first, __last) from left to right using allocator destruction.
template <class _Alloc, class _Iter, class _Sent>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__allocator_destroy(_Alloc& __alloc, _Iter __first, _Sent __last) {
for (; __first != __last; ++__first)
allocator_traits<_Alloc>::destroy(__alloc, std::__to_address(__first));
}

template <class _Alloc, class _Iter>
class _AllocatorDestroyRangeReverse {
public:
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__pstl/backends/libdispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <__iterator/move_iterator.h>
#include <__memory/allocator.h>
#include <__memory/construct_at.h>
#include <__memory/destroy.h>
#include <__memory/unique_ptr.h>
#include <__new/exceptions.h>
#include <__numeric/reduce.h>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/memory
Original file line number Diff line number Diff line change
Expand Up @@ -958,12 +958,14 @@ template<class Pointer = void, class Smart, class... Args>

# if _LIBCPP_STD_VER >= 17
# include <__memory/construct_at.h>
# include <__memory/destroy.h>
# endif

# if _LIBCPP_STD_VER >= 20
# include <__memory/assume_aligned.h>
# include <__memory/concepts.h>
# include <__memory/ranges_construct_at.h>
# include <__memory/ranges_destroy.h>
# include <__memory/ranges_uninitialized_algorithms.h>
# include <__memory/uses_allocator_construction.h>
# endif
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -1567,13 +1567,15 @@ module std [system] {
module compressed_pair { header "__memory/compressed_pair.h" }
module concepts { header "__memory/concepts.h" }
module construct_at { header "__memory/construct_at.h" }
module destroy { header "__memory/destroy.h" }
module destruct_n { header "__memory/destruct_n.h" }
module fwd { header "__fwd/memory.h" }
module inout_ptr { header "__memory/inout_ptr.h" }
module noexcept_move_assign_container { header "__memory/noexcept_move_assign_container.h" }
module out_ptr { header "__memory/out_ptr.h" }
module pointer_traits { header "__memory/pointer_traits.h" }
module ranges_construct_at { header "__memory/ranges_construct_at.h" }
module ranges_destroy { header "__memory/ranges_destroy.h" }
module ranges_uninitialized_algorithms {
header "__memory/ranges_uninitialized_algorithms.h"
export std.algorithm.in_out_result
Expand Down