1// class template array -*- C++ -*-
2
3// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file tr1/array
27 *  This is a TR1 C++ Library header.
28 */
29
30#ifndef _GLIBCXX_TR1_ARRAY
31#define _GLIBCXX_TR1_ARRAY 1
32
33#pragma GCC system_header
34
35#include <bits/stl_algobase.h>
36
37namespace std _GLIBCXX_VISIBILITY(default)
38{
39namespace tr1
40{
41_GLIBCXX_BEGIN_NAMESPACE_VERSION
42
43  /**
44   *  @brief A standard container for storing a fixed size sequence of elements.
45   *
46   *  @ingroup sequences
47   *
48   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
49   *  <a href="tables.html#66">reversible container</a>, and a
50   *  <a href="tables.html#67">sequence</a>.
51   *
52   *  Sets support random access iterators.
53   *
54   *  @param  Tp  Type of element. Required to be a complete type.
55   *  @param  N  Number of elements.
56  */
57  template<typename _Tp, std::size_t _Nm>
58    struct array
59    {
60      typedef _Tp 	    			      value_type;
61      typedef value_type&                   	      reference;
62      typedef const value_type&             	      const_reference;
63      typedef value_type*          		      iterator;
64      typedef const value_type*			      const_iterator;
65      typedef std::size_t                    	      size_type;
66      typedef std::ptrdiff_t                   	      difference_type;
67      typedef std::reverse_iterator<iterator>	      reverse_iterator;
68      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
69
70      // Support for zero-sized arrays mandatory.
71      value_type _M_instance[_Nm ? _Nm : 1];
72
73      // No explicit construct/copy/destroy for aggregate type.
74
75      void
76      assign(const value_type& __u)
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(std::__addressof(_M_instance[0])); }
87
88      const_iterator
89      begin() const
90      { return const_iterator(std::__addressof(_M_instance[0])); }
91
92      iterator
93      end()
94      { return iterator(std::__addressof(_M_instance[_Nm])); }
95
96      const_iterator
97      end() const
98      { return const_iterator(std::__addressof(_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      // Capacity.
117      size_type
118      size() const { return _Nm; }
119
120      size_type
121      max_size() const { return _Nm; }
122
123      bool
124      empty() const { return size() == 0; }
125
126      // Element access.
127      reference
128      operator[](size_type __n)
129      { return _M_instance[__n]; }
130
131      const_reference
132      operator[](size_type __n) const
133      { return _M_instance[__n]; }
134
135      reference
136      at(size_type __n)
137      {
138	if (__n >= _Nm)
139	  std::__throw_out_of_range(__N("array::at"));
140	return _M_instance[__n];
141      }
142
143      const_reference
144      at(size_type __n) const
145      {
146	if (__n >= _Nm)
147	  std::__throw_out_of_range(__N("array::at"));
148	return _M_instance[__n];
149      }
150
151      reference
152      front()
153      { return *begin(); }
154
155      const_reference
156      front() const
157      { return *begin(); }
158
159      reference
160      back()
161      { return _Nm ? *(end() - 1) : *end(); }
162
163      const_reference
164      back() const
165      { return _Nm ? *(end() - 1) : *end(); }
166
167      _Tp*
168      data()
169      { return std::__addressof(_M_instance[0]); }
170
171      const _Tp*
172      data() const
173      { return std::__addressof(_M_instance[0]); }
174    };
175
176  // Array comparisons.
177  template<typename _Tp, std::size_t _Nm>
178    inline bool
179    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
180    { return std::equal(__one.begin(), __one.end(), __two.begin()); }
181
182  template<typename _Tp, std::size_t _Nm>
183    inline bool
184    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
185    { return !(__one == __two); }
186
187  template<typename _Tp, std::size_t _Nm>
188    inline bool
189    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
190    {
191      return std::lexicographical_compare(__a.begin(), __a.end(),
192					  __b.begin(), __b.end());
193    }
194
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 __two < __one; }
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>& __one, const array<_Tp, _Nm>& __two)
208    { return !(__one < __two); }
209
210  // Specialized algorithms [6.2.2.2].
211  template<typename _Tp, std::size_t _Nm>
212    inline void
213    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
214    { __one.swap(__two); }
215
216  // Tuple interface to class template array [6.2.2.5].
217
218  /// tuple_size
219  template<typename _Tp>
220    class tuple_size;
221
222  /// tuple_element
223  template<int _Int, typename _Tp>
224    class tuple_element;
225
226  template<typename _Tp, std::size_t _Nm>
227    struct tuple_size<array<_Tp, _Nm> >
228    { static const int value = _Nm; };
229
230  template<typename _Tp, std::size_t _Nm>
231    const int
232    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_VERSION
249}
250}
251
252#endif // _GLIBCXX_TR1_ARRAY
253