diff mbox series

[3/3] libstdc++: Use std::__uninitialized_default for ranges::uninitialized_value_construct

Message ID 20240627105217.116315-3-jwakely@redhat.com
State New
Headers show
Series [1/3] libstdc++: Use RAII in <bits/stl_uninitialized.h> | expand

Commit Message

Jonathan Wakely June 27, 2024, 10:39 a.m. UTC
By generalizing std::__uninitialized_default to work with non-common
ranges (i.e. iterator/sentinel pair) we can reuse it for the
ranges::uninitialized_value_construct function. Doing that ensures that
whatever optimizations we have for std::uninitialized_value_construct
are automatically used for the ranges version too.

Tested x86_64-linux.

-- >8 --

This reuses the memset optimization in __uninitialized_default for the
ranges equivalent, and similarly for uninitialized_value_construct_n.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_uninitialized.h (uninitialized_value_construct):
	Use __uninitialized_default.
	(uninitialized_value_construct_n): Use __uninitialized_default_n.
	* include/bits/stl_uninitialized.h (__uninitialized_default):
	Allow first and last to be different types, to support arbitrary
	sentinels. Return the end of the initialized range.
	(uninitialized_value_construct): Discard return value from
	__uninitialized_default.
---
 .../include/bits/ranges_uninitialized.h       | 27 +++----------------
 libstdc++-v3/include/bits/stl_uninitialized.h | 13 +++++----
 2 files changed, 11 insertions(+), 29 deletions(-)
diff mbox series

Patch

diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h
index f16f2ef39f5..d84c8502eb9 100644
--- a/libstdc++-v3/include/bits/ranges_uninitialized.h
+++ b/libstdc++-v3/include/bits/ranges_uninitialized.h
@@ -201,18 +201,8 @@  namespace ranges
       _Iter
       operator()(_Iter __first, _Sent __last) const
       {
-	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
-	if constexpr (is_trivial_v<_ValueType>
-		      && is_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;
-	  }
+	return std::__uninitialized_default(std::move(__first),
+					    std::move(__last));
       }
 
     template<__detail::__nothrow_forward_range _Range>
@@ -234,18 +224,7 @@  namespace ranges
       _Iter
       operator()(_Iter __first, iter_difference_t<_Iter> __n) const
       {
-	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
-	if constexpr (is_trivial_v<_ValueType>
-		      && is_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;
-	  }
+	return std::__uninitialized_default_n(std::move(__first), __n);
       }
   };
 
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index 1216b319f66..b13562992de 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -634,9 +634,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // __uninitialized_default
   // Fills [first, last) with value-initialized value_types.
-  template<typename _ForwardIterator>
-    inline void
-    __uninitialized_default(_ForwardIterator __first, _ForwardIterator __last)
+  template<typename _ForwardIterator, typename _Sentinel>
+    _GLIBCXX20_CONSTEXPR
+    inline _ForwardIterator
+    __uninitialized_default(_ForwardIterator __first, _Sentinel __last)
     {
       if constexpr (__is_random_access_iter<_ForwardIterator>::__value)
 	if (void* __ptr = std::__ptr_for_trivial_zero_init(__first))
@@ -649,14 +650,16 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		const size_t __n = __dist;
 		__glibcxx_assert(__n < __SIZE_MAX__ / sizeof(_ValueType));
 		__builtin_memset(__ptr, 0, __n * sizeof(_ValueType));
+		return __first + __dist;
 	      }
-	    return;
+	    return __first;
 	  }
 
       _UninitDestroyGuard<_ForwardIterator> __guard(__first);
       for (; __first != __last; ++__first)
 	std::_Construct(std::__addressof(*__first));
       __guard.release();
+      return __first;
     }
 
   // __uninitialized_default_n
@@ -939,7 +942,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     uninitialized_value_construct(_ForwardIterator __first,
 				  _ForwardIterator __last)
     {
-      return std::__uninitialized_default(__first, __last);
+      std::__uninitialized_default(__first, __last);
     }
 
   /**