00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00034 #ifndef _ARRAY
00035 #define _ARRAY 1
00036
00037 #include <new>
00038 #include <iterator>
00039 #include <algorithm>
00040 #include <cstddef>
00041 #include <bits/functexcept.h>
00042
00043
00044 namespace std
00045 {
00046 namespace tr1
00047 {
00050 template<typename _Tp, std::size_t _Nm>
00051 struct array
00052 {
00053 typedef _Tp value_type;
00054 typedef value_type& reference;
00055 typedef const value_type& const_reference;
00056 typedef value_type* iterator;
00057 typedef const value_type* const_iterator;
00058 typedef std::size_t size_type;
00059 typedef std::ptrdiff_t difference_type;
00060 typedef std::reverse_iterator<iterator> reverse_iterator;
00061 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00062
00063
00064 value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__));
00065
00066
00067
00068 void
00069 assign(const value_type& __u)
00070 { std::fill_n(begin(), size(), __u); }
00071
00072 void
00073 swap(array& __other)
00074 { std::swap_ranges(begin(), end(), __other.begin()); }
00075
00076
00077 iterator
00078 begin()
00079 { return iterator(&_M_instance[0]); }
00080
00081 const_iterator
00082 begin() const
00083 { return const_iterator(&_M_instance[0]); }
00084
00085 iterator
00086 end()
00087 { return iterator(&_M_instance[_Nm]); }
00088
00089 const_iterator
00090 end() const
00091 { return const_iterator(&_M_instance[_Nm]); }
00092
00093 reverse_iterator
00094 rbegin()
00095 { return reverse_iterator(end()); }
00096
00097 const_reverse_iterator
00098 rbegin() const
00099 { return const_reverse_iterator(end()); }
00100
00101 reverse_iterator
00102 rend()
00103 { return reverse_iterator(begin()); }
00104
00105 const_reverse_iterator
00106 rend() const
00107 { return const_reverse_iterator(begin()); }
00108
00109
00110 size_type
00111 size() const { return _Nm; }
00112
00113 size_type
00114 max_size() const { return _Nm; }
00115
00116 bool
00117 empty() const { return size() == 0; }
00118
00119
00120 reference
00121 operator[](size_type __n)
00122 { return _M_instance[__n]; }
00123
00124 const_reference
00125 operator[](size_type __n) const
00126 { return _M_instance[__n]; }
00127
00128 reference
00129 at(size_type __n)
00130 { return _M_at<_Nm>(__n); }
00131
00132 const_reference
00133 at(size_type __n) const
00134 { return _M_at<_Nm>(__n); }
00135
00136 reference
00137 front()
00138 { return *begin(); }
00139
00140 const_reference
00141 front() const
00142 { return *begin(); }
00143
00144 reference
00145 back()
00146 { return _Nm ? *(end() - 1) : *end(); }
00147
00148 const_reference
00149 back() const
00150 { return _Nm ? *(end() - 1) : *end(); }
00151
00152 _Tp*
00153 data()
00154 { return &_M_instance[0]; }
00155
00156 const _Tp*
00157 data() const
00158 { return &_M_instance[0]; }
00159
00160 private:
00161 template<std::size_t _Mm>
00162 typename std::__enable_if<reference, _Mm>::__type
00163 _M_at(size_type __n)
00164 {
00165 if (__builtin_expect(__n >= _Mm, false))
00166 std::__throw_out_of_range("array::_M_at");
00167 return _M_instance[__n];
00168 }
00169
00170
00171 template<std::size_t _Mm>
00172 typename std::__enable_if<reference, !_Mm>::__type
00173 _M_at(size_type)
00174 {
00175 std::__throw_out_of_range("array::_M_at");
00176 return _M_instance[0];
00177 }
00178
00179 template<std::size_t _Mm>
00180 typename std::__enable_if<const_reference, _Mm>::__type
00181 _M_at(size_type __n) const
00182 {
00183 if (__builtin_expect(__n >= _Mm, false))
00184 std::__throw_out_of_range("array::_M_at");
00185 return _M_instance[__n];
00186 }
00187
00188 template<std::size_t _Mm>
00189 typename std::__enable_if<const_reference, !_Mm>::__type
00190 _M_at(size_type) const
00191 {
00192 std::__throw_out_of_range("array::_M_at");
00193 return _M_instance[0];
00194 }
00195 };
00196
00197
00198 template<typename _Tp, std::size_t _Nm>
00199 inline bool
00200 operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00201 { return std::equal(__one.begin(), __one.end(), __two.begin()); }
00202
00203 template<typename _Tp, std::size_t _Nm>
00204 inline bool
00205 operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00206 { return !(__one == __two); }
00207
00208 template<typename _Tp, std::size_t _Nm>
00209 inline bool
00210 operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
00211 {
00212 return std::lexicographical_compare(__a.begin(), __a.end(),
00213 __b.begin(), __b.end());
00214 }
00215
00216 template<typename _Tp, std::size_t _Nm>
00217 inline bool
00218 operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00219 { return __two < __one; }
00220
00221 template<typename _Tp, std::size_t _Nm>
00222 inline bool
00223 operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00224 { return !(__one > __two); }
00225
00226 template<typename _Tp, std::size_t _Nm>
00227 inline bool
00228 operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00229 { return !(__one < __two); }
00230
00231
00232 template<typename _Tp, std::size_t _Nm>
00233 inline void
00234 swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
00235 { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); }
00236
00237
00238 template<typename _Tp> class tuple_size;
00239 template<int _Int, typename _Tp> class tuple_element;
00240
00241 template<typename _Tp, std::size_t _Nm>
00242 struct tuple_size<array<_Tp, _Nm> >
00243 { static const int value = _Nm; };
00244
00245 template<int _Int, typename _Tp, std::size_t _Nm>
00246 struct tuple_element<_Int, array<_Tp, _Nm> >
00247 { typedef _Tp type; };
00248
00249 template<int _Int, typename _Tp, std::size_t _Nm>
00250 inline _Tp&
00251 get(array<_Tp, _Nm>& __arr)
00252 { return __arr[_Int]; }
00253
00254 template<int _Int, typename _Tp, std::size_t _Nm>
00255 inline const _Tp&
00256 get(const array<_Tp, _Nm>& __arr)
00257 { return __arr[_Int]; }
00258 }
00259 }
00260
00261 #endif