1*404b540aSrobert// class template array -*- C++ -*- 2*404b540aSrobert 3*404b540aSrobert// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. 4*404b540aSrobert// 5*404b540aSrobert// This file is part of the GNU ISO C++ Library. This library is free 6*404b540aSrobert// software; you can redistribute it and/or modify it under the 7*404b540aSrobert// terms of the GNU General Public License as published by the 8*404b540aSrobert// Free Software Foundation; either version 2, or (at your option) 9*404b540aSrobert// any later version. 10*404b540aSrobert 11*404b540aSrobert// This library is distributed in the hope that it will be useful, 12*404b540aSrobert// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*404b540aSrobert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*404b540aSrobert// GNU General Public License for more details. 15*404b540aSrobert 16*404b540aSrobert// You should have received a copy of the GNU General Public License along 17*404b540aSrobert// with this library; see the file COPYING. If not, write to the Free 18*404b540aSrobert// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19*404b540aSrobert// USA. 20*404b540aSrobert 21*404b540aSrobert// As a special exception, you may use this file as part of a free software 22*404b540aSrobert// library without restriction. Specifically, if other files instantiate 23*404b540aSrobert// templates or use macros or inline functions from this file, or you compile 24*404b540aSrobert// this file and link it with other files to produce an executable, this 25*404b540aSrobert// file does not by itself cause the resulting executable to be covered by 26*404b540aSrobert// the GNU General Public License. This exception does not however 27*404b540aSrobert// invalidate any other reasons why the executable file might be covered by 28*404b540aSrobert// the GNU General Public License. 29*404b540aSrobert 30*404b540aSrobert/** @file tr1/array 31*404b540aSrobert * This is a TR1 C++ Library header. 32*404b540aSrobert */ 33*404b540aSrobert 34*404b540aSrobert#ifndef _TR1_ARRAY 35*404b540aSrobert#define _TR1_ARRAY 1 36*404b540aSrobert 37*404b540aSrobert#include <new> 38*404b540aSrobert#include <iterator> 39*404b540aSrobert#include <algorithm> 40*404b540aSrobert#include <cstddef> 41*404b540aSrobert#include <bits/functexcept.h> 42*404b540aSrobert#include <ext/type_traits.h> 43*404b540aSrobert 44*404b540aSrobert//namespace std::tr1 45*404b540aSrobertnamespace std 46*404b540aSrobert{ 47*404b540aSrobert_GLIBCXX_BEGIN_NAMESPACE(tr1) 48*404b540aSrobert 49*404b540aSrobert /// @brief struct array [6.2.2]. 50*404b540aSrobert /// NB: Requires complete type _Tp. 51*404b540aSrobert template<typename _Tp, std::size_t _Nm> 52*404b540aSrobert struct array 53*404b540aSrobert { 54*404b540aSrobert typedef _Tp value_type; 55*404b540aSrobert typedef value_type& reference; 56*404b540aSrobert typedef const value_type& const_reference; 57*404b540aSrobert typedef value_type* iterator; 58*404b540aSrobert typedef const value_type* const_iterator; 59*404b540aSrobert typedef std::size_t size_type; 60*404b540aSrobert typedef std::ptrdiff_t difference_type; 61*404b540aSrobert typedef std::reverse_iterator<iterator> reverse_iterator; 62*404b540aSrobert typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 63*404b540aSrobert 64*404b540aSrobert // Support for zero-sized arrays mandatory. 65*404b540aSrobert value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__)); 66*404b540aSrobert 67*404b540aSrobert // No explicit construct/copy/destroy for aggregate type. 68*404b540aSrobert 69*404b540aSrobert void 70*404b540aSrobert assign(const value_type& __u) 71*404b540aSrobert { std::fill_n(begin(), size(), __u); } 72*404b540aSrobert 73*404b540aSrobert void 74*404b540aSrobert swap(array& __other) 75*404b540aSrobert { std::swap_ranges(begin(), end(), __other.begin()); } 76*404b540aSrobert 77*404b540aSrobert // Iterators. 78*404b540aSrobert iterator 79*404b540aSrobert begin() 80*404b540aSrobert { return iterator(&_M_instance[0]); } 81*404b540aSrobert 82*404b540aSrobert const_iterator 83*404b540aSrobert begin() const 84*404b540aSrobert { return const_iterator(&_M_instance[0]); } 85*404b540aSrobert 86*404b540aSrobert iterator 87*404b540aSrobert end() 88*404b540aSrobert { return iterator(&_M_instance[_Nm]); } 89*404b540aSrobert 90*404b540aSrobert const_iterator 91*404b540aSrobert end() const 92*404b540aSrobert { return const_iterator(&_M_instance[_Nm]); } 93*404b540aSrobert 94*404b540aSrobert reverse_iterator 95*404b540aSrobert rbegin() 96*404b540aSrobert { return reverse_iterator(end()); } 97*404b540aSrobert 98*404b540aSrobert const_reverse_iterator 99*404b540aSrobert rbegin() const 100*404b540aSrobert { return const_reverse_iterator(end()); } 101*404b540aSrobert 102*404b540aSrobert reverse_iterator 103*404b540aSrobert rend() 104*404b540aSrobert { return reverse_iterator(begin()); } 105*404b540aSrobert 106*404b540aSrobert const_reverse_iterator 107*404b540aSrobert rend() const 108*404b540aSrobert { return const_reverse_iterator(begin()); } 109*404b540aSrobert 110*404b540aSrobert // Capacity. 111*404b540aSrobert size_type 112*404b540aSrobert size() const { return _Nm; } 113*404b540aSrobert 114*404b540aSrobert size_type 115*404b540aSrobert max_size() const { return _Nm; } 116*404b540aSrobert 117*404b540aSrobert bool 118*404b540aSrobert empty() const { return size() == 0; } 119*404b540aSrobert 120*404b540aSrobert // Element access. 121*404b540aSrobert reference 122*404b540aSrobert operator[](size_type __n) 123*404b540aSrobert { return _M_instance[__n]; } 124*404b540aSrobert 125*404b540aSrobert const_reference 126*404b540aSrobert operator[](size_type __n) const 127*404b540aSrobert { return _M_instance[__n]; } 128*404b540aSrobert 129*404b540aSrobert reference 130*404b540aSrobert at(size_type __n) 131*404b540aSrobert { 132*404b540aSrobert _M_check<_Nm>(__n); 133*404b540aSrobert return _M_instance[__n]; 134*404b540aSrobert } 135*404b540aSrobert 136*404b540aSrobert const_reference 137*404b540aSrobert at(size_type __n) const 138*404b540aSrobert { 139*404b540aSrobert _M_check<_Nm>(__n); 140*404b540aSrobert return _M_instance[__n]; 141*404b540aSrobert } 142*404b540aSrobert 143*404b540aSrobert reference 144*404b540aSrobert front() 145*404b540aSrobert { return *begin(); } 146*404b540aSrobert 147*404b540aSrobert const_reference 148*404b540aSrobert front() const 149*404b540aSrobert { return *begin(); } 150*404b540aSrobert 151*404b540aSrobert reference 152*404b540aSrobert back() 153*404b540aSrobert { return _Nm ? *(end() - 1) : *end(); } 154*404b540aSrobert 155*404b540aSrobert const_reference 156*404b540aSrobert back() const 157*404b540aSrobert { return _Nm ? *(end() - 1) : *end(); } 158*404b540aSrobert 159*404b540aSrobert _Tp* 160*404b540aSrobert data() 161*404b540aSrobert { return &_M_instance[0]; } 162*404b540aSrobert 163*404b540aSrobert const _Tp* 164*404b540aSrobert data() const 165*404b540aSrobert { return &_M_instance[0]; } 166*404b540aSrobert 167*404b540aSrobert private: 168*404b540aSrobert template<std::size_t _Mm> 169*404b540aSrobert typename __gnu_cxx::__enable_if<_Mm, void>::__type 170*404b540aSrobert _M_check(size_type __n) const 171*404b540aSrobert { 172*404b540aSrobert if (__builtin_expect(__n >= _Mm, false)) 173*404b540aSrobert std::__throw_out_of_range(__N("array::_M_check")); 174*404b540aSrobert } 175*404b540aSrobert 176*404b540aSrobert // Avoid "unsigned comparison with zero" warnings. 177*404b540aSrobert template<std::size_t _Mm> 178*404b540aSrobert typename __gnu_cxx::__enable_if<!_Mm, void>::__type 179*404b540aSrobert _M_check(size_type) const 180*404b540aSrobert { std::__throw_out_of_range(__N("array::_M_check")); } 181*404b540aSrobert }; 182*404b540aSrobert 183*404b540aSrobert // Array comparisons. 184*404b540aSrobert template<typename _Tp, std::size_t _Nm> 185*404b540aSrobert inline bool 186*404b540aSrobert operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 187*404b540aSrobert { return std::equal(__one.begin(), __one.end(), __two.begin()); } 188*404b540aSrobert 189*404b540aSrobert template<typename _Tp, std::size_t _Nm> 190*404b540aSrobert inline bool 191*404b540aSrobert operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 192*404b540aSrobert { return !(__one == __two); } 193*404b540aSrobert 194*404b540aSrobert template<typename _Tp, std::size_t _Nm> 195*404b540aSrobert inline bool 196*404b540aSrobert operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 197*404b540aSrobert { 198*404b540aSrobert return std::lexicographical_compare(__a.begin(), __a.end(), 199*404b540aSrobert __b.begin(), __b.end()); 200*404b540aSrobert } 201*404b540aSrobert 202*404b540aSrobert template<typename _Tp, std::size_t _Nm> 203*404b540aSrobert inline bool 204*404b540aSrobert operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 205*404b540aSrobert { return __two < __one; } 206*404b540aSrobert 207*404b540aSrobert template<typename _Tp, std::size_t _Nm> 208*404b540aSrobert inline bool 209*404b540aSrobert operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 210*404b540aSrobert { return !(__one > __two); } 211*404b540aSrobert 212*404b540aSrobert template<typename _Tp, std::size_t _Nm> 213*404b540aSrobert inline bool 214*404b540aSrobert operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 215*404b540aSrobert { return !(__one < __two); } 216*404b540aSrobert 217*404b540aSrobert // Specialized algorithms [6.2.2.2]. 218*404b540aSrobert template<typename _Tp, std::size_t _Nm> 219*404b540aSrobert inline void 220*404b540aSrobert swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 221*404b540aSrobert { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); } 222*404b540aSrobert 223*404b540aSrobert // Tuple interface to class template array [6.2.2.5]. 224*404b540aSrobert template<typename _Tp> class tuple_size; 225*404b540aSrobert template<int _Int, typename _Tp> class tuple_element; 226*404b540aSrobert 227*404b540aSrobert template<typename _Tp, std::size_t _Nm> 228*404b540aSrobert struct tuple_size<array<_Tp, _Nm> > 229*404b540aSrobert { static const int value = _Nm; }; 230*404b540aSrobert 231*404b540aSrobert template<typename _Tp, std::size_t _Nm> 232*404b540aSrobert const int tuple_size<array<_Tp, _Nm> >::value; 233*404b540aSrobert 234*404b540aSrobert template<int _Int, typename _Tp, std::size_t _Nm> 235*404b540aSrobert struct tuple_element<_Int, array<_Tp, _Nm> > 236*404b540aSrobert { typedef _Tp type; }; 237*404b540aSrobert 238*404b540aSrobert template<int _Int, typename _Tp, std::size_t _Nm> 239*404b540aSrobert inline _Tp& 240*404b540aSrobert get(array<_Tp, _Nm>& __arr) 241*404b540aSrobert { return __arr[_Int]; } 242*404b540aSrobert 243*404b540aSrobert template<int _Int, typename _Tp, std::size_t _Nm> 244*404b540aSrobert inline const _Tp& 245*404b540aSrobert get(const array<_Tp, _Nm>& __arr) 246*404b540aSrobert { return __arr[_Int]; } 247*404b540aSrobert 248*404b540aSrobert_GLIBCXX_END_NAMESPACE 249*404b540aSrobert} 250*404b540aSrobert 251*404b540aSrobert#endif 252