array revision 246487
154359Sroberto// -*- C++ -*-
254359Sroberto//===---------------------------- array -----------------------------------===//
354359Sroberto//
454359Sroberto//                     The LLVM Compiler Infrastructure
554359Sroberto//
6280849Scy// This file is dual licensed under the MIT and the University of Illinois Open
7280849Scy// Source Licenses. See LICENSE.TXT for details.
882498Sroberto//
954359Sroberto//===----------------------------------------------------------------------===//
10280849Scy
1154359Sroberto#ifndef _LIBCPP_ARRAY
1254359Sroberto#define _LIBCPP_ARRAY
1354359Sroberto
14280849Scy/*
1554359Sroberto    array synopsis
1654359Sroberto
1754359Srobertonamespace std
18280849Scy{
19280849Scytemplate <class T, size_t N >
20182007Srobertostruct array
2154359Sroberto{
22182007Sroberto    // types:
23280849Scy    typedef T & reference;
2454359Sroberto    typedef const T & const_reference;
25280849Scy    typedef implementation defined iterator;
26280849Scy    typedef implementation defined const_iterator;
2754359Sroberto    typedef size_t size_type;
28182007Sroberto    typedef ptrdiff_t difference_type;
29182007Sroberto    typedef T value_type;
30182007Sroberto    typedef T* pointer;
31182007Sroberto    typedef const T* const_pointer;
32182007Sroberto    typedef std::reverse_iterator<iterator> reverse_iterator;
33182007Sroberto    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
34182007Sroberto
35182007Sroberto    // No explicit construct/copy/destroy for aggregate type
36182007Sroberto    void fill(const T& u);
37182007Sroberto    void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
3854359Sroberto
39280849Scy    // iterators:
40280849Scy    iterator begin() noexcept;
4154359Sroberto    const_iterator begin() const noexcept;
4254359Sroberto    iterator end() noexcept;
43280849Scy    const_iterator end() const noexcept;
44280849Scy
45280849Scy    reverse_iterator rbegin() noexcept;
46280849Scy    const_reverse_iterator rbegin() const noexcept;
47280849Scy    reverse_iterator rend() noexcept;
4854359Sroberto    const_reverse_iterator rend() const noexcept;
4954359Sroberto
5054359Sroberto    const_iterator cbegin() const noexcept;
5154359Sroberto    const_iterator cend() const noexcept;
5254359Sroberto    const_reverse_iterator crbegin() const noexcept;
5354359Sroberto    const_reverse_iterator crend() const noexcept;
5454359Sroberto
5554359Sroberto    // capacity:
5654359Sroberto    constexpr size_type size() const noexcept;
57182007Sroberto    constexpr size_type max_size() const noexcept;
5854359Sroberto    constexpr bool empty() const noexcept;
5954359Sroberto
6054359Sroberto    // element access:
6154359Sroberto    reference operator[](size_type n);
6254359Sroberto    const_reference operator[](size_type n) const;
63182007Sroberto    const_reference at(size_type n) const;
6454359Sroberto    reference at(size_type n);
6554359Sroberto
6654359Sroberto    reference front();
6754359Sroberto    const_reference front() const;
6854359Sroberto    reference back();
6954359Sroberto    const_reference back() const;
7054359Sroberto
7154359Sroberto    T* data() noexcept;
72280849Scy    const T* data() const noexcept;
73182007Sroberto};
7454359Sroberto
75280849Scytemplate <class T, size_t N>
7654359Sroberto  bool operator==(const array<T,N>& x, const array<T,N>& y);
7754359Srobertotemplate <class T, size_t N>
7854359Sroberto  bool operator!=(const array<T,N>& x, const array<T,N>& y);
79182007Srobertotemplate <class T, size_t N>
8054359Sroberto  bool operator<(const array<T,N>& x, const array<T,N>& y);
81182007Srobertotemplate <class T, size_t N>
82182007Sroberto  bool operator>(const array<T,N>& x, const array<T,N>& y);
83182007Srobertotemplate <class T, size_t N>
84182007Sroberto  bool operator<=(const array<T,N>& x, const array<T,N>& y);
85182007Srobertotemplate <class T, size_t N>
86182007Sroberto  bool operator>=(const array<T,N>& x, const array<T,N>& y);
87280849Scy
88316722Sdelphijtemplate <class T, size_t N >
89280849Scy  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
90182007Sroberto
91280849Scytemplate <class T> class tuple_size;
92280849Scytemplate <int I, class T> class tuple_element;
93280849Scytemplate <class T, size_t N> struct tuple_size<array<T, N>>;
94280849Scytemplate <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
95280849Scytemplate <int I, class T, size_t N> T& get(array<T, N>&) noexcept;
96280849Scytemplate <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept;
97280849Scytemplate <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept;
98280849Scy
99280849Scy}  // std
100280849Scy
101182007Sroberto*/
102182007Sroberto
103182007Sroberto#include <__config>
10454359Sroberto#include <__tuple>
10554359Sroberto#include <type_traits>
10654359Sroberto#include <utility>
10754359Sroberto#include <iterator>
10854359Sroberto#include <algorithm>
10954359Sroberto#include <stdexcept>
11054359Sroberto#if defined(_LIBCPP_NO_EXCEPTIONS)
11154359Sroberto    #include <cassert>
11254359Sroberto#endif
11354359Sroberto
11454359Sroberto#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
115182007Sroberto#pragma GCC system_header
116182007Sroberto#endif
11754359Sroberto
118182007Sroberto_LIBCPP_BEGIN_NAMESPACE_STD
11954359Sroberto
120182007Srobertotemplate <class _Tp, size_t _Size>
121182007Srobertostruct _LIBCPP_VISIBLE array
12254359Sroberto{
12354359Sroberto    // types:
124280849Scy    typedef array __self;
125280849Scy    typedef _Tp                                   value_type;
126280849Scy    typedef value_type&                           reference;
12754359Sroberto    typedef const value_type&                     const_reference;
12854359Sroberto    typedef value_type*                           iterator;
129280849Scy    typedef const value_type*                     const_iterator;
130280849Scy    typedef value_type*                           pointer;
131280849Scy    typedef const value_type*                     const_pointer;
132280849Scy    typedef size_t                                size_type;
133280849Scy    typedef ptrdiff_t                             difference_type;
134280849Scy    typedef std::reverse_iterator<iterator>       reverse_iterator;
135280849Scy    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
136280849Scy
137280849Scy    value_type __elems_[_Size > 0 ? _Size : 1];
138280849Scy
139280849Scy    // No explicit construct/copy/destroy for aggregate type
140280849Scy    _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
141280849Scy        {_VSTD::fill_n(__elems_, _Size, __u);}
142280849Scy    _LIBCPP_INLINE_VISIBILITY
143280849Scy    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
144280849Scy        {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
145280849Scy
146280849Scy    // iterators:
147280849Scy    _LIBCPP_INLINE_VISIBILITY
148280849Scy    iterator begin() _NOEXCEPT {return iterator(__elems_);}
149280849Scy    _LIBCPP_INLINE_VISIBILITY
150280849Scy    const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
151280849Scy    _LIBCPP_INLINE_VISIBILITY
152280849Scy    iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
15354359Sroberto    _LIBCPP_INLINE_VISIBILITY
154182007Sroberto    const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
15554359Sroberto
156182007Sroberto    _LIBCPP_INLINE_VISIBILITY
157182007Sroberto    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
15854359Sroberto    _LIBCPP_INLINE_VISIBILITY
159298695Sdelphij    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
160298695Sdelphij    _LIBCPP_INLINE_VISIBILITY
161298695Sdelphij    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
162298695Sdelphij    _LIBCPP_INLINE_VISIBILITY
163298695Sdelphij    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
164298695Sdelphij
165298695Sdelphij    _LIBCPP_INLINE_VISIBILITY
166298695Sdelphij    const_iterator cbegin() const _NOEXCEPT {return begin();}
16754359Sroberto    _LIBCPP_INLINE_VISIBILITY
16854359Sroberto    const_iterator cend() const _NOEXCEPT {return end();}
16954359Sroberto    _LIBCPP_INLINE_VISIBILITY
170182007Sroberto    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
17154359Sroberto    _LIBCPP_INLINE_VISIBILITY
172182007Sroberto    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
17354359Sroberto
174182007Sroberto    // capacity:
175182007Sroberto    _LIBCPP_INLINE_VISIBILITY
176182007Sroberto    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
177182007Sroberto    _LIBCPP_INLINE_VISIBILITY
178182007Sroberto    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
179280849Scy    _LIBCPP_INLINE_VISIBILITY
180182007Sroberto    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
181182007Sroberto
18254359Sroberto    // element access:
18354359Sroberto    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
184280849Scy    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __elems_[__n];}
185182007Sroberto    reference at(size_type __n);
186182007Sroberto    const_reference at(size_type __n) const;
18754359Sroberto
188280849Scy    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
189280849Scy    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __elems_[0];}
190182007Sroberto    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
191280849Scy    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
192280849Scy
193182007Sroberto    _LIBCPP_INLINE_VISIBILITY
194182007Sroberto    value_type* data() _NOEXCEPT {return __elems_;}
195280849Scy    _LIBCPP_INLINE_VISIBILITY
196280849Scy    const value_type* data() const _NOEXCEPT {return __elems_;}
197182007Sroberto};
19854359Sroberto
199182007Srobertotemplate <class _Tp, size_t _Size>
200280849Scytypename array<_Tp, _Size>::reference
201280849Scyarray<_Tp, _Size>::at(size_type __n)
20254359Sroberto{
20354359Sroberto    if (__n >= _Size)
204280849Scy#ifndef _LIBCPP_NO_EXCEPTIONS
205182007Sroberto        throw out_of_range("array::at");
206182007Sroberto#else
207182007Sroberto        assert(!"array::at out_of_range");
20854359Sroberto#endif
209280849Scy    return __elems_[__n];
210280849Scy}
211280849Scy
212280849Scytemplate <class _Tp, size_t _Size>
213182007Srobertotypename array<_Tp, _Size>::const_reference
214182007Srobertoarray<_Tp, _Size>::at(size_type __n) const
21554359Sroberto{
216289764Sglebius    if (__n >= _Size)
217182007Sroberto#ifndef _LIBCPP_NO_EXCEPTIONS
21854359Sroberto        throw out_of_range("array::at");
219182007Sroberto#else
22054359Sroberto        assert(!"array::at out_of_range");
221280849Scy#endif
222182007Sroberto    return __elems_[__n];
22354359Sroberto}
22454359Sroberto
225280849Scytemplate <class _Tp, size_t _Size>
226280849Scy_LIBCPP_INLINE_VISIBILITY inline
227182007Srobertobool
228182007Srobertooperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
229182007Sroberto{
230182007Sroberto    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
231182007Sroberto}
232280849Scy
233182007Srobertotemplate <class _Tp, size_t _Size>
234182007Sroberto_LIBCPP_INLINE_VISIBILITY inline
235182007Srobertobool
236182007Srobertooperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
237182007Sroberto{
238280849Scy    return !(__x == __y);
239182007Sroberto}
240182007Sroberto
241182007Srobertotemplate <class _Tp, size_t _Size>
242182007Sroberto_LIBCPP_INLINE_VISIBILITY inline
243182007Srobertobool
244182007Srobertooperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
245182007Sroberto{
246182007Sroberto    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
247182007Sroberto}
248182007Sroberto
249280849Scytemplate <class _Tp, size_t _Size>
250182007Sroberto_LIBCPP_INLINE_VISIBILITY inline
251280849Scybool
252280849Scyoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
253280849Scy{
254280849Scy    return __y < __x;
255280849Scy}
256280849Scy
257280849Scytemplate <class _Tp, size_t _Size>
258280849Scy_LIBCPP_INLINE_VISIBILITY inline
259280849Scybool
260280849Scyoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
261280849Scy{
262280849Scy    return !(__y < __x);
263280849Scy}
264298695Sdelphij
265280849Scytemplate <class _Tp, size_t _Size>
266280849Scy_LIBCPP_INLINE_VISIBILITY inline
267280849Scybool
268280849Scyoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
269280849Scy{
270280849Scy    return !(__x < __y);
271280849Scy}
272280849Scy
273280849Scytemplate <class _Tp, size_t _Size>
274280849Scy_LIBCPP_INLINE_VISIBILITY inline
275280849Scytypename enable_if
276280849Scy<
277298695Sdelphij    __is_swappable<_Tp>::value,
278298695Sdelphij    void
279298695Sdelphij>::type
280298695Sdelphijswap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
281298695Sdelphij                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
282298695Sdelphij{
283280849Scy    __x.swap(__y);
284280849Scy}
285280849Scy
286280849Scytemplate <class _Tp, size_t _Size>
287280849Scyclass _LIBCPP_VISIBLE tuple_size<array<_Tp, _Size> >
288280849Scy    : public integral_constant<size_t, _Size> {};
28954359Sroberto
290280849Scytemplate <class _Tp, size_t _Size>
291182007Srobertoclass _LIBCPP_VISIBLE tuple_size<const array<_Tp, _Size> >
29254359Sroberto    : public integral_constant<size_t, _Size> {};
293182007Sroberto
294280849Scytemplate <size_t _Ip, class _Tp, size_t _Size>
295182007Srobertoclass _LIBCPP_VISIBLE tuple_element<_Ip, array<_Tp, _Size> >
296182007Sroberto{
297182007Srobertopublic:
298182007Sroberto    typedef _Tp type;
299182007Sroberto};
300280849Scy
301182007Srobertotemplate <size_t _Ip, class _Tp, size_t _Size>
302182007Srobertoclass _LIBCPP_VISIBLE tuple_element<_Ip, const array<_Tp, _Size> >
303182007Sroberto{
304182007Srobertopublic:
305280849Scy    typedef const _Tp type;
306280849Scy};
307280849Scy
308280849Scytemplate <size_t _Ip, class _Tp, size_t _Size>
309280849Scy_LIBCPP_INLINE_VISIBILITY inline
310280849Scy_Tp&
311280849Scyget(array<_Tp, _Size>& __a) _NOEXCEPT
312280849Scy{
313280849Scy    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
314280849Scy    return __a[_Ip];
315280849Scy}
316280849Scy
317280849Scytemplate <size_t _Ip, class _Tp, size_t _Size>
318280849Scy_LIBCPP_INLINE_VISIBILITY inline
319280849Scyconst _Tp&
320280849Scyget(const array<_Tp, _Size>& __a) _NOEXCEPT
321280849Scy{
322280849Scy    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
323280849Scy    return __a[_Ip];
324280849Scy}
325280849Scy
326280849Scy#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
327280849Scy
328280849Scytemplate <size_t _Ip, class _Tp, size_t _Size>
329_LIBCPP_INLINE_VISIBILITY inline
330_Tp&&
331get(array<_Tp, _Size>&& __a) _NOEXCEPT
332{
333    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
334    return _VSTD::move(__a[_Ip]);
335}
336
337#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
338
339_LIBCPP_END_NAMESPACE_STD
340
341#endif  // _LIBCPP_ARRAY
342