array revision 241903
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===---------------------------- array -----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_ARRAY
12227825Stheraven#define _LIBCPP_ARRAY
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    array synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraventemplate <class T, size_t N >
20227825Stheravenstruct array
21227825Stheraven{
22227825Stheraven    // types:
23227825Stheraven    typedef T & reference;
24227825Stheraven    typedef const T & const_reference;
25227825Stheraven    typedef implementation defined iterator;
26227825Stheraven    typedef implementation defined const_iterator;
27227825Stheraven    typedef size_t size_type;
28227825Stheraven    typedef ptrdiff_t difference_type;
29227825Stheraven    typedef T value_type;
30227825Stheraven    typedef T* pointer;
31227825Stheraven    typedef const T* const_pointer;
32227825Stheraven    typedef std::reverse_iterator<iterator> reverse_iterator;
33227825Stheraven    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
34227825Stheraven
35227825Stheraven    // No explicit construct/copy/destroy for aggregate type
36227825Stheraven    void fill(const T& u);
37227825Stheraven    void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
38227825Stheraven
39227825Stheraven    // iterators:
40227825Stheraven    iterator begin() noexcept;
41227825Stheraven    const_iterator begin() const noexcept;
42227825Stheraven    iterator end() noexcept;
43227825Stheraven    const_iterator end() const noexcept;
44227825Stheraven
45227825Stheraven    reverse_iterator rbegin() noexcept;
46227825Stheraven    const_reverse_iterator rbegin() const noexcept;
47227825Stheraven    reverse_iterator rend() noexcept;
48227825Stheraven    const_reverse_iterator rend() const noexcept;
49227825Stheraven
50227825Stheraven    const_iterator cbegin() const noexcept;
51227825Stheraven    const_iterator cend() const noexcept;
52227825Stheraven    const_reverse_iterator crbegin() const noexcept;
53227825Stheraven    const_reverse_iterator crend() const noexcept;
54227825Stheraven
55227825Stheraven    // capacity:
56227825Stheraven    constexpr size_type size() const noexcept;
57227825Stheraven    constexpr size_type max_size() const noexcept;
58241903Sdim    constexpr bool empty() const noexcept;
59227825Stheraven
60227825Stheraven    // element access:
61227825Stheraven    reference operator[](size_type n);
62227825Stheraven    const_reference operator[](size_type n) const;
63227825Stheraven    const_reference at(size_type n) const;
64227825Stheraven    reference at(size_type n);
65227825Stheraven
66227825Stheraven    reference front();
67227825Stheraven    const_reference front() const;
68227825Stheraven    reference back();
69227825Stheraven    const_reference back() const;
70227825Stheraven
71227825Stheraven    T* data() noexcept;
72227825Stheraven    const T* data() const noexcept;
73227825Stheraven};
74227825Stheraven
75227825Stheraventemplate <class T, size_t N>
76227825Stheraven  bool operator==(const array<T,N>& x, const array<T,N>& y);
77227825Stheraventemplate <class T, size_t N>
78227825Stheraven  bool operator!=(const array<T,N>& x, const array<T,N>& y);
79227825Stheraventemplate <class T, size_t N>
80227825Stheraven  bool operator<(const array<T,N>& x, const array<T,N>& y);
81227825Stheraventemplate <class T, size_t N>
82227825Stheraven  bool operator>(const array<T,N>& x, const array<T,N>& y);
83227825Stheraventemplate <class T, size_t N>
84227825Stheraven  bool operator<=(const array<T,N>& x, const array<T,N>& y);
85227825Stheraventemplate <class T, size_t N>
86227825Stheraven  bool operator>=(const array<T,N>& x, const array<T,N>& y);
87227825Stheraven
88227825Stheraventemplate <class T, size_t N >
89227825Stheraven  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
90227825Stheraven
91227825Stheraventemplate <class T> class tuple_size;
92227825Stheraventemplate <int I, class T> class tuple_element;
93227825Stheraventemplate <class T, size_t N> struct tuple_size<array<T, N>>;
94227825Stheraventemplate <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
95227825Stheraventemplate <int I, class T, size_t N> T& get(array<T, N>&) noexcept;
96227825Stheraventemplate <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept;
97227825Stheraventemplate <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept;
98227825Stheraven
99227825Stheraven}  // std
100227825Stheraven
101227825Stheraven*/
102227825Stheraven
103227825Stheraven#include <__config>
104227825Stheraven#include <__tuple>
105227825Stheraven#include <type_traits>
106227825Stheraven#include <utility>
107227825Stheraven#include <iterator>
108227825Stheraven#include <algorithm>
109227825Stheraven#include <stdexcept>
110227825Stheraven#if defined(_LIBCPP_NO_EXCEPTIONS)
111227825Stheraven    #include <cassert>
112227825Stheraven#endif
113227825Stheraven
114227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
115227825Stheraven#pragma GCC system_header
116227825Stheraven#endif
117227825Stheraven
118227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
119227825Stheraven
120227825Stheraventemplate <class _Tp, size_t _Size>
121227825Stheravenstruct _LIBCPP_VISIBLE array
122227825Stheraven{
123227825Stheraven    // types:
124227825Stheraven    typedef array __self;
125227825Stheraven    typedef _Tp                                   value_type;
126227825Stheraven    typedef value_type&                           reference;
127227825Stheraven    typedef const value_type&                     const_reference;
128227825Stheraven    typedef value_type*                           iterator;
129227825Stheraven    typedef const value_type*                     const_iterator;
130227825Stheraven    typedef value_type*                           pointer;
131227825Stheraven    typedef const value_type*                     const_pointer;
132227825Stheraven    typedef size_t                                size_type;
133227825Stheraven    typedef ptrdiff_t                             difference_type;
134227825Stheraven    typedef std::reverse_iterator<iterator>       reverse_iterator;
135227825Stheraven    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
136227825Stheraven
137227825Stheraven    value_type __elems_[_Size > 0 ? _Size : 1];
138227825Stheraven
139227825Stheraven    // No explicit construct/copy/destroy for aggregate type
140227825Stheraven    _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
141227825Stheraven        {_VSTD::fill_n(__elems_, _Size, __u);}
142227825Stheraven    _LIBCPP_INLINE_VISIBILITY
143227825Stheraven    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
144227825Stheraven        {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
145227825Stheraven
146227825Stheraven    // iterators:
147227825Stheraven    _LIBCPP_INLINE_VISIBILITY
148227825Stheraven    iterator begin() _NOEXCEPT {return iterator(__elems_);}
149227825Stheraven    _LIBCPP_INLINE_VISIBILITY
150227825Stheraven    const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
151227825Stheraven    _LIBCPP_INLINE_VISIBILITY
152227825Stheraven    iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
153227825Stheraven    _LIBCPP_INLINE_VISIBILITY
154227825Stheraven    const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
155227825Stheraven
156227825Stheraven    _LIBCPP_INLINE_VISIBILITY
157227825Stheraven    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
158227825Stheraven    _LIBCPP_INLINE_VISIBILITY
159227825Stheraven    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
160227825Stheraven    _LIBCPP_INLINE_VISIBILITY
161227825Stheraven    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
162227825Stheraven    _LIBCPP_INLINE_VISIBILITY
163227825Stheraven    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
164227825Stheraven
165227825Stheraven    _LIBCPP_INLINE_VISIBILITY
166227825Stheraven    const_iterator cbegin() const _NOEXCEPT {return begin();}
167227825Stheraven    _LIBCPP_INLINE_VISIBILITY
168227825Stheraven    const_iterator cend() const _NOEXCEPT {return end();}
169227825Stheraven    _LIBCPP_INLINE_VISIBILITY
170227825Stheraven    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
171227825Stheraven    _LIBCPP_INLINE_VISIBILITY
172227825Stheraven    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
173227825Stheraven
174227825Stheraven    // capacity:
175227825Stheraven    _LIBCPP_INLINE_VISIBILITY
176241903Sdim    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
177227825Stheraven    _LIBCPP_INLINE_VISIBILITY
178241903Sdim    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
179227825Stheraven    _LIBCPP_INLINE_VISIBILITY
180241903Sdim    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
181227825Stheraven
182227825Stheraven    // element access:
183227825Stheraven    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
184227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __elems_[__n];}
185227825Stheraven    reference at(size_type __n);
186227825Stheraven    const_reference at(size_type __n) const;
187227825Stheraven
188227825Stheraven    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
189227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __elems_[0];}
190227825Stheraven    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
191227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
192227825Stheraven
193227825Stheraven    _LIBCPP_INLINE_VISIBILITY
194227825Stheraven    value_type* data() _NOEXCEPT {return __elems_;}
195227825Stheraven    _LIBCPP_INLINE_VISIBILITY
196227825Stheraven    const value_type* data() const _NOEXCEPT {return __elems_;}
197227825Stheraven};
198227825Stheraven
199227825Stheraventemplate <class _Tp, size_t _Size>
200227825Stheraventypename array<_Tp, _Size>::reference
201227825Stheravenarray<_Tp, _Size>::at(size_type __n)
202227825Stheraven{
203227825Stheraven    if (__n >= _Size)
204227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
205227825Stheraven        throw out_of_range("array::at");
206227825Stheraven#else
207227825Stheraven        assert(!"array::at out_of_range");
208227825Stheraven#endif
209227825Stheraven    return __elems_[__n];
210227825Stheraven}
211227825Stheraven
212227825Stheraventemplate <class _Tp, size_t _Size>
213227825Stheraventypename array<_Tp, _Size>::const_reference
214227825Stheravenarray<_Tp, _Size>::at(size_type __n) const
215227825Stheraven{
216227825Stheraven    if (__n >= _Size)
217227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
218227825Stheraven        throw out_of_range("array::at");
219227825Stheraven#else
220227825Stheraven        assert(!"array::at out_of_range");
221227825Stheraven#endif
222227825Stheraven    return __elems_[__n];
223227825Stheraven}
224227825Stheraven
225227825Stheraventemplate <class _Tp, size_t _Size>
226227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
227227825Stheravenbool
228227825Stheravenoperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
229227825Stheraven{
230227825Stheraven    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
231227825Stheraven}
232227825Stheraven
233227825Stheraventemplate <class _Tp, size_t _Size>
234227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
235227825Stheravenbool
236227825Stheravenoperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
237227825Stheraven{
238227825Stheraven    return !(__x == __y);
239227825Stheraven}
240227825Stheraven
241227825Stheraventemplate <class _Tp, size_t _Size>
242227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
243227825Stheravenbool
244227825Stheravenoperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
245227825Stheraven{
246227825Stheraven    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
247227825Stheraven}
248227825Stheraven
249227825Stheraventemplate <class _Tp, size_t _Size>
250227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
251227825Stheravenbool
252227825Stheravenoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
253227825Stheraven{
254227825Stheraven    return __y < __x;
255227825Stheraven}
256227825Stheraven
257227825Stheraventemplate <class _Tp, size_t _Size>
258227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
259227825Stheravenbool
260227825Stheravenoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
261227825Stheraven{
262227825Stheraven    return !(__y < __x);
263227825Stheraven}
264227825Stheraven
265227825Stheraventemplate <class _Tp, size_t _Size>
266227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
267227825Stheravenbool
268227825Stheravenoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
269227825Stheraven{
270227825Stheraven    return !(__x < __y);
271227825Stheraven}
272227825Stheraven
273227825Stheraventemplate <class _Tp, size_t _Size>
274227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
275227825Stheraventypename enable_if
276227825Stheraven<
277227825Stheraven    __is_swappable<_Tp>::value,
278227825Stheraven    void
279227825Stheraven>::type
280227825Stheravenswap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
281227825Stheraven                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
282227825Stheraven{
283227825Stheraven    __x.swap(__y);
284227825Stheraven}
285227825Stheraven
286227825Stheraventemplate <class _Tp, size_t _Size>
287227825Stheravenclass _LIBCPP_VISIBLE tuple_size<array<_Tp, _Size> >
288227825Stheraven    : public integral_constant<size_t, _Size> {};
289227825Stheraven
290227825Stheraventemplate <class _Tp, size_t _Size>
291227825Stheravenclass _LIBCPP_VISIBLE tuple_size<const array<_Tp, _Size> >
292227825Stheraven    : public integral_constant<size_t, _Size> {};
293227825Stheraven
294227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
295227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, array<_Tp, _Size> >
296227825Stheraven{
297227825Stheravenpublic:
298227825Stheraven    typedef _Tp type;
299227825Stheraven};
300227825Stheraven
301227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
302227825Stheravenclass _LIBCPP_VISIBLE tuple_element<_Ip, const array<_Tp, _Size> >
303227825Stheraven{
304227825Stheravenpublic:
305227825Stheraven    typedef const _Tp type;
306227825Stheraven};
307227825Stheraven
308227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
309227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
310227825Stheraven_Tp&
311227825Stheravenget(array<_Tp, _Size>& __a) _NOEXCEPT
312227825Stheraven{
313227825Stheraven    return __a[_Ip];
314227825Stheraven}
315227825Stheraven
316227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
317227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
318227825Stheravenconst _Tp&
319227825Stheravenget(const array<_Tp, _Size>& __a) _NOEXCEPT
320227825Stheraven{
321227825Stheraven    return __a[_Ip];
322227825Stheraven}
323227825Stheraven
324227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
325227825Stheraven
326227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
327227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
328227825Stheraven_Tp&&
329227825Stheravenget(array<_Tp, _Size>&& __a) _NOEXCEPT
330227825Stheraven{
331227825Stheraven    return _VSTD::move(__a[_Ip]);
332227825Stheraven}
333227825Stheraven
334227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
335227825Stheraven
336227825Stheraven_LIBCPP_END_NAMESPACE_STD
337227825Stheraven
338227825Stheraven#endif  // _LIBCPP_ARRAY
339