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