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