array revision 227825
1139823Simp// -*- C++ -*- 2133920Sandre//===---------------------------- array -----------------------------------===// 3133920Sandre// 4133920Sandre// The LLVM Compiler Infrastructure 5133920Sandre// 6133920Sandre// This file is dual licensed under the MIT and the University of Illinois Open 7133920Sandre// Source Licenses. See LICENSE.TXT for details. 8133920Sandre// 9133920Sandre//===----------------------------------------------------------------------===// 10133920Sandre 11133920Sandre#ifndef _LIBCPP_ARRAY 12133920Sandre#define _LIBCPP_ARRAY 13133920Sandre 14133920Sandre/* 15133920Sandre array synopsis 16133920Sandre 17133920Sandrenamespace std 18133920Sandre{ 19133920Sandretemplate <class T, size_t N > 20133920Sandrestruct array 21133920Sandre{ 22133920Sandre // types: 23133920Sandre typedef T & reference; 24133920Sandre typedef const T & const_reference; 25133920Sandre typedef implementation defined iterator; 26133920Sandre typedef implementation defined const_iterator; 27172467Ssilby typedef size_t size_type; 28172467Ssilby typedef ptrdiff_t difference_type; 29172467Ssilby typedef T value_type; 30134346Sru typedef T* pointer; 31133920Sandre typedef const T* const_pointer; 32133920Sandre typedef std::reverse_iterator<iterator> reverse_iterator; 33133920Sandre typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 34133920Sandre 35133920Sandre // No explicit construct/copy/destroy for aggregate type 36133920Sandre void fill(const T& u); 37134383Sandre void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>()))); 38152928Sume 39133920Sandre // iterators: 40133920Sandre iterator begin() noexcept; 41133920Sandre const_iterator begin() const noexcept; 42133920Sandre iterator end() noexcept; 43133920Sandre const_iterator end() const noexcept; 44133920Sandre 45133920Sandre reverse_iterator rbegin() noexcept; 46185895Szec const_reverse_iterator rbegin() const noexcept; 47185895Szec reverse_iterator rend() noexcept; 48133920Sandre const_reverse_iterator rend() const noexcept; 49133920Sandre 50133920Sandre const_iterator cbegin() const noexcept; 51133920Sandre const_iterator cend() const noexcept; 52133920Sandre const_reverse_iterator crbegin() const noexcept; 53133920Sandre const_reverse_iterator crend() const noexcept; 54133920Sandre 55133920Sandre // capacity: 56196423Sjulian constexpr size_type size() const noexcept; 57133920Sandre constexpr size_type max_size() const noexcept; 58133920Sandre bool empty() const noexcept; 59133920Sandre 60133920Sandre // element access: 61133920Sandre reference operator[](size_type n); 62133920Sandre const_reference operator[](size_type n) const; 63133920Sandre const_reference at(size_type n) const; 64133920Sandre reference at(size_type n); 65133920Sandre 66141351Sglebius reference front(); 67141351Sglebius const_reference front() const; 68133920Sandre reference back(); 69133920Sandre const_reference back() const; 70195699Srwatson 71158470Smlaier T* data() noexcept; 72195699Srwatson const T* data() const noexcept; 73158470Smlaier}; 74133920Sandre 75158470Smlaiertemplate <class T, size_t N> 76158470Smlaier bool operator==(const array<T,N>& x, const array<T,N>& y); 77136714Sandretemplate <class T, size_t N> 78136714Sandre bool operator!=(const array<T,N>& x, const array<T,N>& y); 79136714Sandretemplate <class T, size_t N> 80141351Sglebius bool operator<(const array<T,N>& x, const array<T,N>& y); 81141351Sglebiustemplate <class T, size_t N> 82141351Sglebius bool operator>(const array<T,N>& x, const array<T,N>& y); 83136714Sandretemplate <class T, size_t N> 84136714Sandre bool operator<=(const array<T,N>& x, const array<T,N>& y); 85133920Sandretemplate <class T, size_t N> 86133920Sandre bool operator>=(const array<T,N>& x, const array<T,N>& y); 87133920Sandre 88133920Sandretemplate <class T, size_t N > 89135920Smlaier void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); 90135920Smlaier 91133920Sandretemplate <class T> class tuple_size; 92133920Sandretemplate <int I, class T> class tuple_element; 93141351Sglebiustemplate <class T, size_t N> struct tuple_size<array<T, N>>; 94133920Sandretemplate <int I, class T, size_t N> struct tuple_element<I, array<T, N>>; 95133920Sandretemplate <int I, class T, size_t N> T& get(array<T, N>&) noexcept; 96133920Sandretemplate <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; 97140224Sglebiustemplate <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; 98133920Sandre 99133920Sandre} // std 100133920Sandre 101133920Sandre*/ 102133920Sandre 103133920Sandre#include <__config> 104133920Sandre#include <__tuple> 105133920Sandre#include <type_traits> 106173399Soleg#include <utility> 107173399Soleg#include <iterator> 108173399Soleg#include <algorithm> 109173399Soleg#include <stdexcept> 110173399Soleg#if defined(_LIBCPP_NO_EXCEPTIONS) 111173399Soleg #include <cassert> 112193859Soleg#endif 113193859Soleg 114173399Soleg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 115173399Soleg#pragma GCC system_header 116173399Soleg#endif 117173399Soleg 118138652Sglebius_LIBCPP_BEGIN_NAMESPACE_STD 119138652Sglebius 120133920Sandretemplate <class _Tp, size_t _Size> 121133920Sandrestruct _LIBCPP_VISIBLE array 122133920Sandre{ 123133920Sandre // types: 124193859Soleg typedef array __self; 125193859Soleg typedef _Tp value_type; 126133920Sandre typedef value_type& reference; 127133920Sandre typedef const value_type& const_reference; 128133920Sandre typedef value_type* iterator; 129133920Sandre typedef const value_type* const_iterator; 130133920Sandre typedef value_type* pointer; 131135920Smlaier typedef const value_type* const_pointer; 132140224Sglebius typedef size_t size_type; 133133920Sandre typedef ptrdiff_t difference_type; 134191570Soleg typedef std::reverse_iterator<iterator> reverse_iterator; 135191570Soleg typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 136191570Soleg 137191570Soleg value_type __elems_[_Size > 0 ? _Size : 1]; 138191570Soleg 139191570Soleg // No explicit construct/copy/destroy for aggregate type 140140224Sglebius _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) 141140224Sglebius {_VSTD::fill_n(__elems_, _Size, __u);} 142133920Sandre _LIBCPP_INLINE_VISIBILITY 143140224Sglebius void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 144140224Sglebius {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} 145140224Sglebius 146140224Sglebius // iterators: 147133920Sandre _LIBCPP_INLINE_VISIBILITY 148133920Sandre iterator begin() _NOEXCEPT {return iterator(__elems_);} 149133920Sandre _LIBCPP_INLINE_VISIBILITY 150133920Sandre const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} 151133920Sandre _LIBCPP_INLINE_VISIBILITY 152133920Sandre iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} 153133920Sandre _LIBCPP_INLINE_VISIBILITY 154133920Sandre const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} 155133920Sandre 156133920Sandre _LIBCPP_INLINE_VISIBILITY 157133920Sandre reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} 158133920Sandre _LIBCPP_INLINE_VISIBILITY 159133920Sandre const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} 160140224Sglebius _LIBCPP_INLINE_VISIBILITY 161133920Sandre reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} 162140224Sglebius _LIBCPP_INLINE_VISIBILITY 163140224Sglebius const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} 164140224Sglebius 165140224Sglebius _LIBCPP_INLINE_VISIBILITY 166140224Sglebius const_iterator cbegin() const _NOEXCEPT {return begin();} 167193502Sluigi _LIBCPP_INLINE_VISIBILITY 168140224Sglebius const_iterator cend() const _NOEXCEPT {return end();} 169145246Sbrooks _LIBCPP_INLINE_VISIBILITY 170173399Soleg const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} 171145246Sbrooks _LIBCPP_INLINE_VISIBILITY 172173399Soleg const_reverse_iterator crend() const _NOEXCEPT {return rend();} 173173399Soleg 174173399Soleg // capacity: 175140224Sglebius _LIBCPP_INLINE_VISIBILITY 176140224Sglebius /*constexpr*/ size_type size() const _NOEXCEPT {return _Size;} 177140224Sglebius _LIBCPP_INLINE_VISIBILITY 178140224Sglebius /*constexpr*/ size_type max_size() const _NOEXCEPT {return _Size;} 179140224Sglebius _LIBCPP_INLINE_VISIBILITY 180140224Sglebius bool empty() const _NOEXCEPT {return _Size == 0;} 181140224Sglebius 182140224Sglebius // element access: 183140224Sglebius _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __elems_[__n];} 184140224Sglebius _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __elems_[__n];} 185140224Sglebius reference at(size_type __n); 186144712Sglebius const_reference at(size_type __n) const; 187144712Sglebius 188140224Sglebius _LIBCPP_INLINE_VISIBILITY reference front() {return __elems_[0];} 189144712Sglebius _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __elems_[0];} 190140224Sglebius _LIBCPP_INLINE_VISIBILITY reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} 191141351Sglebius _LIBCPP_INLINE_VISIBILITY const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} 192141351Sglebius 193141351Sglebius _LIBCPP_INLINE_VISIBILITY 194141351Sglebius value_type* data() _NOEXCEPT {return __elems_;} 195141351Sglebius _LIBCPP_INLINE_VISIBILITY 196141351Sglebius const value_type* data() const _NOEXCEPT {return __elems_;} 197141351Sglebius}; 198141351Sglebius 199141351Sglebiustemplate <class _Tp, size_t _Size> 200141351Sglebiustypename array<_Tp, _Size>::reference 201165648Spisoarray<_Tp, _Size>::at(size_type __n) 202165648Spiso{ 203165648Spiso if (__n >= _Size) 204141351Sglebius#ifndef _LIBCPP_NO_EXCEPTIONS 205190633Spiso throw out_of_range("array::at"); 206190633Spiso#else 207190633Spiso assert(!"array::at out_of_range"); 208140224Sglebius#endif 209140224Sglebius return __elems_[__n]; 210140224Sglebius} 211140224Sglebius 212133920Sandretemplate <class _Tp, size_t _Size> 213133920Sandretypename array<_Tp, _Size>::const_reference 214133920Sandrearray<_Tp, _Size>::at(size_type __n) const 215133920Sandre{ 216133920Sandre if (__n >= _Size) 217133920Sandre#ifndef _LIBCPP_NO_EXCEPTIONS 218133920Sandre throw out_of_range("array::at"); 219133920Sandre#else 220133920Sandre assert(!"array::at out_of_range"); 221133920Sandre#endif 222135920Smlaier return __elems_[__n]; 223135920Smlaier} 224133920Sandre 225133920Sandretemplate <class _Tp, size_t _Size> 226141351Sglebius_LIBCPP_INLINE_VISIBILITY inline 227133920Sandrebool 228133920Sandreoperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 229133920Sandre{ 230140224Sglebius return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_); 231133920Sandre} 232133920Sandre 233133920Sandretemplate <class _Tp, size_t _Size> 234133920Sandre_LIBCPP_INLINE_VISIBILITY inline 235133920Sandrebool 236133920Sandreoperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 237133920Sandre{ 238133920Sandre return !(__x == __y); 239173399Soleg} 240173399Soleg 241173399Solegtemplate <class _Tp, size_t _Size> 242173399Soleg_LIBCPP_INLINE_VISIBILITY inline 243173399Solegbool 244173399Solegoperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 245193859Soleg{ 246193859Soleg return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size); 247173399Soleg} 248173399Soleg 249173399Solegtemplate <class _Tp, size_t _Size> 250173399Soleg_LIBCPP_INLINE_VISIBILITY inline 251138652Sglebiusbool 252138652Sglebiusoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 253133920Sandre{ 254133920Sandre return __y < __x; 255133920Sandre} 256133920Sandre 257193859Solegtemplate <class _Tp, size_t _Size> 258193859Soleg_LIBCPP_INLINE_VISIBILITY inline 259133920Sandrebool 260133920Sandreoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 261133920Sandre{ 262133920Sandre return !(__y < __x); 263133920Sandre} 264133920Sandre 265135920Smlaiertemplate <class _Tp, size_t _Size> 266140224Sglebius_LIBCPP_INLINE_VISIBILITY inline 267133920Sandrebool 268191570Solegoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 269191570Soleg{ 270191570Soleg return !(__x < __y); 271191570Soleg} 272191570Soleg 273191570Solegtemplate <class _Tp, size_t _Size> 274140224Sglebius_LIBCPP_INLINE_VISIBILITY inline 275140224Sglebiustypename enable_if 276133920Sandre< 277140224Sglebius __is_swappable<_Tp>::value, 278140224Sglebius void 279140224Sglebius>::type 280140224Sglebiusswap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 281133920Sandre _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 282133920Sandre{ 283133920Sandre __x.swap(__y); 284135167Sandre} 285133920Sandre 286133920Sandretemplate <class _Tp, size_t _Size> 287135167Sandreclass _LIBCPP_VISIBLE tuple_size<array<_Tp, _Size> > 288135167Sandre : public integral_constant<size_t, _Size> {}; 289135167Sandre 290135167Sandretemplate <class _Tp, size_t _Size> 291133920Sandreclass _LIBCPP_VISIBLE tuple_size<const array<_Tp, _Size> > 292133920Sandre : public integral_constant<size_t, _Size> {}; 293133920Sandre 294133920Sandretemplate <size_t _Ip, class _Tp, size_t _Size> 295133920Sandreclass _LIBCPP_VISIBLE tuple_element<_Ip, array<_Tp, _Size> > 296133920Sandre{ 297133920Sandrepublic: 298140224Sglebius typedef _Tp type; 299133920Sandre}; 300140224Sglebius 301140224Sglebiustemplate <size_t _Ip, class _Tp, size_t _Size> 302140224Sglebiusclass _LIBCPP_VISIBLE tuple_element<_Ip, const array<_Tp, _Size> > 303140224Sglebius{ 304140224Sglebiuspublic: 305193502Sluigi typedef const _Tp type; 306140224Sglebius}; 307145246Sbrooks 308173399Solegtemplate <size_t _Ip, class _Tp, size_t _Size> 309145246Sbrooks_LIBCPP_INLINE_VISIBILITY inline 310173399Soleg_Tp& 311173399Solegget(array<_Tp, _Size>& __a) _NOEXCEPT 312173399Soleg{ 313140224Sglebius return __a[_Ip]; 314140224Sglebius} 315140224Sglebius 316140224Sglebiustemplate <size_t _Ip, class _Tp, size_t _Size> 317140224Sglebius_LIBCPP_INLINE_VISIBILITY inline 318140224Sglebiusconst _Tp& 319140224Sglebiusget(const array<_Tp, _Size>& __a) _NOEXCEPT 320140224Sglebius{ 321140224Sglebius return __a[_Ip]; 322140224Sglebius} 323140224Sglebius 324140224Sglebius#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 325140224Sglebius 326144712Sglebiustemplate <size_t _Ip, class _Tp, size_t _Size> 327144712Sglebius_LIBCPP_INLINE_VISIBILITY inline 328140224Sglebius_Tp&& 329144712Sglebiusget(array<_Tp, _Size>&& __a) _NOEXCEPT 330140224Sglebius{ 331141351Sglebius return _VSTD::move(__a[_Ip]); 332141351Sglebius} 333141351Sglebius 334141351Sglebius#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 335141351Sglebius 336141351Sglebius_LIBCPP_END_NAMESPACE_STD 337141351Sglebius 338141351Sglebius#endif // _LIBCPP_ARRAY 339141351Sglebius