From e7457c3eacf65a90b11d084434c20cd58ebbdb27 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sat, 28 Oct 2006 22:02:44 +0000 Subject: [PATCH] array (array<>::_M_at): New. 2006-10-28 Paolo Carlini * 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 --- libstdc++-v3/ChangeLog | 14 ++++ libstdc++-v3/include/ext/array_allocator.h | 2 +- libstdc++-v3/include/tr1/array | 74 +++++++++++++------ .../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 5dacf66aafb..cb13016879d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2006-10-28 Paolo Carlini + + * 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 * 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 08661864c2a..0bbd97a2d09 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 > + template > class array_allocator : public array_allocator_base<_Tp> { public: diff --git a/libstdc++-v3/include/tr1/array b/libstdc++-v3/include/tr1/array index 9332efeb4ab..43898740a1c 100644 --- a/libstdc++-v3/include/tr1/array +++ b/libstdc++-v3/include/tr1/array @@ -39,6 +39,7 @@ #include #include #include +#include //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 + template struct array { typedef _Tp value_type; @@ -60,9 +61,6 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) typedef std::reverse_iterator reverse_iterator; typedef std::reverse_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 + 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 + typename __gnu_cxx::__enable_if::__type + _M_at(size_type) + { + std::__throw_out_of_range("array::_M_at"); + return _M_instance[0]; + } + + template + 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 + typename __gnu_cxx::__enable_if::__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 class tuple_size; template class tuple_element; - + template struct tuple_size > { static const int value = _Nm; }; - + template 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 d288d20569a..10796dccfb8 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 // -// 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 #include +#include 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; } -