array

Go to the documentation of this file.
00001 // class template array -*- C++ -*-
00002 
00003 // Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
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 //namespace std::tr1
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       // Support for zero-sized arrays mandatory.
00064       value_type _M_instance[_Nm ? _Nm : 1] __attribute__((__aligned__));
00065 
00066       // No explicit construct/copy/destroy for aggregate type.
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       // Iterators.
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       // Capacity.
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       // Element access.
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       // Avoid "unsigned comparison with zero" warnings.
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   // Array comparisons.
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   // Specialized algorithms [6.2.2.2].
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   // Tuple interface to class template array [6.2.2.5].
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 } // namespace std::tr1
00259 }
00260 
00261 #endif

Generated on Tue Feb 2 16:55:43 2010 for GNU C++ STL by  doxygen 1.4.7