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