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);
62262801Sdim    const_reference operator[](size_type n) const; // constexpr in C++14
63262801Sdim    const_reference at(size_type n) const; // constexpr in C++14
64227825Stheraven    reference at(size_type n);
65227825Stheraven
66227825Stheraven    reference front();
67262801Sdim    const_reference front() const; // constexpr in C++14
68227825Stheraven    reference back();
69262801Sdim    const_reference back() const; // constexpr in C++14
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>>;
95262801Sdimtemplate <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
96262801Sdimtemplate <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
97262801Sdimtemplate <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
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>
121262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY 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];}
184262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}
185227825Stheraven    reference at(size_type __n);
186262801Sdim    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
187227825Stheraven
188227825Stheraven    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
189262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}
190227825Stheraven    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
191262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 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>
213262801Sdim_LIBCPP_CONSTEXPR_AFTER_CXX11
214227825Stheraventypename array<_Tp, _Size>::const_reference
215227825Stheravenarray<_Tp, _Size>::at(size_type __n) const
216227825Stheraven{
217227825Stheraven    if (__n >= _Size)
218227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
219227825Stheraven        throw out_of_range("array::at");
220227825Stheraven#else
221227825Stheraven        assert(!"array::at out_of_range");
222227825Stheraven#endif
223227825Stheraven    return __elems_[__n];
224227825Stheraven}
225227825Stheraven
226227825Stheraventemplate <class _Tp, size_t _Size>
227262801Sdiminline _LIBCPP_INLINE_VISIBILITY
228227825Stheravenbool
229227825Stheravenoperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
230227825Stheraven{
231227825Stheraven    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
232227825Stheraven}
233227825Stheraven
234227825Stheraventemplate <class _Tp, size_t _Size>
235262801Sdiminline _LIBCPP_INLINE_VISIBILITY
236227825Stheravenbool
237227825Stheravenoperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
238227825Stheraven{
239227825Stheraven    return !(__x == __y);
240227825Stheraven}
241227825Stheraven
242227825Stheraventemplate <class _Tp, size_t _Size>
243262801Sdiminline _LIBCPP_INLINE_VISIBILITY
244227825Stheravenbool
245227825Stheravenoperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
246227825Stheraven{
247227825Stheraven    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
248227825Stheraven}
249227825Stheraven
250227825Stheraventemplate <class _Tp, size_t _Size>
251262801Sdiminline _LIBCPP_INLINE_VISIBILITY
252227825Stheravenbool
253227825Stheravenoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
254227825Stheraven{
255227825Stheraven    return __y < __x;
256227825Stheraven}
257227825Stheraven
258227825Stheraventemplate <class _Tp, size_t _Size>
259262801Sdiminline _LIBCPP_INLINE_VISIBILITY
260227825Stheravenbool
261227825Stheravenoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
262227825Stheraven{
263227825Stheraven    return !(__y < __x);
264227825Stheraven}
265227825Stheraven
266227825Stheraventemplate <class _Tp, size_t _Size>
267262801Sdiminline _LIBCPP_INLINE_VISIBILITY
268227825Stheravenbool
269227825Stheravenoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
270227825Stheraven{
271227825Stheraven    return !(__x < __y);
272227825Stheraven}
273227825Stheraven
274227825Stheraventemplate <class _Tp, size_t _Size>
275262801Sdiminline _LIBCPP_INLINE_VISIBILITY
276227825Stheraventypename enable_if
277227825Stheraven<
278227825Stheraven    __is_swappable<_Tp>::value,
279227825Stheraven    void
280227825Stheraven>::type
281227825Stheravenswap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
282227825Stheraven                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
283227825Stheraven{
284227825Stheraven    __x.swap(__y);
285227825Stheraven}
286227825Stheraven
287227825Stheraventemplate <class _Tp, size_t _Size>
288262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
289227825Stheraven    : public integral_constant<size_t, _Size> {};
290227825Stheraven
291227825Stheraventemplate <class _Tp, size_t _Size>
292262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
293227825Stheraven    : public integral_constant<size_t, _Size> {};
294227825Stheraven
295227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
296262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
297227825Stheraven{
298227825Stheravenpublic:
299227825Stheraven    typedef _Tp type;
300227825Stheraven};
301227825Stheraven
302227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
303262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
304227825Stheraven{
305227825Stheravenpublic:
306227825Stheraven    typedef const _Tp type;
307227825Stheraven};
308227825Stheraven
309227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
310262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
311227825Stheraven_Tp&
312227825Stheravenget(array<_Tp, _Size>& __a) _NOEXCEPT
313227825Stheraven{
314246487Stheraven    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
315262801Sdim    return __a.__elems_[_Ip];
316227825Stheraven}
317227825Stheraven
318227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
319262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
320227825Stheravenconst _Tp&
321227825Stheravenget(const array<_Tp, _Size>& __a) _NOEXCEPT
322227825Stheraven{
323246487Stheraven    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
324262801Sdim    return __a.__elems_[_Ip];
325227825Stheraven}
326227825Stheraven
327227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
328227825Stheraven
329227825Stheraventemplate <size_t _Ip, class _Tp, size_t _Size>
330262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
331227825Stheraven_Tp&&
332227825Stheravenget(array<_Tp, _Size>&& __a) _NOEXCEPT
333227825Stheraven{
334246487Stheraven    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
335262801Sdim    return _VSTD::move(__a.__elems_[_Ip]);
336227825Stheraven}
337227825Stheraven
338227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
339227825Stheraven
340227825Stheraven_LIBCPP_END_NAMESPACE_STD
341227825Stheraven
342227825Stheraven#endif  // _LIBCPP_ARRAY
343