This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Fix a couple of tr1/array issues


Hi,

tested x86-linux, committed mainline, 4_2, 4_1.

Paolo.

////////////////
2006-10-28  Paolo Carlini  <pcarlini@suse.de>
	
	* include/tr1/array (array<>::_M_at): New.
	(array<>::at): Fix off-by-one bug, use the above.
	* testsuite/tr1/6_containers/array/element_access/
	at_out_of_range.cc: Adjust.

	* include/tr1/array (class array<>): Remove non-conforming default
	for the second parameter.
	* include/ext/array_allocator.h: Adjust.

	* include/tr1/array (array<>::front, array<>::back): Do not return
	a reference to memory not belonging to the array when _Nm == 0.
Index: include/ext/array_allocator.h
===================================================================
--- include/ext/array_allocator.h	(revision 118104)
+++ include/ext/array_allocator.h	(working copy)
@@ -87,7 +87,7 @@
    *  @brief  An allocator that uses previously allocated memory.
    *  This memory can be externally, globally, or otherwise allocated.
    */
-  template<typename _Tp, typename _Array = std::tr1::array<_Tp> >
+  template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> >
     class array_allocator : public array_allocator_base<_Tp>
     {
     public:
Index: include/tr1/array
===================================================================
--- include/tr1/array	(revision 118104)
+++ include/tr1/array	(working copy)
@@ -39,6 +39,7 @@
 #include <algorithm>
 #include <cstddef>
 #include <bits/functexcept.h>
+#include <ext/type_traits.h>
 
 //namespace std::tr1
 namespace std
@@ -47,7 +48,7 @@
 
   /// @brief  struct array [6.2.2].
   /// NB: Requires complete type _Tp.
-  template<typename _Tp, std::size_t _Nm = 1>
+  template<typename _Tp, std::size_t _Nm>
     struct array
     {
       typedef _Tp 	    			      value_type;
@@ -60,9 +61,6 @@
       typedef std::reverse_iterator<iterator>	      reverse_iterator;
       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
 
-      // Compile time constant without other dependencies.
-      enum { _S_index = _Nm };
-
       // Support for zero-sized arrays mandatory.
       value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__));
 
@@ -120,31 +118,23 @@
       empty() const { return size() == 0; }
 
       // Element access.
-      reference 
+      reference
       operator[](size_type __n)
       { return _M_instance[__n]; }
 
-      const_reference 
+      const_reference
       operator[](size_type __n) const
       { return _M_instance[__n]; }
 
-      const_reference 
+      reference
+      at(size_type __n)
+      { return _M_at<_Nm>(__n); }
+
+      const_reference
       at(size_type __n) const
-      { 
-	if (__builtin_expect(__n > _Nm, false))
-	  std::__throw_out_of_range("array::at");
-	return _M_instance[__n]; 
-      }
+      { return _M_at<_Nm>(__n); }
 
       reference 
-      at(size_type __n)
-      { 
-	if (__builtin_expect(__n > _Nm, false))
-	  std::__throw_out_of_range("array::at");
-	return _M_instance[__n]; 
-      }
-
-      reference 
       front()
       { return *begin(); }
 
@@ -154,11 +144,11 @@
 
       reference 
       back()
-      { return *(end() - 1); }
+      { return _Nm ? *(end() - 1) : *end(); }
 
       const_reference 
       back() const
-      { return *(end() - 1); }
+      { return _Nm ? *(end() - 1) : *end(); }
 
       _Tp* 
       data()
@@ -167,6 +157,42 @@
       const _Tp* 
       data() const
       { return &_M_instance[0]; }
+
+    private:
+      template<std::size_t _Mm>
+        typename __gnu_cxx::__enable_if<_Mm, reference>::__type
+        _M_at(size_type __n)
+        {
+	  if (__builtin_expect(__n >= _Mm, false))
+	    std::__throw_out_of_range("array::_M_at");
+	  return _M_instance[__n];
+	}
+
+      // Avoid "unsigned comparison with zero" warnings.
+      template<std::size_t _Mm>
+        typename __gnu_cxx::__enable_if<!_Mm, reference>::__type
+        _M_at(size_type)
+        {
+	  std::__throw_out_of_range("array::_M_at");
+	  return _M_instance[0];
+	}
+
+      template<std::size_t _Mm>
+        typename __gnu_cxx::__enable_if<_Mm, const_reference>::__type
+        _M_at(size_type __n) const
+        {
+	  if (__builtin_expect(__n >= _Mm, false))
+	    std::__throw_out_of_range("array::_M_at");
+	  return _M_instance[__n];
+	}
+
+      template<std::size_t _Mm>
+        typename __gnu_cxx::__enable_if<!_Mm, const_reference>::__type
+        _M_at(size_type) const
+        {
+	  std::__throw_out_of_range("array::_M_at");
+	  return _M_instance[0];
+	}     
     };
 
   // Array comparisons.
@@ -212,11 +238,11 @@
   // Tuple interface to class template array [6.2.2.5].
   template<typename _Tp> class tuple_size;
   template<int _Int, typename _Tp> class tuple_element;
-  
+
   template<typename _Tp, std::size_t _Nm>
     struct tuple_size<array<_Tp, _Nm> >
     { static const int value = _Nm; };
- 
+
   template<int _Int, typename _Tp, std::size_t _Nm>
     struct tuple_element<_Int, array<_Tp, _Nm> >
     { typedef _Tp type; };
Index: testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc
===================================================================
--- testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc	(revision 118104)
+++ testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc	(working copy)
@@ -1,6 +1,6 @@
 // 2004-10-20  Benjamin Kosnik  <bkoz@redhat.com>
 //
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 //
 // 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
@@ -22,6 +22,7 @@
 
 #include <tr1/array>
 #include <stdexcept>
+#include <testsuite_hooks.h>
 
 void
 test01() 
@@ -34,15 +35,17 @@
   try
     {
       a.at(len);
+      VERIFY( false );
     }
   catch(std::out_of_range& obj)
     {
       // Expected.
+      VERIFY( true );
     }
   catch(...)
     {
       // Failed.
-      throw;
+      VERIFY( false );
     }
 }
 
@@ -51,4 +54,3 @@
   test01();
   return 0;
 }
-

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]