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

Jonathan Wakely jwakely@redhat.com
Thu Mar 20 19:03:24 GMT 2025


I forgot I'd tweaked my git-send-email settings and so this patch
didn't get sent to gcc-patches, sorry. Resending ...


On 20/03/25 18:52 +0000, Jonathan Wakely wrote:
>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