xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/tr1/array (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
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