1*38fd1498Szrj// <array> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file include/array 26*38fd1498Szrj * This is a Standard C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_ARRAY 30*38fd1498Szrj#define _GLIBCXX_ARRAY 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#if __cplusplus < 201103L 35*38fd1498Szrj# include <bits/c++0x_warning.h> 36*38fd1498Szrj#else 37*38fd1498Szrj 38*38fd1498Szrj#include <utility> 39*38fd1498Szrj#include <stdexcept> 40*38fd1498Szrj#include <bits/stl_algobase.h> 41*38fd1498Szrj#include <bits/range_access.h> 42*38fd1498Szrj 43*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 44*38fd1498Szrj{ 45*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_CONTAINER 46*38fd1498Szrj 47*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 48*38fd1498Szrj struct __array_traits 49*38fd1498Szrj { 50*38fd1498Szrj typedef _Tp _Type[_Nm]; 51*38fd1498Szrj typedef __is_swappable<_Tp> _Is_swappable; 52*38fd1498Szrj typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable; 53*38fd1498Szrj 54*38fd1498Szrj static constexpr _Tp& 55*38fd1498Szrj _S_ref(const _Type& __t, std::size_t __n) noexcept 56*38fd1498Szrj { return const_cast<_Tp&>(__t[__n]); } 57*38fd1498Szrj 58*38fd1498Szrj static constexpr _Tp* 59*38fd1498Szrj _S_ptr(const _Type& __t) noexcept 60*38fd1498Szrj { return const_cast<_Tp*>(__t); } 61*38fd1498Szrj }; 62*38fd1498Szrj 63*38fd1498Szrj template<typename _Tp> 64*38fd1498Szrj struct __array_traits<_Tp, 0> 65*38fd1498Szrj { 66*38fd1498Szrj struct _Type { }; 67*38fd1498Szrj typedef true_type _Is_swappable; 68*38fd1498Szrj typedef true_type _Is_nothrow_swappable; 69*38fd1498Szrj 70*38fd1498Szrj static constexpr _Tp& 71*38fd1498Szrj _S_ref(const _Type&, std::size_t) noexcept 72*38fd1498Szrj { return *static_cast<_Tp*>(nullptr); } 73*38fd1498Szrj 74*38fd1498Szrj static constexpr _Tp* 75*38fd1498Szrj _S_ptr(const _Type&) noexcept 76*38fd1498Szrj { return nullptr; } 77*38fd1498Szrj }; 78*38fd1498Szrj 79*38fd1498Szrj /** 80*38fd1498Szrj * @brief A standard container for storing a fixed size sequence of elements. 81*38fd1498Szrj * 82*38fd1498Szrj * @ingroup sequences 83*38fd1498Szrj * 84*38fd1498Szrj * Meets the requirements of a <a href="tables.html#65">container</a>, a 85*38fd1498Szrj * <a href="tables.html#66">reversible container</a>, and a 86*38fd1498Szrj * <a href="tables.html#67">sequence</a>. 87*38fd1498Szrj * 88*38fd1498Szrj * Sets support random access iterators. 89*38fd1498Szrj * 90*38fd1498Szrj * @tparam Tp Type of element. Required to be a complete type. 91*38fd1498Szrj * @tparam N Number of elements. 92*38fd1498Szrj */ 93*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 94*38fd1498Szrj struct array 95*38fd1498Szrj { 96*38fd1498Szrj typedef _Tp value_type; 97*38fd1498Szrj typedef value_type* pointer; 98*38fd1498Szrj typedef const value_type* const_pointer; 99*38fd1498Szrj typedef value_type& reference; 100*38fd1498Szrj typedef const value_type& const_reference; 101*38fd1498Szrj typedef value_type* iterator; 102*38fd1498Szrj typedef const value_type* const_iterator; 103*38fd1498Szrj typedef std::size_t size_type; 104*38fd1498Szrj typedef std::ptrdiff_t difference_type; 105*38fd1498Szrj typedef std::reverse_iterator<iterator> reverse_iterator; 106*38fd1498Szrj typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 107*38fd1498Szrj 108*38fd1498Szrj // Support for zero-sized arrays mandatory. 109*38fd1498Szrj typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; 110*38fd1498Szrj typename _AT_Type::_Type _M_elems; 111*38fd1498Szrj 112*38fd1498Szrj // No explicit construct/copy/destroy for aggregate type. 113*38fd1498Szrj 114*38fd1498Szrj // DR 776. 115*38fd1498Szrj void 116*38fd1498Szrj fill(const value_type& __u) 117*38fd1498Szrj { std::fill_n(begin(), size(), __u); } 118*38fd1498Szrj 119*38fd1498Szrj void 120*38fd1498Szrj swap(array& __other) 121*38fd1498Szrj noexcept(_AT_Type::_Is_nothrow_swappable::value) 122*38fd1498Szrj { std::swap_ranges(begin(), end(), __other.begin()); } 123*38fd1498Szrj 124*38fd1498Szrj // Iterators. 125*38fd1498Szrj _GLIBCXX17_CONSTEXPR iterator 126*38fd1498Szrj begin() noexcept 127*38fd1498Szrj { return iterator(data()); } 128*38fd1498Szrj 129*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_iterator 130*38fd1498Szrj begin() const noexcept 131*38fd1498Szrj { return const_iterator(data()); } 132*38fd1498Szrj 133*38fd1498Szrj _GLIBCXX17_CONSTEXPR iterator 134*38fd1498Szrj end() noexcept 135*38fd1498Szrj { return iterator(data() + _Nm); } 136*38fd1498Szrj 137*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_iterator 138*38fd1498Szrj end() const noexcept 139*38fd1498Szrj { return const_iterator(data() + _Nm); } 140*38fd1498Szrj 141*38fd1498Szrj _GLIBCXX17_CONSTEXPR reverse_iterator 142*38fd1498Szrj rbegin() noexcept 143*38fd1498Szrj { return reverse_iterator(end()); } 144*38fd1498Szrj 145*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_reverse_iterator 146*38fd1498Szrj rbegin() const noexcept 147*38fd1498Szrj { return const_reverse_iterator(end()); } 148*38fd1498Szrj 149*38fd1498Szrj _GLIBCXX17_CONSTEXPR reverse_iterator 150*38fd1498Szrj rend() noexcept 151*38fd1498Szrj { return reverse_iterator(begin()); } 152*38fd1498Szrj 153*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_reverse_iterator 154*38fd1498Szrj rend() const noexcept 155*38fd1498Szrj { return const_reverse_iterator(begin()); } 156*38fd1498Szrj 157*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_iterator 158*38fd1498Szrj cbegin() const noexcept 159*38fd1498Szrj { return const_iterator(data()); } 160*38fd1498Szrj 161*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_iterator 162*38fd1498Szrj cend() const noexcept 163*38fd1498Szrj { return const_iterator(data() + _Nm); } 164*38fd1498Szrj 165*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_reverse_iterator 166*38fd1498Szrj crbegin() const noexcept 167*38fd1498Szrj { return const_reverse_iterator(end()); } 168*38fd1498Szrj 169*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_reverse_iterator 170*38fd1498Szrj crend() const noexcept 171*38fd1498Szrj { return const_reverse_iterator(begin()); } 172*38fd1498Szrj 173*38fd1498Szrj // Capacity. 174*38fd1498Szrj constexpr size_type 175*38fd1498Szrj size() const noexcept { return _Nm; } 176*38fd1498Szrj 177*38fd1498Szrj constexpr size_type 178*38fd1498Szrj max_size() const noexcept { return _Nm; } 179*38fd1498Szrj 180*38fd1498Szrj constexpr bool 181*38fd1498Szrj empty() const noexcept { return size() == 0; } 182*38fd1498Szrj 183*38fd1498Szrj // Element access. 184*38fd1498Szrj _GLIBCXX17_CONSTEXPR reference 185*38fd1498Szrj operator[](size_type __n) noexcept 186*38fd1498Szrj { return _AT_Type::_S_ref(_M_elems, __n); } 187*38fd1498Szrj 188*38fd1498Szrj constexpr const_reference 189*38fd1498Szrj operator[](size_type __n) const noexcept 190*38fd1498Szrj { return _AT_Type::_S_ref(_M_elems, __n); } 191*38fd1498Szrj 192*38fd1498Szrj _GLIBCXX17_CONSTEXPR reference 193*38fd1498Szrj at(size_type __n) 194*38fd1498Szrj { 195*38fd1498Szrj if (__n >= _Nm) 196*38fd1498Szrj std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " 197*38fd1498Szrj ">= _Nm (which is %zu)"), 198*38fd1498Szrj __n, _Nm); 199*38fd1498Szrj return _AT_Type::_S_ref(_M_elems, __n); 200*38fd1498Szrj } 201*38fd1498Szrj 202*38fd1498Szrj constexpr const_reference 203*38fd1498Szrj at(size_type __n) const 204*38fd1498Szrj { 205*38fd1498Szrj // Result of conditional expression must be an lvalue so use 206*38fd1498Szrj // boolean ? lvalue : (throw-expr, lvalue) 207*38fd1498Szrj return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) 208*38fd1498Szrj : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " 209*38fd1498Szrj ">= _Nm (which is %zu)"), 210*38fd1498Szrj __n, _Nm), 211*38fd1498Szrj _AT_Type::_S_ref(_M_elems, 0)); 212*38fd1498Szrj } 213*38fd1498Szrj 214*38fd1498Szrj _GLIBCXX17_CONSTEXPR reference 215*38fd1498Szrj front() noexcept 216*38fd1498Szrj { return *begin(); } 217*38fd1498Szrj 218*38fd1498Szrj constexpr const_reference 219*38fd1498Szrj front() const noexcept 220*38fd1498Szrj { return _AT_Type::_S_ref(_M_elems, 0); } 221*38fd1498Szrj 222*38fd1498Szrj _GLIBCXX17_CONSTEXPR reference 223*38fd1498Szrj back() noexcept 224*38fd1498Szrj { return _Nm ? *(end() - 1) : *end(); } 225*38fd1498Szrj 226*38fd1498Szrj constexpr const_reference 227*38fd1498Szrj back() const noexcept 228*38fd1498Szrj { 229*38fd1498Szrj return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) 230*38fd1498Szrj : _AT_Type::_S_ref(_M_elems, 0); 231*38fd1498Szrj } 232*38fd1498Szrj 233*38fd1498Szrj _GLIBCXX17_CONSTEXPR pointer 234*38fd1498Szrj data() noexcept 235*38fd1498Szrj { return _AT_Type::_S_ptr(_M_elems); } 236*38fd1498Szrj 237*38fd1498Szrj _GLIBCXX17_CONSTEXPR const_pointer 238*38fd1498Szrj data() const noexcept 239*38fd1498Szrj { return _AT_Type::_S_ptr(_M_elems); } 240*38fd1498Szrj }; 241*38fd1498Szrj 242*38fd1498Szrj#if __cpp_deduction_guides >= 201606 243*38fd1498Szrj template<typename _Tp, typename... _Up> 244*38fd1498Szrj array(_Tp, _Up...) 245*38fd1498Szrj -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>, 246*38fd1498Szrj 1 + sizeof...(_Up)>; 247*38fd1498Szrj#endif 248*38fd1498Szrj 249*38fd1498Szrj // Array comparisons. 250*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 251*38fd1498Szrj inline bool 252*38fd1498Szrj operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 253*38fd1498Szrj { return std::equal(__one.begin(), __one.end(), __two.begin()); } 254*38fd1498Szrj 255*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 256*38fd1498Szrj inline bool 257*38fd1498Szrj operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 258*38fd1498Szrj { return !(__one == __two); } 259*38fd1498Szrj 260*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 261*38fd1498Szrj inline bool 262*38fd1498Szrj operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 263*38fd1498Szrj { 264*38fd1498Szrj return std::lexicographical_compare(__a.begin(), __a.end(), 265*38fd1498Szrj __b.begin(), __b.end()); 266*38fd1498Szrj } 267*38fd1498Szrj 268*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 269*38fd1498Szrj inline bool 270*38fd1498Szrj operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 271*38fd1498Szrj { return __two < __one; } 272*38fd1498Szrj 273*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 274*38fd1498Szrj inline bool 275*38fd1498Szrj operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 276*38fd1498Szrj { return !(__one > __two); } 277*38fd1498Szrj 278*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 279*38fd1498Szrj inline bool 280*38fd1498Szrj operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 281*38fd1498Szrj { return !(__one < __two); } 282*38fd1498Szrj 283*38fd1498Szrj // Specialized algorithms. 284*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 285*38fd1498Szrj inline 286*38fd1498Szrj#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 287*38fd1498Szrj // Constrained free swap overload, see p0185r1 288*38fd1498Szrj typename enable_if< 289*38fd1498Szrj _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value 290*38fd1498Szrj >::type 291*38fd1498Szrj#else 292*38fd1498Szrj void 293*38fd1498Szrj#endif 294*38fd1498Szrj swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 295*38fd1498Szrj noexcept(noexcept(__one.swap(__two))) 296*38fd1498Szrj { __one.swap(__two); } 297*38fd1498Szrj 298*38fd1498Szrj#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 299*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 300*38fd1498Szrj typename enable_if< 301*38fd1498Szrj !_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type 302*38fd1498Szrj swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete; 303*38fd1498Szrj#endif 304*38fd1498Szrj 305*38fd1498Szrj template<std::size_t _Int, typename _Tp, std::size_t _Nm> 306*38fd1498Szrj constexpr _Tp& 307*38fd1498Szrj get(array<_Tp, _Nm>& __arr) noexcept 308*38fd1498Szrj { 309*38fd1498Szrj static_assert(_Int < _Nm, "array index is within bounds"); 310*38fd1498Szrj return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: 311*38fd1498Szrj _S_ref(__arr._M_elems, _Int); 312*38fd1498Szrj } 313*38fd1498Szrj 314*38fd1498Szrj template<std::size_t _Int, typename _Tp, std::size_t _Nm> 315*38fd1498Szrj constexpr _Tp&& 316*38fd1498Szrj get(array<_Tp, _Nm>&& __arr) noexcept 317*38fd1498Szrj { 318*38fd1498Szrj static_assert(_Int < _Nm, "array index is within bounds"); 319*38fd1498Szrj return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); 320*38fd1498Szrj } 321*38fd1498Szrj 322*38fd1498Szrj template<std::size_t _Int, typename _Tp, std::size_t _Nm> 323*38fd1498Szrj constexpr const _Tp& 324*38fd1498Szrj get(const array<_Tp, _Nm>& __arr) noexcept 325*38fd1498Szrj { 326*38fd1498Szrj static_assert(_Int < _Nm, "array index is within bounds"); 327*38fd1498Szrj return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: 328*38fd1498Szrj _S_ref(__arr._M_elems, _Int); 329*38fd1498Szrj } 330*38fd1498Szrj 331*38fd1498Szrj template<std::size_t _Int, typename _Tp, std::size_t _Nm> 332*38fd1498Szrj constexpr const _Tp&& 333*38fd1498Szrj get(const array<_Tp, _Nm>&& __arr) noexcept 334*38fd1498Szrj { 335*38fd1498Szrj static_assert(_Int < _Nm, "array index is within bounds"); 336*38fd1498Szrj return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); 337*38fd1498Szrj } 338*38fd1498Szrj 339*38fd1498Szrj_GLIBCXX_END_NAMESPACE_CONTAINER 340*38fd1498Szrj} // namespace std 341*38fd1498Szrj 342*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 343*38fd1498Szrj{ 344*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 345*38fd1498Szrj 346*38fd1498Szrj // Tuple interface to class template array. 347*38fd1498Szrj 348*38fd1498Szrj /// tuple_size 349*38fd1498Szrj template<typename _Tp> 350*38fd1498Szrj struct tuple_size; 351*38fd1498Szrj 352*38fd1498Szrj /// Partial specialization for std::array 353*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 354*38fd1498Szrj struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>> 355*38fd1498Szrj : public integral_constant<std::size_t, _Nm> { }; 356*38fd1498Szrj 357*38fd1498Szrj /// tuple_element 358*38fd1498Szrj template<std::size_t _Int, typename _Tp> 359*38fd1498Szrj struct tuple_element; 360*38fd1498Szrj 361*38fd1498Szrj /// Partial specialization for std::array 362*38fd1498Szrj template<std::size_t _Int, typename _Tp, std::size_t _Nm> 363*38fd1498Szrj struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>> 364*38fd1498Szrj { 365*38fd1498Szrj static_assert(_Int < _Nm, "index is out of bounds"); 366*38fd1498Szrj typedef _Tp type; 367*38fd1498Szrj }; 368*38fd1498Szrj 369*38fd1498Szrj template<typename _Tp, std::size_t _Nm> 370*38fd1498Szrj struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type 371*38fd1498Szrj { }; 372*38fd1498Szrj 373*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 374*38fd1498Szrj} // namespace std 375*38fd1498Szrj 376*38fd1498Szrj#ifdef _GLIBCXX_DEBUG 377*38fd1498Szrj# include <debug/array> 378*38fd1498Szrj#endif 379*38fd1498Szrj 380*38fd1498Szrj#ifdef _GLIBCXX_PROFILE 381*38fd1498Szrj# include <profile/array> 382*38fd1498Szrj#endif 383*38fd1498Szrj 384*38fd1498Szrj#endif // C++11 385*38fd1498Szrj 386*38fd1498Szrj#endif // _GLIBCXX_ARRAY 387