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