OSDN Git Service

2011-07-20 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / array
1 // <array> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 include/array
26  *  This is a Standard C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_ARRAY
30 #define _GLIBCXX_ARRAY 1
31
32 #pragma GCC system_header
33
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37
38 #include <stdexcept>
39 #include <bits/stl_algobase.h>
40 #include <bits/range_access.h>
41
42 namespace std _GLIBCXX_VISIBILITY(default)
43 {
44 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45
46   /**
47    *  @brief A standard container for storing a fixed size sequence of elements.
48    *
49    *  @ingroup sequences
50    *
51    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
52    *  <a href="tables.html#66">reversible container</a>, and a
53    *  <a href="tables.html#67">sequence</a>.
54    *
55    *  Sets support random access iterators.
56    *
57    *  @param  Tp  Type of element. Required to be a complete type.
58    *  @param  N  Number of elements.
59   */
60   template<typename _Tp, std::size_t _Nm>
61     struct array
62     {
63       typedef _Tp                                     value_type;
64       typedef _Tp*                                    pointer;
65       typedef const _Tp*                              const_pointer;
66       typedef value_type&                             reference;
67       typedef const value_type&                       const_reference;
68       typedef value_type*                             iterator;
69       typedef const value_type*                       const_iterator;
70       typedef std::size_t                             size_type;
71       typedef std::ptrdiff_t                          difference_type;
72       typedef std::reverse_iterator<iterator>         reverse_iterator;
73       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
74
75       // Support for zero-sized arrays mandatory.
76       value_type _M_instance[_Nm ? _Nm : 1];
77
78       // No explicit construct/copy/destroy for aggregate type.
79
80       // DR 776.
81       void
82       fill(const value_type& __u)
83       { std::fill_n(begin(), size(), __u); }
84
85       void
86       swap(array& __other)
87       noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
88       { std::swap_ranges(begin(), end(), __other.begin()); }
89
90       // Iterators.
91       iterator
92       begin() noexcept
93       { return iterator(std::__addressof(_M_instance[0])); }
94
95       const_iterator
96       begin() const noexcept
97       { return const_iterator(std::__addressof(_M_instance[0])); }
98
99       iterator
100       end() noexcept
101       { return iterator(std::__addressof(_M_instance[_Nm])); }
102
103       const_iterator
104       end() const noexcept
105       { return const_iterator(std::__addressof(_M_instance[_Nm])); }
106
107       reverse_iterator 
108       rbegin() noexcept
109       { return reverse_iterator(end()); }
110
111       const_reverse_iterator 
112       rbegin() const noexcept
113       { return const_reverse_iterator(end()); }
114
115       reverse_iterator 
116       rend() noexcept
117       { return reverse_iterator(begin()); }
118
119       const_reverse_iterator 
120       rend() const noexcept
121       { return const_reverse_iterator(begin()); }
122
123       const_iterator
124       cbegin() const noexcept
125       { return const_iterator(std::__addressof(_M_instance[0])); }
126
127       const_iterator
128       cend() const noexcept
129       { return const_iterator(std::__addressof(_M_instance[_Nm])); }
130
131       const_reverse_iterator 
132       crbegin() const noexcept
133       { return const_reverse_iterator(end()); }
134
135       const_reverse_iterator 
136       crend() const noexcept
137       { return const_reverse_iterator(begin()); }
138
139       // Capacity.
140       constexpr size_type 
141       size() const noexcept { return _Nm; }
142
143       constexpr size_type 
144       max_size() const noexcept { return _Nm; }
145
146       constexpr bool 
147       empty() const noexcept { return size() == 0; }
148
149       // Element access.
150       reference
151       operator[](size_type __n)
152       { return _M_instance[__n]; }
153
154       constexpr const_reference
155       operator[](size_type __n) const noexcept
156       { return _M_instance[__n]; }
157
158       reference
159       at(size_type __n)
160       {
161         if (__n >= _Nm)
162           std::__throw_out_of_range(__N("array::at"));
163         return _M_instance[__n];
164       }
165
166       constexpr const_reference
167       at(size_type __n) const
168       {
169         return __n < _Nm ? _M_instance[__n] : 
170 #ifdef __EXCEPTIONS
171                            throw out_of_range(__N("array::at"));
172 #else
173                            _M_instance[0];
174 #endif
175       }
176
177       reference 
178       front()
179       { return *begin(); }
180
181       const_reference 
182       front() const
183       { return *begin(); }
184
185       reference 
186       back()
187       { return _Nm ? *(end() - 1) : *end(); }
188
189       const_reference 
190       back() const
191       { return _Nm ? *(end() - 1) : *end(); }
192
193       _Tp*
194       data() noexcept
195       { return std::__addressof(_M_instance[0]); }
196
197       const _Tp*
198       data() const noexcept
199       { return std::__addressof(_M_instance[0]); }
200     };
201
202   // Array comparisons.
203   template<typename _Tp, std::size_t _Nm>
204     inline bool 
205     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
206     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
207
208   template<typename _Tp, std::size_t _Nm>
209     inline bool
210     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
211     { return !(__one == __two); }
212
213   template<typename _Tp, std::size_t _Nm>
214     inline bool
215     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
216     { 
217       return std::lexicographical_compare(__a.begin(), __a.end(),
218                                           __b.begin(), __b.end()); 
219     }
220
221   template<typename _Tp, std::size_t _Nm>
222     inline bool
223     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
224     { return __two < __one; }
225
226   template<typename _Tp, std::size_t _Nm>
227     inline bool
228     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
229     { return !(__one > __two); }
230
231   template<typename _Tp, std::size_t _Nm>
232     inline bool
233     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
234     { return !(__one < __two); }
235
236   // Specialized algorithms.
237   template<typename _Tp, std::size_t _Nm>
238     inline void
239     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
240     noexcept(noexcept(__one.swap(__two)))
241     { __one.swap(__two); }
242
243   // Tuple interface to class template array.
244
245   /// tuple_size
246   template<typename _Tp> 
247     class tuple_size;
248
249   template<typename _Tp, std::size_t _Nm>
250     struct tuple_size<array<_Tp, _Nm>>
251     : public integral_constant<std::size_t, _Nm> { };
252
253   /// tuple_element
254   template<std::size_t _Int, typename _Tp>
255     class tuple_element;
256
257   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
258     struct tuple_element<_Int, array<_Tp, _Nm> >
259     { typedef _Tp type; };
260
261   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
262     inline _Tp&
263     get(array<_Tp, _Nm>& __arr) noexcept
264     { return __arr[_Int]; }
265
266   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
267     inline _Tp&&
268     get(array<_Tp, _Nm>&& __arr) noexcept
269     { return std::move(get<_Int>(__arr)); }
270
271   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
272     inline const _Tp&
273     get(const array<_Tp, _Nm>& __arr) noexcept
274     { return __arr[_Int]; }
275
276 _GLIBCXX_END_NAMESPACE_VERSION
277 } // namespace
278
279 #endif // __GXX_EXPERIMENTAL_CXX0X__
280
281 #endif // _GLIBCXX_ARRAY