diff options
author | Paolo Carlini <pcarlini@suse.de> | 2006-10-28 22:02:44 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2006-10-28 22:02:44 +0000 |
commit | e7457c3eacf65a90b11d084434c20cd58ebbdb27 (patch) | |
tree | 3206ab3ee6fca21ddeddab4ec985b4751ca13866 | |
parent | f1827a8c6996a8fc972db78323775b19f800a82d (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/array_allocator.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1/array | 74 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/tr1/6_containers/array/element_access/at_out_of_range.cc | 8 |
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; } - |