PR libstdc++/28277 (partial: valarray bits)
authorPaolo Carlini <pcarlini@suse.de>
Sun, 16 Jul 2006 15:38:59 +0000 (15:38 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 16 Jul 2006 15:38:59 +0000 (15:38 +0000)
2006-07-16  Paolo Carlini  <pcarlini@suse.de>

PR libstdc++/28277 (partial: valarray bits)
* include/std/std_valarray.h (valarray<>::shift(int),
valarray<>::cshift(int)): Avoid __builtin_alloca with no limit,
do the work in place.
* testsuite/26_numerics/valarray/28277.cc: New.

From-SVN: r115501

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/std_valarray.h
libstdc++-v3/testsuite/26_numerics/valarray/28277.cc [new file with mode: 0644]

index dd32bf9..541c6c0 100644 (file)
@@ -1,3 +1,11 @@
+2006-07-16  Paolo Carlini  <pcarlini@suse.de>
+
+       PR libstdc++/28277 (partial: valarray bits)
+       * include/std/std_valarray.h (valarray<>::shift(int),
+       valarray<>::cshift(int)): Avoid __builtin_alloca with no limit,
+       do the work in place.
+       * testsuite/26_numerics/valarray/28277.cc: New.
+
 2006-07-15  Paolo Carlini  <pcarlini@suse.de>
 
        PR libstdc++/28277 (partial: ostream bits 1)
index ada7aea..47b00a5 100644 (file)
@@ -778,63 +778,78 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       return std::__valarray_sum(_M_data, _M_data + _M_size);
     }
 
-  template <class _Tp>
+  template<class _Tp>
      inline valarray<_Tp>
      valarray<_Tp>::shift(int __n) const
      {
-       _Tp* const __a = static_cast<_Tp*>
-         (__builtin_alloca(sizeof(_Tp) * _M_size));
+       valarray<_Tp> __ret;
+       _Tp* __restrict__ __tmp_M_data =
+        std::__valarray_get_storage<_Tp>(_M_size);
+
        if (__n == 0)                          // no shift
-         std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
+         std::__valarray_copy_construct(_M_data, _M_data + _M_size,
+                                       __tmp_M_data);
        else if (__n > 0)         // __n > 0: shift left
          {                 
            if (size_t(__n) > _M_size)
-             std::__valarray_default_construct(__a, __a + __n);
+             std::__valarray_default_construct(__tmp_M_data,
+                                              __tmp_M_data + __n);
            else
              {
                std::__valarray_copy_construct(_M_data + __n,
-                                             _M_data + _M_size, __a);
-               std::__valarray_default_construct(__a + _M_size -__n,
-                                                __a + _M_size);
+                                             _M_data + _M_size,
+                                             __tmp_M_data);
+               std::__valarray_default_construct(__tmp_M_data + _M_size - __n,
+                                                __tmp_M_data + _M_size);
              }
          }
        else                        // __n < 0: shift right
          {                          
-           std::__valarray_copy_construct (_M_data, _M_data + _M_size + __n,
-                                          __a - __n);
-           std::__valarray_default_construct(__a, __a - __n);
+           std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n,
+                                         __tmp_M_data - __n);
+           std::__valarray_default_construct(__tmp_M_data,
+                                            __tmp_M_data - __n);
          }
-       return valarray<_Tp>(__a, _M_size);
+
+       __ret._M_size = _M_size;
+       __ret._M_data = __tmp_M_data;
+       return __ret;
      }
 
-  template <class _Tp>
+  template<class _Tp>
      inline valarray<_Tp>
-     valarray<_Tp>::cshift (int __n) const
+     valarray<_Tp>::cshift(int __n) const
      {
-       _Tp* const __a = static_cast<_Tp*>
-         (__builtin_alloca (sizeof(_Tp) * _M_size));
+       valarray<_Tp> __ret;
+       _Tp* __restrict__ __tmp_M_data =
+        std::__valarray_get_storage<_Tp>(_M_size);
+
        if (__n == 0)               // no cshift
-         std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a);
+         std::__valarray_copy_construct(_M_data, _M_data + _M_size,
+                                       __tmp_M_data);
        else if (__n > 0)           // cshift left
          {               
            std::__valarray_copy_construct(_M_data, _M_data + __n,
-                                         __a + _M_size - __n);
+                                         __tmp_M_data + _M_size - __n);
            std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size,
-                                         __a);
+                                         __tmp_M_data);
          }
        else                        // cshift right
          {                       
            std::__valarray_copy_construct
-             (_M_data + _M_size + __n, _M_data + _M_size, __a);
+             (_M_data + _M_size + __n, _M_data + _M_size, __tmp_M_data);
            std::__valarray_copy_construct
-             (_M_data, _M_data + _M_size+__n, __a - __n);
+             (_M_data, _M_data + _M_size + __n, __tmp_M_data - __n);
          }
-       return valarray<_Tp>(__a, _M_size);
+
+       __ret._M_size = _M_size;
+       __ret._M_data = __tmp_M_data;
+       return __ret;
      }
 
-  template <class _Tp>
+  template<class _Tp>
     inline void
-    valarray<_Tp>::resize (size_t __n, _Tp __c)
+    valarray<_Tp>::resize(size_t __n, _Tp __c)
     {
       // This complication is so to make valarray<valarray<T> > work
       // even though it is not required by the standard.  Nobody should
diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/28277.cc b/libstdc++-v3/testsuite/26_numerics/valarray/28277.cc
new file mode 100644 (file)
index 0000000..52f4c71
--- /dev/null
@@ -0,0 +1,44 @@
+// 2006-07-15  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <valarray>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  const std::valarray<int> v1(1, 5000000);
+
+  const std::valarray<int> v2 = v1.shift(1);
+  VERIFY( v2.size() == v1.size() );
+  VERIFY( v2[v1.size() - 1] == 0 );
+
+  const std::valarray<int> v3 = v2.cshift(-1);
+  VERIFY( v3.size() == v2.size() );
+  VERIFY( v3[0] == 0 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}