1169691Skan// class template array -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan/** @file tr1/array
31169691Skan *  This is a TR1 C++ Library header. 
32169691Skan */
33169691Skan
34169691Skan#ifndef _TR1_ARRAY
35169691Skan#define _TR1_ARRAY 1
36169691Skan
37169691Skan#include <new>
38169691Skan#include <iterator>
39169691Skan#include <algorithm>
40169691Skan#include <cstddef>
41169691Skan#include <bits/functexcept.h>
42169691Skan#include <ext/type_traits.h>
43169691Skan
44169691Skan//namespace std::tr1
45169691Skannamespace std
46169691Skan{
47169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1)
48169691Skan
49169691Skan  /// @brief  struct array [6.2.2].
50169691Skan  /// NB: Requires complete type _Tp.
51169691Skan  template<typename _Tp, std::size_t _Nm>
52169691Skan    struct array
53169691Skan    {
54169691Skan      typedef _Tp 	    			      value_type;
55169691Skan      typedef value_type&                   	      reference;
56169691Skan      typedef const value_type&             	      const_reference;
57169691Skan      typedef value_type*          		      iterator;
58169691Skan      typedef const value_type*			      const_iterator;
59169691Skan      typedef std::size_t                    	      size_type;
60169691Skan      typedef std::ptrdiff_t                   	      difference_type;
61169691Skan      typedef std::reverse_iterator<iterator>	      reverse_iterator;
62169691Skan      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
63169691Skan
64169691Skan      // Support for zero-sized arrays mandatory.
65169691Skan      value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__));
66169691Skan
67169691Skan      // No explicit construct/copy/destroy for aggregate type.
68169691Skan
69169691Skan      void 
70169691Skan      assign(const value_type& __u)
71169691Skan      { std::fill_n(begin(), size(), __u); }
72169691Skan
73169691Skan      void 
74169691Skan      swap(array& __other)
75169691Skan      { std::swap_ranges(begin(), end(), __other.begin()); }
76169691Skan
77169691Skan      // Iterators.
78169691Skan      iterator
79169691Skan      begin()
80169691Skan      { return iterator(&_M_instance[0]); }
81169691Skan
82169691Skan      const_iterator
83169691Skan      begin() const 
84169691Skan      { return const_iterator(&_M_instance[0]); }
85169691Skan
86169691Skan      iterator
87169691Skan      end() 
88169691Skan      { return iterator(&_M_instance[_Nm]); }
89169691Skan
90169691Skan      const_iterator
91169691Skan      end() const
92169691Skan      { return const_iterator(&_M_instance[_Nm]); }
93169691Skan
94169691Skan      reverse_iterator 
95169691Skan      rbegin()
96169691Skan      { return reverse_iterator(end()); }
97169691Skan
98169691Skan      const_reverse_iterator 
99169691Skan      rbegin() const
100169691Skan      { return const_reverse_iterator(end()); }
101169691Skan
102169691Skan      reverse_iterator 
103169691Skan      rend()
104169691Skan      { return reverse_iterator(begin()); }
105169691Skan
106169691Skan      const_reverse_iterator 
107169691Skan      rend() const
108169691Skan      { return const_reverse_iterator(begin()); }
109169691Skan
110169691Skan      // Capacity.
111169691Skan      size_type 
112169691Skan      size() const { return _Nm; }
113169691Skan
114169691Skan      size_type 
115169691Skan      max_size() const { return _Nm; }
116169691Skan
117169691Skan      bool 
118169691Skan      empty() const { return size() == 0; }
119169691Skan
120169691Skan      // Element access.
121169691Skan      reference
122169691Skan      operator[](size_type __n)
123169691Skan      { return _M_instance[__n]; }
124169691Skan
125169691Skan      const_reference
126169691Skan      operator[](size_type __n) const
127169691Skan      { return _M_instance[__n]; }
128169691Skan
129169691Skan      reference
130169691Skan      at(size_type __n)
131169691Skan      { 
132169691Skan	_M_check<_Nm>(__n);
133169691Skan	return _M_instance[__n];
134169691Skan      }
135169691Skan
136169691Skan      const_reference
137169691Skan      at(size_type __n) const
138169691Skan      {
139169691Skan	_M_check<_Nm>(__n);
140169691Skan	return _M_instance[__n];
141169691Skan      }
142169691Skan
143169691Skan      reference 
144169691Skan      front()
145169691Skan      { return *begin(); }
146169691Skan
147169691Skan      const_reference 
148169691Skan      front() const
149169691Skan      { return *begin(); }
150169691Skan
151169691Skan      reference 
152169691Skan      back()
153169691Skan      { return _Nm ? *(end() - 1) : *end(); }
154169691Skan
155169691Skan      const_reference 
156169691Skan      back() const
157169691Skan      { return _Nm ? *(end() - 1) : *end(); }
158169691Skan
159169691Skan      _Tp* 
160169691Skan      data()
161169691Skan      { return &_M_instance[0]; }
162169691Skan
163169691Skan      const _Tp* 
164169691Skan      data() const
165169691Skan      { return &_M_instance[0]; }
166169691Skan
167169691Skan    private:
168169691Skan      template<std::size_t _Mm>
169169691Skan        typename __gnu_cxx::__enable_if<_Mm, void>::__type
170169691Skan        _M_check(size_type __n) const
171169691Skan        {
172169691Skan	  if (__builtin_expect(__n >= _Mm, false))
173169691Skan	    std::__throw_out_of_range(__N("array::_M_check"));
174169691Skan	}
175169691Skan
176169691Skan      // Avoid "unsigned comparison with zero" warnings.
177169691Skan      template<std::size_t _Mm>
178169691Skan        typename __gnu_cxx::__enable_if<!_Mm, void>::__type
179169691Skan        _M_check(size_type) const
180169691Skan        { std::__throw_out_of_range(__N("array::_M_check")); }
181169691Skan    };
182169691Skan
183169691Skan  // Array comparisons.
184169691Skan  template<typename _Tp, std::size_t _Nm>
185169691Skan    inline bool 
186169691Skan    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
187169691Skan    { return std::equal(__one.begin(), __one.end(), __two.begin()); }
188169691Skan
189169691Skan  template<typename _Tp, std::size_t _Nm>
190169691Skan    inline bool
191169691Skan    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
192169691Skan    { return !(__one == __two); }
193169691Skan
194169691Skan  template<typename _Tp, std::size_t _Nm>
195169691Skan    inline bool
196169691Skan    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
197169691Skan    { 
198169691Skan      return std::lexicographical_compare(__a.begin(), __a.end(),
199169691Skan					  __b.begin(), __b.end()); 
200169691Skan    }
201169691Skan
202169691Skan  template<typename _Tp, std::size_t _Nm>
203169691Skan    inline bool
204169691Skan    operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
205169691Skan    { return __two < __one; }
206169691Skan
207169691Skan  template<typename _Tp, std::size_t _Nm>
208169691Skan    inline bool
209169691Skan    operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
210169691Skan    { return !(__one > __two); }
211169691Skan
212169691Skan  template<typename _Tp, std::size_t _Nm>
213169691Skan    inline bool
214169691Skan    operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
215169691Skan    { return !(__one < __two); }
216169691Skan
217169691Skan  // Specialized algorithms [6.2.2.2].
218169691Skan  template<typename _Tp, std::size_t _Nm>
219169691Skan    inline void
220169691Skan    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
221169691Skan    { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); }
222169691Skan
223169691Skan  // Tuple interface to class template array [6.2.2.5].
224169691Skan  template<typename _Tp> class tuple_size;
225169691Skan  template<int _Int, typename _Tp> class tuple_element;
226169691Skan
227169691Skan  template<typename _Tp, std::size_t _Nm>
228169691Skan    struct tuple_size<array<_Tp, _Nm> >
229169691Skan    { static const int value = _Nm; };
230169691Skan
231169691Skan  template<typename _Tp, std::size_t _Nm>
232169691Skan    const int tuple_size<array<_Tp, _Nm> >::value;
233169691Skan
234169691Skan  template<int _Int, typename _Tp, std::size_t _Nm>
235169691Skan    struct tuple_element<_Int, array<_Tp, _Nm> >
236169691Skan    { typedef _Tp type; };
237169691Skan
238169691Skan  template<int _Int, typename _Tp, std::size_t _Nm>
239169691Skan    inline _Tp&
240169691Skan    get(array<_Tp, _Nm>& __arr)
241169691Skan    { return __arr[_Int]; }
242169691Skan
243169691Skan  template<int _Int, typename _Tp, std::size_t _Nm>
244169691Skan    inline const _Tp&
245169691Skan    get(const array<_Tp, _Nm>& __arr)
246169691Skan    { return __arr[_Int]; }
247169691Skan
248169691Skan_GLIBCXX_END_NAMESPACE
249169691Skan}
250169691Skan
251169691Skan#endif
252