1 // class template array -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009 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 30 namespace 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 typedef value_type& reference; 53 typedef const value_type& const_reference; 54 typedef value_type* iterator; 55 typedef const value_type* const_iterator; 56 typedef std::size_t size_type; 57 typedef std::ptrdiff_t difference_type; 58 typedef std::reverse_iterator<iterator> reverse_iterator; 59 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 60 61 // Support for zero-sized arrays mandatory. 62 value_type _M_instance[_Nm ? _Nm : 1]; 63 64 // No explicit construct/copy/destroy for aggregate type. 65 66 void 67 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 68 // DR 776. 69 fill(const value_type& __u) 70 #else 71 assign(const value_type& __u) 72 #endif 73 { std::fill_n(begin(), size(), __u); } 74 75 void 76 swap(array& __other) 77 { std::swap_ranges(begin(), end(), __other.begin()); } 78 79 // Iterators. 80 iterator 81 begin() 82 { return iterator(&_M_instance[0]); } 83 84 const_iterator 85 begin() const 86 { return const_iterator(&_M_instance[0]); } 87 88 iterator 89 end() 90 { return iterator(&_M_instance[_Nm]); } 91 92 const_iterator 93 end() const 94 { return const_iterator(&_M_instance[_Nm]); } 95 96 reverse_iterator 97 rbegin() 98 { return reverse_iterator(end()); } 99 100 const_reverse_iterator 101 rbegin() const 102 { return const_reverse_iterator(end()); } 103 104 reverse_iterator 105 rend() 106 { return reverse_iterator(begin()); } 107 108 const_reverse_iterator 109 rend() const 110 { return const_reverse_iterator(begin()); } 111 112 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 113 const_iterator 114 cbegin() const 115 { return const_iterator(&_M_instance[0]); } 116 117 const_iterator 118 cend() const 119 { return const_iterator(&_M_instance[_Nm]); } 120 121 const_reverse_iterator 122 crbegin() const 123 { return const_reverse_iterator(end()); } 124 125 const_reverse_iterator 126 crend() const 127 { return const_reverse_iterator(begin()); } 128 #endif 129 130 // Capacity. 131 size_type 132 size() const { return _Nm; } 133 134 size_type 135 max_size() const { return _Nm; } 136 137 bool 138 empty() const { return size() == 0; } 139 140 // Element access. 141 reference 142 operator[](size_type __n) 143 { return _M_instance[__n]; } 144 145 const_reference 146 operator[](size_type __n) const 147 { return _M_instance[__n]; } 148 149 reference 150 at(size_type __n) 151 { 152 if (__builtin_expect(__n >= _Nm, false)) 153 std::__throw_out_of_range(__N("array::at")); 154 return _M_instance[__n]; 155 } 156 157 const_reference 158 at(size_type __n) const 159 { 160 if (__builtin_expect(__n >= _Nm, false)) 161 std::__throw_out_of_range(__N("array::at")); 162 return _M_instance[__n]; 163 } 164 165 reference 166 front() 167 { return *begin(); } 168 169 const_reference 170 front() const 171 { return *begin(); } 172 173 reference 174 back() 175 { return _Nm ? *(end() - 1) : *end(); } 176 177 const_reference 178 back() const 179 { return _Nm ? *(end() - 1) : *end(); } 180 181 _Tp* 182 data() 183 { return &_M_instance[0]; } 184 185 const _Tp* 186 data() const 187 { return &_M_instance[0]; } 188 }; 189 190 // Array comparisons. 191 template<typename _Tp, std::size_t _Nm> 192 inline bool 193 operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 194 { return std::equal(__one.begin(), __one.end(), __two.begin()); } 195 196 template<typename _Tp, std::size_t _Nm> 197 inline bool 198 operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 199 { return !(__one == __two); } 200 201 template<typename _Tp, std::size_t _Nm> 202 inline bool 203 operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 204 { 205 return std::lexicographical_compare(__a.begin(), __a.end(), 206 __b.begin(), __b.end()); 207 } 208 209 template<typename _Tp, std::size_t _Nm> 210 inline bool 211 operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 212 { return __two < __one; } 213 214 template<typename _Tp, std::size_t _Nm> 215 inline bool 216 operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 217 { return !(__one > __two); } 218 219 template<typename _Tp, std::size_t _Nm> 220 inline bool 221 operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 222 { return !(__one < __two); } 223 224 // Specialized algorithms [6.2.2.2]. 225 template<typename _Tp, std::size_t _Nm> 226 inline void 227 swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 228 { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); } 229 230 // Tuple interface to class template array [6.2.2.5]. 231 232 /// tuple_size 233 template<typename _Tp> 234 class tuple_size; 235 236 /// tuple_element 237 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 238 template<std::size_t _Int, typename _Tp> 239 #else 240 template<int _Int, typename _Tp> 241 #endif 242 class tuple_element; 243 244 template<typename _Tp, std::size_t _Nm> 245 struct tuple_size<array<_Tp, _Nm> > 246 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 247 { static const std::size_t value = _Nm; }; 248 #else 249 { static const int value = _Nm; }; 250 #endif 251 252 template<typename _Tp, std::size_t _Nm> 253 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 254 const std::size_t 255 #else 256 const int 257 #endif 258 tuple_size<array<_Tp, _Nm> >::value; 259 260 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 261 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 262 #else 263 template<int _Int, typename _Tp, std::size_t _Nm> 264 #endif 265 struct tuple_element<_Int, array<_Tp, _Nm> > 266 { typedef _Tp type; }; 267 268 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 269 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 270 #else 271 template<int _Int, typename _Tp, std::size_t _Nm> 272 #endif 273 inline _Tp& 274 get(array<_Tp, _Nm>& __arr) 275 { return __arr[_Int]; } 276 277 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 278 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 279 #else 280 template<int _Int, typename _Tp, std::size_t _Nm> 281 #endif 282 inline const _Tp& 283 get(const array<_Tp, _Nm>& __arr) 284 { return __arr[_Int]; } 285 286 _GLIBCXX_END_NAMESPACE_TR1 287 } 288