[v3 PATCH] PR libstdc++/77619

Jonathan Wakely jwakely@redhat.com
Tue Sep 20 14:07:00 GMT 2016


On 18/09/16 21:07 +0300, Ville Voutilainen wrote:
>diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
>index 3d12628..c7ca1f8 100644
>--- a/libstdc++-v3/include/bits/stl_construct.h
>+++ b/libstdc++-v3/include/bits/stl_construct.h
>@@ -83,6 +83,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>       ::new(static_cast<void*>(__p)) _T1(__value);
>     }
> #endif

Blank line here please.

>+  template<typename _T1>
>+    inline void
>+    _Construct_novalue(_T1* __p)
>+    { ::new(static_cast<void*>(__p)) _T1; }
>
>   /**
>    * Destroy the object pointed to by a pointer type.


>diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
>index c5c81fb..b4213d5 100644
>--- a/libstdc++-v3/include/bits/stl_uninitialized.h
>+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
>@@ -640,6 +644,104 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> 				allocator<_Tp>&)
>     { return std::__uninitialized_default_n(__first, __n); }
>
>+  template<bool _TrivialValueType>
>+    struct __uninitialized_default_novalue_1
>+    {
>+      template<typename _ForwardIterator>
>+        static void
>+        __uninit_default_novalue(_ForwardIterator __first,
>+				 _ForwardIterator __last)
>+        {
          ...
>+	}

The left brace is indented with spaces and the right one with a tab,
might as well make them the same.

>+    };
>+
>+  template<>
>+    struct __uninitialized_default_novalue_1<true>
>+    {
>+      template<typename _ForwardIterator>
>+        static void
>+        __uninit_default_novalue(_ForwardIterator __first,
>+				 _ForwardIterator __last)
>+        {
>+	}

Ditto.

>+    };
>+
>+  template<bool _TrivialValueType>
>+    struct __uninitialized_default_novalue_n_1
>+    {
>+      template<typename _ForwardIterator, typename _Size>
>+        static _ForwardIterator
>+        __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
>+        {
>+	  _ForwardIterator __cur = __first;
>+	  __try
>+	    {
>+	      for (; __n > 0; --__n, ++__cur)
>+		std::_Construct_novalue(std::__addressof(*__cur));
>+	      return __cur;
>+	    }
>+	  __catch(...)
>+	    {
>+	      std::_Destroy(__first, __cur);
>+	      __throw_exception_again;
>+	    }
>+	}

Ditto.

>+    };
>+
>+  template<>
>+    struct __uninitialized_default_novalue_n_1<true>
>+    {
>+      template<typename _ForwardIterator, typename _Size>
>+        static _ForwardIterator
>+        __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
>+        {
>+	}

Ditto.

>+    };
>+
>+  // __uninitialized_default_novalue
>+  // Fills [first, last) with std::distance(first, last) default-initialized
>+  // value_types(s).
>+  template<typename _ForwardIterator>
>+    inline void
>+    __uninitialized_default_novalue(_ForwardIterator __first,
>+				    _ForwardIterator __last)
>+    {
>+      typedef typename iterator_traits<_ForwardIterator>::value_type
>+	_ValueType;
>+      // trivial types can have deleted assignment
>+      const bool __assignable = is_copy_assignable<_ValueType>::value;

Aha! A non-whitespace comment ... __assignable isn't used. If it's not
needed it can be removed.

>+      std::__uninitialized_default_novalue_1<
>+	is_trivially_default_constructible<_ValueType>::value>::
>+	__uninit_default_novalue(__first, __last);
>+    }
>+
>+  // __uninitialized_default_n
>+  // Fills [first, first + n) with n default-initialized value_type(s).
>+  template<typename _ForwardIterator, typename _Size>
>+    inline _ForwardIterator
>+    __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
>+    {
>+      typedef typename iterator_traits<_ForwardIterator>::value_type
>+	_ValueType;
>+      // trivial types can have deleted assignment
>+      const bool __assignable = is_copy_assignable<_ValueType>::value;

Ditto.

>+      return __uninitialized_default_novalue_n_1<
>+	is_trivially_default_constructible<_ValueType>::value>::
>+	__uninit_default_novalue_n(__first, __n);
>+    }
>
>   template<typename _InputIterator, typename _Size,
> 	   typename _ForwardIterator>
>@@ -669,6 +771,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> 			   random_access_iterator_tag)
>     { return std::uninitialized_copy(__first, __first + __n, __result); }
>
>+  template<typename _InputIterator, typename _Size,
>+	   typename _ForwardIterator>
>+    pair<_InputIterator, _ForwardIterator>
>+    __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
>+			   _ForwardIterator __result, input_iterator_tag)
>+    {
>+      _ForwardIterator __cur = __result;
>+      __try
>+	{
>+	  for (; __n > 0; --__n, ++__first, ++__cur)
>+	    std::_Construct(std::__addressof(*__cur), *__first);
>+	  return {__first, __cur};
>+	}
>+      __catch(...)
>+	{
>+	  std::_Destroy(__result, __cur);
>+	  __throw_exception_again;
>+	}
>+    }
>+
>+  template<typename _RandomAccessIterator, typename _Size,
>+	   typename _ForwardIterator>
>+    inline pair<_RandomAccessIterator, _ForwardIterator>
>+    __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
>+			   _ForwardIterator __result,
>+			   random_access_iterator_tag)
>+    {
>+      auto second = uninitialized_copy(__first, __first + __n, __result);
>+      auto first = std::next(__first, __n);
>+      return {first, second};

I was going to say these names need to be uglified, but they can't be
macros due to std::pair. Carry on.

>@@ -744,35 +877,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     uninitialized_move_n(_InputIterator __first, _Size __count,
> 			 _ForwardIterator __result)
>   {
>-    for (; __count > 0; ++__result, (void) ++__first, --__count)
>-      ::new (static_cast<void*>(std::__addressof(*__result)))
>-	  typename
>-	  iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
>-    return {__first, __result};
>+    auto res = std::__uninitialized_copy_n_pair
>+      (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
>+       __count, __result);
>+    return {res.first.base(), res.second};

However, res isn't a reserved name AFAIK, so should be __res.

OK for trunk with that change, and the whitespace changes if you would
be so kind. Thanks.



More information about the Libstdc++ mailing list