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 /libstdc++-v3/include/tr1 | |
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
Diffstat (limited to 'libstdc++-v3/include/tr1')
-rw-r--r-- | libstdc++-v3/include/tr1/array | 74 |
1 files changed, 50 insertions, 24 deletions
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; }; |