aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2006-10-28 22:02:44 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2006-10-28 22:02:44 +0000
commite7457c3eacf65a90b11d084434c20cd58ebbdb27 (patch)
tree3206ab3ee6fca21ddeddab4ec985b4751ca13866
parentf1827a8c6996a8fc972db78323775b19f800a82d (diff)
downloadgcc-e7457c3eacf65a90b11d084434c20cd58ebbdb27.zip
gcc-e7457c3eacf65a90b11d084434c20cd58ebbdb27.tar.gz
gcc-e7457c3eacf65a90b11d084434c20cd58ebbdb27.tar.bz2
array (array<>::_M_at): New.
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. From-SVN: r118114
-rw-r--r--libstdc++-v3/ChangeLog14
-rw-r--r--libstdc++-v3/include/ext/array_allocator.h2
-rw-r--r--libstdc++-v3/include/tr1/array74
-rw-r--r--libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc8
4 files changed, 70 insertions, 28 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 5dacf66..cb13016 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+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.
+
2006-10-17 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (money_get<>::__do_get(iter_type,
diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h
index 0866186..0bbd97a 100644
--- a/libstdc++-v3/include/ext/array_allocator.h
+++ b/libstdc++-v3/include/ext/array_allocator.h
@@ -87,7 +87,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
* @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:
diff --git a/libstdc++-v3/include/tr1/array b/libstdc++-v3/include/tr1/array
index 9332efe..4389874 100644
--- a/libstdc++-v3/include/tr1/array
+++ b/libstdc++-v3/include/tr1/array
@@ -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 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
/// @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 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
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,29 +118,21 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
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
- at(size_type __n) const
- {
- if (__builtin_expect(__n > _Nm, false))
- std::__throw_out_of_range("array::at");
- return _M_instance[__n];
- }
-
- reference
+ reference
at(size_type __n)
- {
- if (__builtin_expect(__n > _Nm, false))
- std::__throw_out_of_range("array::at");
- return _M_instance[__n];
- }
+ { return _M_at<_Nm>(__n); }
+
+ const_reference
+ at(size_type __n) const
+ { return _M_at<_Nm>(__n); }
reference
front()
@@ -154,11 +144,11 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
// 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; };
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc b/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc
index d288d20..10796dc 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc
@@ -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 @@ test01()
try
{
a.at(len);
+ VERIFY( false );
}
catch(std::out_of_range& obj)
{
// Expected.
+ VERIFY( true );
}
catch(...)
{
// Failed.
- throw;
+ VERIFY( false );
}
}
@@ -51,4 +54,3 @@ int main()
test01();
return 0;
}
-