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