1// -*- C++ -*- 2//===---------------------------- array -----------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is dual licensed under the MIT and the University of Illinois Open 7// Source Licenses. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_ARRAY 12#define _LIBCPP_ARRAY 13 14/* 15 array synopsis 16 17namespace std 18{ 19template <class T, size_t N > 20struct array 21{ 22 // types: 23 typedef T & reference; 24 typedef const T & const_reference; 25 typedef implementation defined iterator; 26 typedef implementation defined const_iterator; 27 typedef size_t size_type; 28 typedef ptrdiff_t difference_type; 29 typedef T value_type; 30 typedef T* pointer; 31 typedef const T* const_pointer; 32 typedef std::reverse_iterator<iterator> reverse_iterator; 33 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 34 35 // No explicit construct/copy/destroy for aggregate type 36 void fill(const T& u); 37 void swap(array& a) noexcept(is_nothrow_swappable_v<T>); 38 39 // iterators: 40 iterator begin() noexcept; 41 const_iterator begin() const noexcept; 42 iterator end() noexcept; 43 const_iterator end() const noexcept; 44 45 reverse_iterator rbegin() noexcept; 46 const_reverse_iterator rbegin() const noexcept; 47 reverse_iterator rend() noexcept; 48 const_reverse_iterator rend() const noexcept; 49 50 const_iterator cbegin() const noexcept; 51 const_iterator cend() const noexcept; 52 const_reverse_iterator crbegin() const noexcept; 53 const_reverse_iterator crend() const noexcept; 54 55 // capacity: 56 constexpr size_type size() const noexcept; 57 constexpr size_type max_size() const noexcept; 58 constexpr bool empty() const noexcept; 59 60 // element access: 61 reference operator[](size_type n); 62 const_reference operator[](size_type n) const; // constexpr in C++14 63 const_reference at(size_type n) const; // constexpr in C++14 64 reference at(size_type n); 65 66 reference front(); 67 const_reference front() const; // constexpr in C++14 68 reference back(); 69 const_reference back() const; // constexpr in C++14 70 71 T* data() noexcept; 72 const T* data() const noexcept; 73}; 74 75template <class T, size_t N> 76 bool operator==(const array<T,N>& x, const array<T,N>& y); 77template <class T, size_t N> 78 bool operator!=(const array<T,N>& x, const array<T,N>& y); 79template <class T, size_t N> 80 bool operator<(const array<T,N>& x, const array<T,N>& y); 81template <class T, size_t N> 82 bool operator>(const array<T,N>& x, const array<T,N>& y); 83template <class T, size_t N> 84 bool operator<=(const array<T,N>& x, const array<T,N>& y); 85template <class T, size_t N> 86 bool operator>=(const array<T,N>& x, const array<T,N>& y); 87 88template <class T, size_t N > 89 void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); 90 91template <class T> class tuple_size; 92template <size_t I, class T> class tuple_element; 93template <class T, size_t N> struct tuple_size<array<T, N>>; 94template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>; 95template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14 96template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14 97template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14 98template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14 99 100} // std 101 102*/ 103 104#include <__config> 105#include <__tuple> 106#include <type_traits> 107#include <utility> 108#include <iterator> 109#include <algorithm> 110#include <stdexcept> 111 112#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 113#pragma GCC system_header 114#endif 115 116 117 118_LIBCPP_BEGIN_NAMESPACE_STD 119 120template <class _Tp, size_t _Size> 121struct __array_traits { 122 typedef _Tp _StorageT[_Size]; 123 124 _LIBCPP_INLINE_VISIBILITY 125 static _LIBCPP_CONSTEXPR_AFTER_CXX14 typename remove_const<_Tp>::type* 126 __data(typename remove_const<_StorageT>::type& __store) { 127 return __store; 128 } 129 130 _LIBCPP_INLINE_VISIBILITY 131 static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) { 132 return __store; 133 } 134 135 _LIBCPP_INLINE_VISIBILITY 136 static void __swap(_StorageT& __lhs, _StorageT& __rhs) { 137 std::swap_ranges(__lhs, __lhs + _Size, __rhs); 138 } 139 140 _LIBCPP_INLINE_VISIBILITY 141 static void __fill(_StorageT& __arr, _Tp const& __val) { 142 _VSTD::fill_n(__arr, _Size, __val); 143 } 144}; 145 146template <class _Tp> 147struct __array_traits<_Tp, 0> { 148 typedef typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type 149 _NonConstStorageT; 150 typedef typename conditional<is_const<_Tp>::value, const _NonConstStorageT, 151 _NonConstStorageT>::type _StorageT; 152 153 typedef typename remove_const<_Tp>::type _NonConstTp; 154 _LIBCPP_INLINE_VISIBILITY 155 static _NonConstTp* __data(_NonConstStorageT& __store) { 156 _StorageT *__ptr = std::addressof(__store); 157 return reinterpret_cast<_NonConstTp*>(__ptr); 158 } 159 160 _LIBCPP_INLINE_VISIBILITY 161 static const _Tp* __data(const _StorageT& __store) { 162 const _StorageT *__ptr = std::addressof(__store); 163 return reinterpret_cast<const _Tp*>(__ptr); 164 } 165 166 _LIBCPP_INLINE_VISIBILITY 167 static void __swap(_StorageT&, _StorageT&) {} 168 169 _LIBCPP_INLINE_VISIBILITY 170 static void __fill(_StorageT&, _Tp const&) {} 171}; 172 173template <class _Tp, size_t _Size> 174struct _LIBCPP_TEMPLATE_VIS array 175{ 176 // types: 177 typedef array __self; 178 typedef _Tp value_type; 179 typedef value_type& reference; 180 typedef const value_type& const_reference; 181 typedef value_type* iterator; 182 typedef const value_type* const_iterator; 183 typedef value_type* pointer; 184 typedef const value_type* const_pointer; 185 typedef size_t size_type; 186 typedef ptrdiff_t difference_type; 187 typedef std::reverse_iterator<iterator> reverse_iterator; 188 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 189 190 typedef __array_traits<_Tp, _Size> _Traits; 191 typename _Traits::_StorageT __elems_; 192 193 // No explicit construct/copy/destroy for aggregate type 194 _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) { 195 static_assert(_Size != 0 || !is_const<_Tp>::value, 196 "cannot fill zero-sized array of type 'const T'"); 197 _Traits::__fill(__elems_, __u); 198 } 199 200 _LIBCPP_INLINE_VISIBILITY 201 void swap(array& __a) 202 _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) { 203 static_assert(_Size != 0 || !is_const<_Tp>::value, 204 "cannot swap zero-sized array of type 'const T'"); 205 _Traits::__swap(__elems_, __a.__elems_); 206 } 207 208 // iterators: 209 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 210 iterator begin() _NOEXCEPT {return iterator(data());} 211 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 212 const_iterator begin() const _NOEXCEPT {return const_iterator(data());} 213 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 214 iterator end() _NOEXCEPT {return iterator(data() + _Size);} 215 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 216 const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);} 217 218 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 219 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} 220 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 221 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} 222 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 223 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} 224 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 225 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} 226 227 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 228 const_iterator cbegin() const _NOEXCEPT {return begin();} 229 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 230 const_iterator cend() const _NOEXCEPT {return end();} 231 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 232 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} 233 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 234 const_reverse_iterator crend() const _NOEXCEPT {return rend();} 235 236 // capacity: 237 _LIBCPP_INLINE_VISIBILITY 238 _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;} 239 _LIBCPP_INLINE_VISIBILITY 240 _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;} 241 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 242 _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;} 243 244 // element access: 245 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 246 reference operator[](size_type __n) {return __elems_[__n];} 247 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 248 const_reference operator[](size_type __n) const {return __elems_[__n];} 249 250 _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n); 251 _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const; 252 253 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() {return __elems_[0];} 254 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];} 255 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() {return __elems_[_Size > 0 ? _Size-1 : 0];} 256 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} 257 258 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 259 value_type* data() _NOEXCEPT {return _Traits::__data(__elems_);} 260 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 261 const value_type* data() const _NOEXCEPT {return _Traits::__data(__elems_);} 262}; 263 264template <class _Tp, size_t _Size> 265_LIBCPP_CONSTEXPR_AFTER_CXX14 266typename array<_Tp, _Size>::reference 267array<_Tp, _Size>::at(size_type __n) 268{ 269 if (__n >= _Size) 270 __throw_out_of_range("array::at"); 271 272 return __elems_[__n]; 273} 274 275template <class _Tp, size_t _Size> 276_LIBCPP_CONSTEXPR_AFTER_CXX11 277typename array<_Tp, _Size>::const_reference 278array<_Tp, _Size>::at(size_type __n) const 279{ 280 if (__n >= _Size) 281 __throw_out_of_range("array::at"); 282 return __elems_[__n]; 283} 284 285template <class _Tp, size_t _Size> 286inline _LIBCPP_INLINE_VISIBILITY 287bool 288operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 289{ 290 return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_); 291} 292 293template <class _Tp, size_t _Size> 294inline _LIBCPP_INLINE_VISIBILITY 295bool 296operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 297{ 298 return !(__x == __y); 299} 300 301template <class _Tp, size_t _Size> 302inline _LIBCPP_INLINE_VISIBILITY 303bool 304operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 305{ 306 return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size); 307} 308 309template <class _Tp, size_t _Size> 310inline _LIBCPP_INLINE_VISIBILITY 311bool 312operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 313{ 314 return __y < __x; 315} 316 317template <class _Tp, size_t _Size> 318inline _LIBCPP_INLINE_VISIBILITY 319bool 320operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 321{ 322 return !(__y < __x); 323} 324 325template <class _Tp, size_t _Size> 326inline _LIBCPP_INLINE_VISIBILITY 327bool 328operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) 329{ 330 return !(__x < __y); 331} 332 333template <class _Tp, size_t _Size> 334inline _LIBCPP_INLINE_VISIBILITY 335typename enable_if 336< 337 _Size == 0 || 338 __is_swappable<_Tp>::value, 339 void 340>::type 341swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) 342 _NOEXCEPT_(noexcept(__x.swap(__y))) 343{ 344 __x.swap(__y); 345} 346 347template <class _Tp, size_t _Size> 348class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > 349 : public integral_constant<size_t, _Size> {}; 350 351template <size_t _Ip, class _Tp, size_t _Size> 352class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> > 353{ 354 static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)"); 355public: 356 typedef _Tp type; 357}; 358 359template <size_t _Ip, class _Tp, size_t _Size> 360inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 361_Tp& 362get(array<_Tp, _Size>& __a) _NOEXCEPT 363{ 364 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); 365 return __a.__elems_[_Ip]; 366} 367 368template <size_t _Ip, class _Tp, size_t _Size> 369inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 370const _Tp& 371get(const array<_Tp, _Size>& __a) _NOEXCEPT 372{ 373 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); 374 return __a.__elems_[_Ip]; 375} 376 377#ifndef _LIBCPP_CXX03_LANG 378 379template <size_t _Ip, class _Tp, size_t _Size> 380inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 381_Tp&& 382get(array<_Tp, _Size>&& __a) _NOEXCEPT 383{ 384 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); 385 return _VSTD::move(__a.__elems_[_Ip]); 386} 387 388template <size_t _Ip, class _Tp, size_t _Size> 389inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 390const _Tp&& 391get(const array<_Tp, _Size>&& __a) _NOEXCEPT 392{ 393 static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)"); 394 return _VSTD::move(__a.__elems_[_Ip]); 395} 396 397#endif // !_LIBCPP_CXX03_LANG 398 399_LIBCPP_END_NAMESPACE_STD 400 401#endif // _LIBCPP_ARRAY 402