1// class template array -*- C++ -*- 2 3// Copyright (C) 2004, 2005, 2006 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 2, 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// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30/** @file 31 * This is a TR1 C++ Library header. 32 */ 33 34#ifndef _ARRAY 35#define _ARRAY 1 36 37#include <new> 38#include <iterator> 39#include <algorithm> 40#include <cstddef> 41#include <bits/functexcept.h> 42 43//namespace std::tr1 44namespace std 45{ 46namespace tr1 47{ 48 /// @brief struct array [6.2.2]. 49 /// NB: Requires complete type _Tp. 50 template<typename _Tp, std::size_t _Nm> 51 struct array 52 { 53 typedef _Tp value_type; 54 typedef value_type& reference; 55 typedef const value_type& const_reference; 56 typedef value_type* iterator; 57 typedef const value_type* const_iterator; 58 typedef std::size_t size_type; 59 typedef std::ptrdiff_t difference_type; 60 typedef std::reverse_iterator<iterator> reverse_iterator; 61 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 62 63 // Support for zero-sized arrays mandatory. 64 value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__)); 65 66 // No explicit construct/copy/destroy for aggregate type. 67 68 void 69 assign(const value_type& __u) 70 { std::fill_n(begin(), size(), __u); } 71 72 void 73 swap(array& __other) 74 { std::swap_ranges(begin(), end(), __other.begin()); } 75 76 // Iterators. 77 iterator 78 begin() 79 { return iterator(&_M_instance[0]); } 80 81 const_iterator 82 begin() const 83 { return const_iterator(&_M_instance[0]); } 84 85 iterator 86 end() 87 { return iterator(&_M_instance[_Nm]); } 88 89 const_iterator 90 end() const 91 { return const_iterator(&_M_instance[_Nm]); } 92 93 reverse_iterator 94 rbegin() 95 { return reverse_iterator(end()); } 96 97 const_reverse_iterator 98 rbegin() const 99 { return const_reverse_iterator(end()); } 100 101 reverse_iterator 102 rend() 103 { return reverse_iterator(begin()); } 104 105 const_reverse_iterator 106 rend() const 107 { return const_reverse_iterator(begin()); } 108 109 // Capacity. 110 size_type 111 size() const { return _Nm; } 112 113 size_type 114 max_size() const { return _Nm; } 115 116 bool 117 empty() const { return size() == 0; } 118 119 // Element access. 120 reference 121 operator[](size_type __n) 122 { return _M_instance[__n]; } 123 124 const_reference 125 operator[](size_type __n) const 126 { return _M_instance[__n]; } 127 128 reference 129 at(size_type __n) 130 { return _M_at<_Nm>(__n); } 131 132 const_reference 133 at(size_type __n) const 134 { return _M_at<_Nm>(__n); } 135 136 reference 137 front() 138 { return *begin(); } 139 140 const_reference 141 front() const 142 { return *begin(); } 143 144 reference 145 back() 146 { return _Nm ? *(end() - 1) : *end(); } 147 148 const_reference 149 back() const 150 { return _Nm ? *(end() - 1) : *end(); } 151 152 _Tp* 153 data() 154 { return &_M_instance[0]; } 155 156 const _Tp* 157 data() const 158 { return &_M_instance[0]; } 159 160 private: 161 template<std::size_t _Mm> 162 typename std::__enable_if<reference, _Mm>::__type 163 _M_at(size_type __n) 164 { 165 if (__builtin_expect(__n >= _Mm, false)) 166 std::__throw_out_of_range("array::_M_at"); 167 return _M_instance[__n]; 168 } 169 170 // Avoid "unsigned comparison with zero" warnings. 171 template<std::size_t _Mm> 172 typename std::__enable_if<reference, !_Mm>::__type 173 _M_at(size_type) 174 { 175 std::__throw_out_of_range("array::_M_at"); 176 return _M_instance[0]; 177 } 178 179 template<std::size_t _Mm> 180 typename std::__enable_if<const_reference, _Mm>::__type 181 _M_at(size_type __n) const 182 { 183 if (__builtin_expect(__n >= _Mm, false)) 184 std::__throw_out_of_range("array::_M_at"); 185 return _M_instance[__n]; 186 } 187 188 template<std::size_t _Mm> 189 typename std::__enable_if<const_reference, !_Mm>::__type 190 _M_at(size_type) const 191 { 192 std::__throw_out_of_range("array::_M_at"); 193 return _M_instance[0]; 194 } 195 }; 196 197 // Array comparisons. 198 template<typename _Tp, std::size_t _Nm> 199 inline bool 200 operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 201 { return std::equal(__one.begin(), __one.end(), __two.begin()); } 202 203 template<typename _Tp, std::size_t _Nm> 204 inline bool 205 operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 206 { return !(__one == __two); } 207 208 template<typename _Tp, std::size_t _Nm> 209 inline bool 210 operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 211 { 212 return std::lexicographical_compare(__a.begin(), __a.end(), 213 __b.begin(), __b.end()); 214 } 215 216 template<typename _Tp, std::size_t _Nm> 217 inline bool 218 operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 219 { return __two < __one; } 220 221 template<typename _Tp, std::size_t _Nm> 222 inline bool 223 operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 224 { return !(__one > __two); } 225 226 template<typename _Tp, std::size_t _Nm> 227 inline bool 228 operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 229 { return !(__one < __two); } 230 231 // Specialized algorithms [6.2.2.2]. 232 template<typename _Tp, std::size_t _Nm> 233 inline void 234 swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 235 { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); } 236 237 // Tuple interface to class template array [6.2.2.5]. 238 template<typename _Tp> class tuple_size; 239 template<int _Int, typename _Tp> class tuple_element; 240 241 template<typename _Tp, std::size_t _Nm> 242 struct tuple_size<array<_Tp, _Nm> > 243 { static const int value = _Nm; }; 244 245 template<int _Int, typename _Tp, std::size_t _Nm> 246 struct tuple_element<_Int, array<_Tp, _Nm> > 247 { typedef _Tp type; }; 248 249 template<int _Int, typename _Tp, std::size_t _Nm> 250 inline _Tp& 251 get(array<_Tp, _Nm>& __arr) 252 { return __arr[_Int]; } 253 254 template<int _Int, typename _Tp, std::size_t _Nm> 255 inline const _Tp& 256 get(const array<_Tp, _Nm>& __arr) 257 { return __arr[_Int]; } 258} // namespace std::tr1 259} 260 261#endif 262