[PATCH] libstdc++: Simplify std::vector::vector(from_range_t, const Alloc&)

Jonathan Wakely jwakely@redhat.com
Thu Mar 20 18:52:06 GMT 2025


Tomasz suggested replacing this constructor with just append_range(rg),
after using a delegating constructor so that the destructor will run if
append_range exits via an exception.

This is slightly less simple than his suggestion, because I want to
avoid the overhead of reserve's slow path and the ASan annotations.
Neither of those is needed for this constructor, because we have no
existing storage to reallocate and no unused capacity to tell ASan
about.

libstdc++-v3/ChangeLog:

	* include/bits/stl_vector.h (vector(from_range_t, Alloc)): Use
	delegating constructor instead of RAII guards. Use append_range
	for unsized input range case.
---

Tested x86_64-linux.

 libstdc++-v3/include/bits/stl_vector.h | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 9c75f64b6ef..09fd53696d1 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -758,7 +758,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       template<__detail::__container_compatible_range<_Tp> _Rg>
 	constexpr
 	vector(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
-	: _Base(__a)
+	: vector(__a)
 	{
 	  if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
 	    {
@@ -766,28 +766,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	      pointer __start =
 		this->_M_allocate(_S_check_init_len(__n,
 						    _M_get_Tp_allocator()));
-	      _Guard_alloc __guard(__start, __n, *this);
 	      this->_M_impl._M_finish = this->_M_impl._M_start = __start;
 	      this->_M_impl._M_end_of_storage = __start + __n;
 	      _Base::_M_append_range(__rg);
-	      (void) __guard._M_release();
 	    }
 	  else
-	    {
-	      // If an exception is thrown ~_Base() will deallocate storage,
-	      // but will not destroy elements. This RAII type destroys them.
-	      struct _Clear
-	      {
-		constexpr ~_Clear() { if (_M_this) _M_this->clear(); }
-		vector* _M_this;
-	      } __guard{this};
-
-	      auto __first = ranges::begin(__rg);
-	      const auto __last = ranges::end(__rg);
-	      for (; __first != __last; ++__first)
-		emplace_back(*__first);
-	      __guard._M_this = nullptr;
-	    }
+	    append_range(std::move(__rg));
 	}
 #endif
 
-- 
2.49.0



More information about the Libstdc++ mailing list