1// class template array -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file tr1_impl/array 26 * This is an internal header file, included by other library headers. 27 * You should not attempt to use it directly. 28 */ 29 30namespace std 31{ 32_GLIBCXX_BEGIN_NAMESPACE_TR1 33 34 /** 35 * @brief A standard container for storing a fixed size sequence of elements. 36 * 37 * @ingroup sequences 38 * 39 * Meets the requirements of a <a href="tables.html#65">container</a>, a 40 * <a href="tables.html#66">reversible container</a>, and a 41 * <a href="tables.html#67">sequence</a>. 42 * 43 * Sets support random access iterators. 44 * 45 * @param Tp Type of element. Required to be a complete type. 46 * @param N Number of elements. 47 */ 48 template<typename _Tp, std::size_t _Nm> 49 struct array 50 { 51 typedef _Tp value_type; 52#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 53 typedef _Tp* pointer; 54 typedef const _Tp* const_pointer; 55#endif 56 typedef value_type& reference; 57 typedef const value_type& const_reference; 58 typedef value_type* iterator; 59 typedef const value_type* const_iterator; 60 typedef std::size_t size_type; 61 typedef std::ptrdiff_t difference_type; 62 typedef std::reverse_iterator<iterator> reverse_iterator; 63 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 64 65 // Support for zero-sized arrays mandatory. 66 value_type _M_instance[_Nm ? _Nm : 1]; 67 68 // No explicit construct/copy/destroy for aggregate type. 69 70 void 71#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 72 // DR 776. 73 fill(const value_type& __u) 74#else 75 assign(const value_type& __u) 76#endif 77 { std::fill_n(begin(), size(), __u); } 78 79 void 80 swap(array& __other) 81 { std::swap_ranges(begin(), end(), __other.begin()); } 82 83 // Iterators. 84 iterator 85 begin() 86 { return iterator(&_M_instance[0]); } 87 88 const_iterator 89 begin() const 90 { return const_iterator(&_M_instance[0]); } 91 92 iterator 93 end() 94 { return iterator(&_M_instance[_Nm]); } 95 96 const_iterator 97 end() const 98 { return const_iterator(&_M_instance[_Nm]); } 99 100 reverse_iterator 101 rbegin() 102 { return reverse_iterator(end()); } 103 104 const_reverse_iterator 105 rbegin() const 106 { return const_reverse_iterator(end()); } 107 108 reverse_iterator 109 rend() 110 { return reverse_iterator(begin()); } 111 112 const_reverse_iterator 113 rend() const 114 { return const_reverse_iterator(begin()); } 115 116#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 117 const_iterator 118 cbegin() const 119 { return const_iterator(&_M_instance[0]); } 120 121 const_iterator 122 cend() const 123 { return const_iterator(&_M_instance[_Nm]); } 124 125 const_reverse_iterator 126 crbegin() const 127 { return const_reverse_iterator(end()); } 128 129 const_reverse_iterator 130 crend() const 131 { return const_reverse_iterator(begin()); } 132#endif 133 134 // Capacity. 135 size_type 136 size() const { return _Nm; } 137 138 size_type 139 max_size() const { return _Nm; } 140 141 bool 142 empty() const { return size() == 0; } 143 144 // Element access. 145 reference 146 operator[](size_type __n) 147 { return _M_instance[__n]; } 148 149 const_reference 150 operator[](size_type __n) const 151 { return _M_instance[__n]; } 152 153 reference 154 at(size_type __n) 155 { 156 if (__n >= _Nm) 157 std::__throw_out_of_range(__N("array::at")); 158 return _M_instance[__n]; 159 } 160 161 const_reference 162 at(size_type __n) const 163 { 164 if (__n >= _Nm) 165 std::__throw_out_of_range(__N("array::at")); 166 return _M_instance[__n]; 167 } 168 169 reference 170 front() 171 { return *begin(); } 172 173 const_reference 174 front() const 175 { return *begin(); } 176 177 reference 178 back() 179 { return _Nm ? *(end() - 1) : *end(); } 180 181 const_reference 182 back() const 183 { return _Nm ? *(end() - 1) : *end(); } 184 185 _Tp* 186 data() 187 { return &_M_instance[0]; } 188 189 const _Tp* 190 data() const 191 { return &_M_instance[0]; } 192 }; 193 194 // Array comparisons. 195 template<typename _Tp, std::size_t _Nm> 196 inline bool 197 operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 198 { return std::equal(__one.begin(), __one.end(), __two.begin()); } 199 200 template<typename _Tp, std::size_t _Nm> 201 inline bool 202 operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 203 { return !(__one == __two); } 204 205 template<typename _Tp, std::size_t _Nm> 206 inline bool 207 operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 208 { 209 return std::lexicographical_compare(__a.begin(), __a.end(), 210 __b.begin(), __b.end()); 211 } 212 213 template<typename _Tp, std::size_t _Nm> 214 inline bool 215 operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 216 { return __two < __one; } 217 218 template<typename _Tp, std::size_t _Nm> 219 inline bool 220 operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 221 { return !(__one > __two); } 222 223 template<typename _Tp, std::size_t _Nm> 224 inline bool 225 operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 226 { return !(__one < __two); } 227 228 // Specialized algorithms [6.2.2.2]. 229 template<typename _Tp, std::size_t _Nm> 230 inline void 231 swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 232 { __one.swap(__two); } 233 234 // Tuple interface to class template array [6.2.2.5]. 235 236 /// tuple_size 237 template<typename _Tp> 238 class tuple_size; 239 240 /// tuple_element 241#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 242 template<std::size_t _Int, typename _Tp> 243#else 244 template<int _Int, typename _Tp> 245#endif 246 class tuple_element; 247 248 template<typename _Tp, std::size_t _Nm> 249 struct tuple_size<array<_Tp, _Nm> > 250#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 251 { static const std::size_t value = _Nm; }; 252#else 253 { static const int value = _Nm; }; 254#endif 255 256 template<typename _Tp, std::size_t _Nm> 257#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 258 const std::size_t 259#else 260 const int 261#endif 262 tuple_size<array<_Tp, _Nm> >::value; 263 264#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 265 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 266#else 267 template<int _Int, typename _Tp, std::size_t _Nm> 268#endif 269 struct tuple_element<_Int, array<_Tp, _Nm> > 270 { typedef _Tp type; }; 271 272#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 273 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 274#else 275 template<int _Int, typename _Tp, std::size_t _Nm> 276#endif 277 inline _Tp& 278 get(array<_Tp, _Nm>& __arr) 279 { return __arr[_Int]; } 280 281#ifdef _GLIBCXX_INCLUDE_AS_CXX0X 282 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 283#else 284 template<int _Int, typename _Tp, std::size_t _Nm> 285#endif 286 inline const _Tp& 287 get(const array<_Tp, _Nm>& __arr) 288 { return __arr[_Int]; } 289 290_GLIBCXX_END_NAMESPACE_TR1 291} 292