Patchwork [v3] Add __uninitialized_default*; use __is_trivial instead of __is_pod in most places

login
register
mail settings
Submitter Paolo Carlini
Date June 17, 2010, 8:41 a.m.
Message ID <4C19DF9E.4040506@oracle.com>
Download mbox | patch
Permalink /patch/55986/
State New
Headers show

Comments

Paolo Carlini - June 17, 2010, 8:41 a.m.
Hi,

Some infrastructure for forthcoming C++0x work + finally got around to
use __is_trivial instead of the more restrictive __is_pod in many
places. About the latter in particular, I'm also adding in CC Jason -
implemented __is_trivial and briefly discussed with him the rather
straightforward plan of replacing most dispatches in the library based
on POD-ness to trivial-ness.

Tested x86_64-linux, committed to mainline.

Paolo.

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

	* include/bits/stl_uninitialized.h (__uninitialized_default,
	__uninitialized_default_n, __uninitialized_default_a,
	__uninitialized_default_n_a): Add.

	* include/bits/stl_uninitialized.h (uninitialized_copy,
	uninitialized_fill, uninitialized_fill_n): Use __is_trivial
	instead of __is_pod.
	* include/bits/valarray_array.h: Likewise.
	* include/bits/stl_algobase.h (__copy_move_backward_a,
	__copy_move_a): Likewise.
Jason Merrill - June 17, 2010, 2:14 p.m.
On 06/17/2010 04:41 AM, Paolo Carlini wrote:
> Some infrastructure for forthcoming C++0x work + finally got around to
> use __is_trivial instead of the more restrictive __is_pod in many
> places. About the latter in particular, I'm also adding in CC Jason -
> implemented __is_trivial and briefly discussed with him the rather
> straightforward plan of replacing most dispatches in the library based
> on POD-ness to trivial-ness.

Note that I've submitted an NB comment on the FCD suggesting that POD be 
changed from "trivial and standard layout" to "trivially copyable and 
standard layout" to make struct A { const int i; }; POD again.

Jason
Paolo Carlini - June 17, 2010, 2:29 p.m.
On 06/17/2010 04:14 PM, Jason Merrill wrote:
> On 06/17/2010 04:41 AM, Paolo Carlini wrote:
>> Some infrastructure for forthcoming C++0x work + finally got around to
>> use __is_trivial instead of the more restrictive __is_pod in many
>> places. About the latter in particular, I'm also adding in CC Jason -
>> implemented __is_trivial and briefly discussed with him the rather
>> straightforward plan of replacing most dispatches in the library based
>> on POD-ness to trivial-ness.
>
> Note that I've submitted an NB comment on the FCD suggesting that POD
> be changed from "trivial and standard layout" to "trivially copyable
> and standard layout" to make struct A { const int i; }; POD again.
Ok... That issue with POD, good. Thus the idea is resolving it by taking
out from POD-ness the trivial default bit... It seems to me then that,
post that kind of resolution, what we *had* before my patch would be
wrong, because we used to rely on the trivial default constructor. What
we have now, however, seems correct -  maybe could be loosened a bit,
we'll see - but it seems correct, because if I understand correctly,
trivial itself is not going to change, thus still includes the trivial
default constructor bit.

Paolo.

Patch

Index: include/bits/stl_algobase.h
===================================================================
--- include/bits/stl_algobase.h	(revision 160877)
+++ include/bits/stl_algobase.h	(working copy)
@@ -394,7 +394,7 @@ 
       typedef typename iterator_traits<_II>::value_type _ValueTypeI;
       typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
       typedef typename iterator_traits<_II>::iterator_category _Category;
-      const bool __simple = (__is_pod(_ValueTypeI)
+      const bool __simple = (__is_trivial(_ValueTypeI)
 	                     && __is_pointer<_II>::__value
 	                     && __is_pointer<_OI>::__value
 			     && __are_same<_ValueTypeI, _ValueTypeO>::__value);
@@ -589,7 +589,7 @@ 
       typedef typename iterator_traits<_BI1>::value_type _ValueType1;
       typedef typename iterator_traits<_BI2>::value_type _ValueType2;
       typedef typename iterator_traits<_BI1>::iterator_category _Category;
-      const bool __simple = (__is_pod(_ValueType1)
+      const bool __simple = (__is_trivial(_ValueType1)
 	                     && __is_pointer<_BI1>::__value
 	                     && __is_pointer<_BI2>::__value
 			     && __are_same<_ValueType1, _ValueType2>::__value);
Index: include/bits/stl_uninitialized.h
===================================================================
--- include/bits/stl_uninitialized.h	(revision 160877)
+++ include/bits/stl_uninitialized.h	(working copy)
@@ -60,13 +60,13 @@ 
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
-  template<bool>
+  template<bool _TrivialValueTypes>
     struct __uninitialized_copy
     {
       template<typename _InputIterator, typename _ForwardIterator>
         static _ForwardIterator
-        uninitialized_copy(_InputIterator __first, _InputIterator __last,
-			   _ForwardIterator __result)
+        __uninit_copy(_InputIterator __first, _InputIterator __last,
+		      _ForwardIterator __result)
         {
 	  _ForwardIterator __cur = __result;
 	  __try
@@ -88,8 +88,8 @@ 
     {
       template<typename _InputIterator, typename _ForwardIterator>
         static _ForwardIterator
-        uninitialized_copy(_InputIterator __first, _InputIterator __last,
-			   _ForwardIterator __result)
+        __uninit_copy(_InputIterator __first, _InputIterator __last,
+		      _ForwardIterator __result)
         { return std::copy(__first, __last, __result); }
     };
 
@@ -112,19 +112,19 @@ 
       typedef typename iterator_traits<_ForwardIterator>::value_type
 	_ValueType2;
 
-      return std::__uninitialized_copy<(__is_pod(_ValueType1)
-					&& __is_pod(_ValueType2))>::
-	uninitialized_copy(__first, __last, __result);
+      return std::__uninitialized_copy<(__is_trivial(_ValueType1)
+					&& __is_trivial(_ValueType2))>::
+	__uninit_copy(__first, __last, __result);
     }
 
 
-  template<bool>
+  template<bool _TrivialValueType>
     struct __uninitialized_fill
     {
       template<typename _ForwardIterator, typename _Tp>
         static void
-        uninitialized_fill(_ForwardIterator __first,
-			   _ForwardIterator __last, const _Tp& __x)
+        __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
+		      const _Tp& __x)
         {
 	  _ForwardIterator __cur = __first;
 	  __try
@@ -145,8 +145,8 @@ 
     {
       template<typename _ForwardIterator, typename _Tp>
         static void
-        uninitialized_fill(_ForwardIterator __first,
-			   _ForwardIterator __last, const _Tp& __x)
+        __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
+		      const _Tp& __x)
         { std::fill(__first, __last, __x); }
     };
 
@@ -167,18 +167,18 @@ 
       typedef typename iterator_traits<_ForwardIterator>::value_type
 	_ValueType;
 
-      std::__uninitialized_fill<__is_pod(_ValueType)>::
-	uninitialized_fill(__first, __last, __x);
+      std::__uninitialized_fill<__is_trivial(_ValueType)>::
+	__uninit_fill(__first, __last, __x);
     }
 
 
-  template<bool>
+  template<bool _TrivialValueType>
     struct __uninitialized_fill_n
     {
       template<typename _ForwardIterator, typename _Size, typename _Tp>
         static void
-        uninitialized_fill_n(_ForwardIterator __first, _Size __n,
-			     const _Tp& __x)
+        __uninit_fill_n(_ForwardIterator __first, _Size __n,
+			const _Tp& __x)
         {
 	  _ForwardIterator __cur = __first;
 	  __try
@@ -199,8 +199,8 @@ 
     {
       template<typename _ForwardIterator, typename _Size, typename _Tp>
         static void
-        uninitialized_fill_n(_ForwardIterator __first, _Size __n,
-			     const _Tp& __x)
+        __uninit_fill_n(_ForwardIterator __first, _Size __n,
+			const _Tp& __x)
         { std::fill_n(__first, __n, __x); }
     };
 
@@ -220,8 +220,8 @@ 
       typedef typename iterator_traits<_ForwardIterator>::value_type
 	_ValueType;
 
-      std::__uninitialized_fill_n<__is_pod(_ValueType)>::
-	uninitialized_fill_n(__first, __n, __x);
+      std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
+	__uninit_fill_n(__first, __n, __x);
     }
 
   // Extensions: versions of uninitialized_copy, uninitialized_fill,
@@ -427,6 +427,166 @@ 
     }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
+  // Extensions: __uninitialized_default, __uninitialized_default_n,
+  // __uninitialized_default_a, __uninitialized_default_n_a.
+
+  template<bool _TrivialValueType>
+    struct __uninitialized_default_1
+    {
+      template<typename _ForwardIterator>
+        static void
+        __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
+        {
+	  _ForwardIterator __cur = __first;
+	  __try
+	    {
+	      for (; __cur != __last; ++__cur)
+		std::_Construct(std::__addressof(*__cur));
+	    }
+	  __catch(...)
+	    {
+	      std::_Destroy(__first, __cur);
+	      __throw_exception_again;
+	    }
+	}
+    };
+
+  template<>
+    struct __uninitialized_default_1<true>
+    {
+      template<typename _ForwardIterator>
+        static void
+        __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
+        {
+	  typedef typename iterator_traits<_ForwardIterator>::value_type
+	    _ValueType;
+
+	  std::fill(__first, __last, _ValueType());
+	}
+    };
+
+  template<bool _TrivialValueType>
+    struct __uninitialized_default_n_1
+    {
+      template<typename _ForwardIterator, typename _Size>
+        static void
+        __uninit_default_n(_ForwardIterator __first, _Size __n)
+        {
+	  _ForwardIterator __cur = __first;
+	  __try
+	    {
+	      for (; __n > 0; --__n, ++__cur)
+		std::_Construct(std::__addressof(*__cur));
+	    }
+	  __catch(...)
+	    {
+	      std::_Destroy(__first, __cur);
+	      __throw_exception_again;
+	    }
+	}
+    };
+
+  template<>
+    struct __uninitialized_default_n_1<true>
+    {
+      template<typename _ForwardIterator, typename _Size>
+        static void
+        __uninit_default_n(_ForwardIterator __first, _Size __n)
+        {
+	  typedef typename iterator_traits<_ForwardIterator>::value_type
+	    _ValueType;
+
+	  std::fill_n(__first, __n, _ValueType());
+	}
+    };
+
+  // __uninitialized_default
+  // Fills [first, last) with std::distance(first, last) default
+  // constructed value_types(s).
+  template<typename _ForwardIterator>
+    inline void
+    __uninitialized_default(_ForwardIterator __first,
+			    _ForwardIterator __last)
+    {
+      typedef typename iterator_traits<_ForwardIterator>::value_type
+	_ValueType;
+
+      std::__uninitialized_default_1<__is_trivial(_ValueType)>::
+	__uninit_default(__first, __last);
+    }
+
+  // __uninitialized_default_n
+  // Fills [first, first + n) with n default constructed value_type(s).
+  template<typename _ForwardIterator, typename _Size>
+    inline void
+    __uninitialized_default_n(_ForwardIterator __first, _Size __n)
+    {
+      typedef typename iterator_traits<_ForwardIterator>::value_type
+	_ValueType;
+
+      std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
+	__uninit_default_n(__first, __n);
+    }
+
+
+  // __uninitialized_default_a
+  // Fills [first, last) with std::distance(first, last) default
+  // constructed value_types(s), constructed with the allocator alloc.
+  template<typename _ForwardIterator, typename _Allocator>
+    void
+    __uninitialized_default_a(_ForwardIterator __first,
+			      _ForwardIterator __last,
+			      _Allocator& __alloc)
+    {
+      _ForwardIterator __cur = __first;
+      __try
+	{
+	  for (; __cur != __last; ++__cur)
+	    __alloc.construct(std::__addressof(*__cur));
+	}
+      __catch(...)
+	{
+	  std::_Destroy(__first, __cur, __alloc);
+	  __throw_exception_again;
+	}
+    }
+
+  template<typename _ForwardIterator, typename _Tp>
+    inline void
+    __uninitialized_default_a(_ForwardIterator __first,
+			      _ForwardIterator __last,
+			      allocator<_Tp>&)
+    { std::__uninitialized_default(__first, __last); }
+
+
+  // __uninitialized_default_n_a
+  // Fills [first, first + n) with n default constructed value_types(s),
+  // constructed with the allocator alloc.
+  template<typename _ForwardIterator, typename _Size, typename _Allocator>
+    void
+    __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
+				_Allocator& __alloc)
+    {
+      _ForwardIterator __cur = __first;
+      __try
+	{
+	  for (; __n > 0; --__n, ++__cur)
+	    __alloc.construct(std::__addressof(*__cur));
+	}
+      __catch(...)
+	{
+	  std::_Destroy(__first, __cur, __alloc);
+	  __throw_exception_again;
+	}
+    }
+
+  template<typename _ForwardIterator, typename _Size, typename _Tp>
+    inline void
+    __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
+				allocator<_Tp>&)
+    { std::__uninitialized_default_n(__first, __n); }
+
+
   template<typename _InputIterator, typename _Size,
 	   typename _ForwardIterator>
     _ForwardIterator
Index: include/bits/valarray_array.h
===================================================================
--- include/bits/valarray_array.h	(revision 160877)
+++ include/bits/valarray_array.h	(working copy)
@@ -1,7 +1,7 @@ 
 // The template and inlines for the -*- C++ -*- internal _Array helper class.
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009
+// 2006, 2007, 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -127,7 +127,7 @@ 
     inline void
     __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t)
     {
-      _Array_init_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __t);
+      _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t);
     }
 
   //
@@ -160,7 +160,7 @@ 
     __valarray_copy_construct(const _Tp* __b, const _Tp* __e,
 			      _Tp* __restrict__ __o)
     {
-      _Array_copy_ctor<_Tp, __is_pod(_Tp)>::_S_do_it(__b, __e, __o);
+      _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o);
     }
 
   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
@@ -169,7 +169,7 @@ 
     __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
 			       size_t __s, _Tp* __restrict__ __o)
     {
-      if (__is_pod(_Tp))
+      if (__is_trivial(_Tp))
 	while (__n--)
 	  {
 	    *__o++ = *__a;
@@ -190,7 +190,7 @@ 
 			       const size_t* __restrict__ __i,
 			       _Tp* __restrict__ __o, size_t __n)
     {
-      if (__is_pod(_Tp))
+      if (__is_trivial(_Tp))
 	while (__n--)
 	  *__o++ = __a[*__i++];
       else
@@ -203,7 +203,7 @@ 
     inline void
     __valarray_destroy_elements(_Tp* __b, _Tp* __e)
     {
-      if (!__is_pod(_Tp))
+      if (!__is_trivial(_Tp))
 	while (__b != __e)
 	  {
 	    __b->~_Tp();
@@ -267,7 +267,7 @@ 
     __valarray_copy(const _Tp* __restrict__ __a, size_t __n,
 		    _Tp* __restrict__ __b)
     {
-      _Array_copier<_Tp, __is_pod(_Tp)>::_S_do_it(__a, __n, __b);
+      _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b);
     }
 
   // Copy strided array __a[<__n : __s>] in plain __b[<__n>]