1// class template array -*- C++ -*-
2
3// Copyright (C) 2007, 2008, 2009, 2010 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 3, 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// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file tr1_impl/array
26 *  This is an internal header file, included by other library headers.
27 *  You should not attempt to use it directly.
28 */
29
30namespace std
31{
32_GLIBCXX_BEGIN_NAMESPACE_TR1
33
34  /**
35   *  @brief A standard container for storing a fixed size sequence of elements.
36   *
37   *  @ingroup sequences
38   *
39   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
40   *  <a href="tables.html#66">reversible container</a>, and a
41   *  <a href="tables.html#67">sequence</a>.
42   *
43   *  Sets support random access iterators.
44   *
45   *  @param  Tp  Type of element. Required to be a complete type.
46   *  @param  N  Number of elements.
47  */
48  template<typename _Tp, std::size_t _Nm>
49    struct array
50    {
51      typedef _Tp 	    			      value_type;
52#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
53      typedef _Tp*                                    pointer;
54      typedef const _Tp*                              const_pointer;
55#endif
56      typedef value_type&                   	      reference;
57      typedef const value_type&             	      const_reference;
58      typedef value_type*          		      iterator;
59      typedef const value_type*			      const_iterator;
60      typedef std::size_t                    	      size_type;
61      typedef std::ptrdiff_t                   	      difference_type;
62      typedef std::reverse_iterator<iterator>	      reverse_iterator;
63      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
64
65      // Support for zero-sized arrays mandatory.
66      value_type _M_instance[_Nm ? _Nm : 1];
67
68      // No explicit construct/copy/destroy for aggregate type.
69
70      void
71#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
72      // DR 776.
73      fill(const value_type& __u)
74#else
75      assign(const value_type& __u)
76#endif
77      { std::fill_n(begin(), size(), __u); }
78
79      void
80      swap(array& __other)
81      { std::swap_ranges(begin(), end(), __other.begin()); }
82
83      // Iterators.
84      iterator
85      begin()
86      { return iterator(&_M_instance[0]); }
87
88      const_iterator
89      begin() const 
90      { return const_iterator(&_M_instance[0]); }
91
92      iterator
93      end()
94      { return iterator(&_M_instance[_Nm]); }
95
96      const_iterator
97      end() const
98      { return const_iterator(&_M_instance[_Nm]); }
99
100      reverse_iterator 
101      rbegin()
102      { return reverse_iterator(end()); }
103
104      const_reverse_iterator 
105      rbegin() const
106      { return const_reverse_iterator(end()); }
107
108      reverse_iterator 
109      rend()
110      { return reverse_iterator(begin()); }
111
112      const_reverse_iterator 
113      rend() const
114      { return const_reverse_iterator(begin()); }
115
116#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
117      const_iterator
118      cbegin() const 
119      { return const_iterator(&_M_instance[0]); }
120
121      const_iterator
122      cend() const
123      { return const_iterator(&_M_instance[_Nm]); }
124
125      const_reverse_iterator 
126      crbegin() const
127      { return const_reverse_iterator(end()); }
128
129      const_reverse_iterator 
130      crend() const
131      { return const_reverse_iterator(begin()); }
132#endif
133
134      // Capacity.
135      size_type 
136      size() const { return _Nm; }
137
138      size_type 
139      max_size() const { return _Nm; }
140
141      bool 
142      empty() const { return size() == 0; }
143
144      // Element access.
145      reference
146      operator[](size_type __n)
147      { return _M_instance[__n]; }
148
149      const_reference
150      operator[](size_type __n) const
151      { return _M_instance[__n]; }
152
153      reference
154      at(size_type __n)
155      {
156	if (__n >= _Nm)
157	  std::__throw_out_of_range(__N("array::at"));
158	return _M_instance[__n];
159      }
160
161      const_reference
162      at(size_type __n) const
163      {
164	if (__n >= _Nm)
165	  std::__throw_out_of_range(__N("array::at"));
166	return _M_instance[__n];
167      }
168
169      reference 
170      front()
171      { return *begin(); }
172
173      const_reference 
174      front() const
175      { return *begin(); }
176
177      reference 
178      back()
179      { return _Nm ? *(end() - 1) : *end(); }
180
181      const_reference 
182      back() const
183      { return _Nm ? *(end() - 1) : *end(); }
184
185      _Tp* 
186      data()
187      { return &_M_instance[0]; }
188
189      const _Tp* 
190      data() const
191      { return &_M_instance[0]; }
192    };
193
194  // Array comparisons.
195  template<typename _Tp, std::size_t _Nm>
196    inline bool 
197    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
198    { return std::equal(__one.begin(), __one.end(), __two.begin()); }
199
200  template<typename _Tp, std::size_t _Nm>
201    inline bool
202    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
203    { return !(__one == __two); }
204
205  template<typename _Tp, std::size_t _Nm>
206    inline bool
207    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
208    { 
209      return std::lexicographical_compare(__a.begin(), __a.end(),
210					  __b.begin(), __b.end()); 
211    }
212
213  template<typename _Tp, std::size_t _Nm>
214    inline bool
215    operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
216    { return __two < __one; }
217
218  template<typename _Tp, std::size_t _Nm>
219    inline bool
220    operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
221    { return !(__one > __two); }
222
223  template<typename _Tp, std::size_t _Nm>
224    inline bool
225    operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
226    { return !(__one < __two); }
227
228  // Specialized algorithms [6.2.2.2].
229  template<typename _Tp, std::size_t _Nm>
230    inline void
231    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
232    { __one.swap(__two); }
233
234  // Tuple interface to class template array [6.2.2.5].
235
236  /// tuple_size
237  template<typename _Tp> 
238    class tuple_size;
239
240  /// tuple_element
241#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
242  template<std::size_t _Int, typename _Tp>
243#else
244  template<int _Int, typename _Tp>
245#endif
246    class tuple_element;
247
248  template<typename _Tp, std::size_t _Nm>
249    struct tuple_size<array<_Tp, _Nm> >
250#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
251    { static const std::size_t value = _Nm; };
252#else
253    { static const int value = _Nm; };
254#endif
255
256  template<typename _Tp, std::size_t _Nm>
257#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
258    const std::size_t
259#else
260    const int
261#endif
262    tuple_size<array<_Tp, _Nm> >::value;  
263
264#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
265  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
266#else
267  template<int _Int, typename _Tp, std::size_t _Nm>
268#endif
269    struct tuple_element<_Int, array<_Tp, _Nm> >
270    { typedef _Tp type; };
271
272#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
273  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
274#else
275  template<int _Int, typename _Tp, std::size_t _Nm>
276#endif
277    inline _Tp&
278    get(array<_Tp, _Nm>& __arr)
279    { return __arr[_Int]; }
280
281#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
282  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
283#else
284  template<int _Int, typename _Tp, std::size_t _Nm>
285#endif
286    inline const _Tp&
287    get(const array<_Tp, _Nm>& __arr)
288    { return __arr[_Int]; }
289
290_GLIBCXX_END_NAMESPACE_TR1
291}
292