Patchwork [v3] uninitialized_* clean up

login
register
mail settings
Submitter Paolo Carlini
Date June 16, 2010, 12:31 p.m.
Message ID <4C18C41B.1090602@oracle.com>
Download mbox | patch
Permalink /patch/55876/
State New
Headers show

Comments

Paolo Carlini - June 16, 2010, 12:31 p.m.
Hi,

a small clean-up figured out while working on various other issues: move
the recently added _Temp_buf helper with the latter; simplify
uninitialized_copy_n, consistently with all the other uninitialized_*,
to use _Construct (which perfectly forward in C++0x mode); change
_Construct to variadic consistently with allocator::construct (thus will
also work for default construction)

Tested x86-64-linux without PCHs, committed to mainline.

Paolo.

//////////////////////
2010-06-16  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/stl_construct.h (_Construct): Change to variadic in
	C++0x mode, consistently with allocator::construct.
	* include/bits/stl_uninitialized.h (__uninitialized_copy_n): Use
	_Construct.
	(__uninitialized_construct_range): Move to...
	* include/bits/stl_tempbuf.h (__uninitialized_construct_buf): ... here.

Patch

Index: include/bits/stl_uninitialized.h
===================================================================
--- include/bits/stl_uninitialized.h	(revision 160826)
+++ include/bits/stl_uninitialized.h	(working copy)
@@ -173,70 +173,6 @@ 
 
 
   template<bool>
-    struct __uninitialized_construct_range_dispatch
-    {
-      template<typename _ForwardIterator, typename _Tp>
-        static void
-        __ucr(_ForwardIterator __first, _ForwardIterator __last,
-	      _Tp& __value)
-        {
-	  if(__first == __last)
-	    return;
-
-	  _ForwardIterator __cur = __first;
-	  __try
-	    {
-	      std::_Construct(std::__addressof(*__first),
-			      _GLIBCXX_MOVE(__value));
-	      _ForwardIterator __prev = __cur;
-	      ++__cur;
-	      for(; __cur != __last; ++__cur, ++__prev)
-		std::_Construct(std::__addressof(*__cur),
-				_GLIBCXX_MOVE(*__prev));
-	      __value = _GLIBCXX_MOVE(*__prev);
-	    }
-	  __catch(...)
-	    {
-	      std::_Destroy(__first, __cur);
-	      __throw_exception_again;
-	    }
-	}
-    };
-
-  template<>
-    struct __uninitialized_construct_range_dispatch<true>
-    {
-      template<typename _ForwardIterator, typename _Tp>
-        static void
-        __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
-    };
-
-  // Constructs objects in the range [first, last).
-  // Note that while these new objects will take valid values,
-  // their exact value is not defined. In particular they may
-  // be 'moved from'.
-  //
-  // While __value may altered during this algorithm, it will have
-  // the same value when the algorithm finishes, unless one of the
-  // constructions throws.
-  //
-  // Requirements: _ForwardIterator::value_type(_Tp&&) is valid.
-  template<typename _ForwardIterator, typename _Tp>
-    inline void
-    __uninitialized_construct_range(_ForwardIterator __first,
-				    _ForwardIterator __last,
-				    _Tp& __value)
-    {
-      typedef typename std::iterator_traits<_ForwardIterator>::value_type
-	_ValueType;
-
-      std::__uninitialized_construct_range_dispatch<
-        __has_trivial_constructor(_ValueType)>::
-	  __ucr(__first, __last, __value);
-    }
-
-
-  template<bool>
     struct __uninitialized_fill_n
     {
       template<typename _ForwardIterator, typename _Size, typename _Tp>
@@ -501,8 +437,7 @@ 
       __try
 	{
 	  for (; __n > 0; --__n, ++__first, ++__cur)
-	    ::new(static_cast<void*>(std::__addressof(*__cur))) typename
-		iterator_traits<_ForwardIterator>::value_type(*__first);
+	    std::_Construct(std::__addressof(*__cur), *__first);
 	  return __cur;
 	}
       __catch(...)
Index: include/bits/stl_tempbuf.h
===================================================================
--- include/bits/stl_tempbuf.h	(revision 160826)
+++ include/bits/stl_tempbuf.h	(working copy)
@@ -59,7 +59,6 @@ 
 
 #include <bits/stl_algobase.h>
 #include <bits/stl_construct.h>
-#include <bits/stl_uninitialized.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
@@ -176,7 +175,71 @@ 
       operator=(const _Temporary_buffer&);
     };
 
+
+  template<bool>
+    struct __uninitialized_construct_buf_dispatch
+    {
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        __ucr(_ForwardIterator __first, _ForwardIterator __last,
+	      _Tp& __value)
+        {
+	  if(__first == __last)
+	    return;
+
+	  _ForwardIterator __cur = __first;
+	  __try
+	    {
+	      std::_Construct(std::__addressof(*__first),
+			      _GLIBCXX_MOVE(__value));
+	      _ForwardIterator __prev = __cur;
+	      ++__cur;
+	      for(; __cur != __last; ++__cur, ++__prev)
+		std::_Construct(std::__addressof(*__cur),
+				_GLIBCXX_MOVE(*__prev));
+	      __value = _GLIBCXX_MOVE(*__prev);
+	    }
+	  __catch(...)
+	    {
+	      std::_Destroy(__first, __cur);
+	      __throw_exception_again;
+	    }
+	}
+    };
+
+  template<>
+    struct __uninitialized_construct_buf_dispatch<true>
+    {
+      template<typename _ForwardIterator, typename _Tp>
+        static void
+        __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { }
+    };
+
+  // Constructs objects in the range [first, last).
+  // Note that while these new objects will take valid values,
+  // their exact value is not defined. In particular they may
+  // be 'moved from'.
+  //
+  // While __value may altered during this algorithm, it will have
+  // the same value when the algorithm finishes, unless one of the
+  // constructions throws.
+  //
+  // Requirements: _ForwardIterator::value_type(_Tp&&) is valid.
   template<typename _ForwardIterator, typename _Tp>
+    inline void
+    __uninitialized_construct_buf(_ForwardIterator __first,
+				  _ForwardIterator __last,
+				  _Tp& __value)
+    {
+      typedef typename std::iterator_traits<_ForwardIterator>::value_type
+	_ValueType;
+
+      std::__uninitialized_construct_buf_dispatch<
+        __has_trivial_constructor(_ValueType)>::
+	  __ucr(__first, __last, __value);
+    }
+
+  template<typename _ForwardIterator, typename _Tp>
     _Temporary_buffer<_ForwardIterator, _Tp>::
     _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last)
     : _M_original_len(std::distance(__first, __last)),
@@ -189,8 +252,8 @@ 
 	  _M_buffer = __p.first;
 	  _M_len = __p.second;
 	  if(_M_buffer)
-	    std::__uninitialized_construct_range(_M_buffer, _M_buffer + _M_len,
-						 *__first);
+	    std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
+					       *__first);
 	}
       __catch(...)
 	{
Index: include/bits/stl_construct.h
===================================================================
--- include/bits/stl_construct.h	(revision 160826)
+++ include/bits/stl_construct.h	(working copy)
@@ -67,19 +67,21 @@ 
    * Constructs an object in existing memory by invoking an allocated
    * object's constructor with an initializer.
    */
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<typename _T1, typename... _Args>
+    inline void
+    _Construct(_T1* __p, _Args&&... __args)
+    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
+#else
   template<typename _T1, typename _T2>
     inline void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-    // Allow perfect forwarding
-    _Construct(_T1* __p, _T2&& __value)
-#else
     _Construct(_T1* __p, const _T2& __value)
-#endif
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 402. wrong new expression in [some_]allocator::construct
-      ::new(static_cast<void*>(__p)) _T1(_GLIBCXX_FORWARD(_T2, __value));
+      ::new(static_cast<void*>(__p)) _T1(__value);
     }
+#endif
 
   /**
    * Destroy the object pointed to by a pointer type.