stl_vector.h

Go to the documentation of this file.
00001 // Vector implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 
00030 /*
00031  *
00032  * Copyright (c) 1994
00033  * Hewlett-Packard Company
00034  *
00035  * Permission to use, copy, modify, distribute and sell this software
00036  * and its documentation for any purpose is hereby granted without fee,
00037  * provided that the above copyright notice appear in all copies and
00038  * that both that copyright notice and this permission notice appear
00039  * in supporting documentation.  Hewlett-Packard Company makes no
00040  * representations about the suitability of this software for any
00041  * purpose.  It is provided "as is" without express or implied warranty.
00042  *
00043  *
00044  * Copyright (c) 1996
00045  * Silicon Graphics Computer Systems, Inc.
00046  *
00047  * Permission to use, copy, modify, distribute and sell this software
00048  * and its documentation for any purpose is hereby granted without fee,
00049  * provided that the above copyright notice appear in all copies and
00050  * that both that copyright notice and this permission notice appear
00051  * in supporting documentation.  Silicon Graphics makes no
00052  * representations about the suitability of this  software for any
00053  * purpose.  It is provided "as is" without express or implied warranty.
00054  */
00055 
00061 #ifndef _VECTOR_H
00062 #define _VECTOR_H 1
00063 
00064 #include <bits/stl_iterator_base_funcs.h>
00065 #include <bits/functexcept.h>
00066 #include <bits/concept_check.h>
00067 
00068 namespace _GLIBCXX_STD
00069 {
00075   template<typename _Tp, typename _Alloc>
00076     struct _Vector_base
00077     {
00078       struct _Vector_impl 
00079     : public _Alloc {
00080     _Tp*           _M_start;
00081     _Tp*           _M_finish;
00082     _Tp*           _M_end_of_storage;
00083     _Vector_impl (_Alloc const& __a)
00084       : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
00085     { }
00086       };
00087       
00088     public:
00089       typedef _Alloc allocator_type;
00090 
00091       allocator_type
00092       get_allocator() const { return *static_cast<const _Alloc*>(&this->_M_impl); }
00093 
00094       _Vector_base(const allocator_type& __a) : _M_impl(__a)
00095       { }
00096 
00097       _Vector_base(size_t __n, const allocator_type& __a)
00098     : _M_impl(__a)
00099       {
00100     this->_M_impl._M_start = this->_M_allocate(__n);
00101     this->_M_impl._M_finish = this->_M_impl._M_start;
00102     this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00103       }
00104 
00105       ~_Vector_base()
00106       { _M_deallocate(this->_M_impl._M_start,
00107               this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }
00108 
00109     public:
00110       _Vector_impl _M_impl;
00111 
00112       _Tp*
00113       _M_allocate(size_t __n) { return _M_impl.allocate(__n); }
00114 
00115       void
00116       _M_deallocate(_Tp* __p, size_t __n)
00117       { if (__p) _M_impl.deallocate(__p, __n); }
00118     };
00119 
00120 
00140   template<typename _Tp, typename _Alloc = allocator<_Tp> >
00141     class vector : protected _Vector_base<_Tp, _Alloc>
00142     {
00143       // Concept requirements.
00144       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00145 
00146       typedef _Vector_base<_Tp, _Alloc>         _Base;
00147       typedef vector<_Tp, _Alloc>           vector_type;
00148 
00149     public:
00150       typedef _Tp                    value_type;
00151       typedef typename _Alloc::pointer                   pointer;
00152       typedef typename _Alloc::const_pointer             const_pointer;
00153       typedef typename _Alloc::reference                 reference;
00154       typedef typename _Alloc::const_reference           const_reference;
00155       typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
00156       typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
00157       const_iterator;
00158       typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
00159       typedef std::reverse_iterator<iterator>        reverse_iterator;
00160       typedef size_t                     size_type;
00161       typedef ptrdiff_t                  difference_type;
00162       typedef typename _Base::allocator_type         allocator_type;
00163 
00164     protected:
00170       using _Base::_M_allocate;
00171       using _Base::_M_deallocate;
00172       using _Base::_M_impl;
00173 
00174     public:
00175       // [23.2.4.1] construct/copy/destroy
00176       // (assign() and get_allocator() are also listed in this section)
00180       explicit
00181       vector(const allocator_type& __a = allocator_type())
00182       : _Base(__a) { }
00183 
00191       vector(size_type __n, const value_type& __value,
00192          const allocator_type& __a = allocator_type())
00193       : _Base(__n, __a)
00194       { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
00195                             __n, __value); }
00196 
00204       explicit
00205       vector(size_type __n)
00206       : _Base(__n, allocator_type())
00207       { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
00208                             __n, value_type()); }
00209 
00219       vector(const vector& __x)
00220       : _Base(__x.size(), __x.get_allocator())
00221       { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
00222                           this->_M_impl._M_start);
00223       }
00224 
00240       template<typename _InputIterator>
00241         vector(_InputIterator __first, _InputIterator __last,
00242            const allocator_type& __a = allocator_type())
00243     : _Base(__a)
00244         {
00245       // Check whether it's an integral type.  If so, it's not an iterator.
00246       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00247       _M_initialize_dispatch(__first, __last, _Integral());
00248     }
00249 
00256       ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); }
00257 
00266       vector&
00267       operator=(const vector& __x);
00268 
00279       void
00280       assign(size_type __n, const value_type& __val)
00281       { _M_fill_assign(__n, __val); }
00282 
00295       template<typename _InputIterator>
00296         void
00297         assign(_InputIterator __first, _InputIterator __last)
00298         {
00299       // Check whether it's an integral type.  If so, it's not an iterator.
00300       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00301       _M_assign_dispatch(__first, __last, _Integral());
00302     }
00303 
00305       using _Base::get_allocator;
00306 
00307       // iterators
00313       iterator
00314       begin() { return iterator (this->_M_impl._M_start); }
00315 
00321       const_iterator
00322       begin() const { return const_iterator (this->_M_impl._M_start); }
00323 
00329       iterator
00330       end() { return iterator (this->_M_impl._M_finish); }
00331 
00337       const_iterator
00338       end() const { return const_iterator (this->_M_impl._M_finish); }
00339 
00345       reverse_iterator
00346       rbegin() { return reverse_iterator(end()); }
00347 
00353       const_reverse_iterator
00354       rbegin() const { return const_reverse_iterator(end()); }
00355 
00361       reverse_iterator
00362       rend() { return reverse_iterator(begin()); }
00363 
00369       const_reverse_iterator
00370       rend() const { return const_reverse_iterator(begin()); }
00371 
00372       // [23.2.4.2] capacity
00374       size_type
00375       size() const { return size_type(end() - begin()); }
00376 
00378       size_type
00379       max_size() const { return size_type(-1) / sizeof(value_type); }
00380 
00392       void
00393       resize(size_type __new_size, const value_type& __x)
00394       {
00395     if (__new_size < size())
00396       erase(begin() + __new_size, end());
00397     else
00398       insert(end(), __new_size - size(), __x);
00399       }
00400 
00411       void
00412       resize(size_type __new_size) { resize(__new_size, value_type()); }
00413 
00418       size_type
00419       capacity() const
00420       { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); }
00421 
00426       bool
00427       empty() const { return begin() == end(); }
00428 
00446       void
00447       reserve(size_type __n);
00448 
00449       // element access
00461       reference
00462       operator[](size_type __n) { return *(begin() + __n); }
00463 
00475       const_reference
00476       operator[](size_type __n) const { return *(begin() + __n); }
00477 
00478     protected:
00480       void
00481       _M_range_check(size_type __n) const
00482       {
00483     if (__n >= this->size())
00484       __throw_out_of_range(__N("vector::_M_range_check"));
00485       }
00486 
00487     public:
00499       reference
00500       at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
00501 
00513       const_reference
00514       at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
00515 
00520       reference
00521       front() { return *begin(); }
00522 
00527       const_reference
00528       front() const { return *begin(); }
00529 
00534       reference
00535       back() { return *(end() - 1); }
00536 
00541       const_reference
00542       back() const { return *(end() - 1); }
00543 
00544       // [23.2.4.3] modifiers
00555       void
00556       push_back(const value_type& __x)
00557       {
00558     if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
00559       {
00560         std::_Construct(this->_M_impl._M_finish, __x);
00561         ++this->_M_impl._M_finish;
00562       }
00563     else
00564       _M_insert_aux(end(), __x);
00565       }
00566 
00576       void
00577       pop_back()
00578       {
00579     --this->_M_impl._M_finish;
00580     std::_Destroy(this->_M_impl._M_finish);
00581       }
00582 
00594       iterator
00595       insert(iterator __position, const value_type& __x);
00596 
00610       void
00611       insert(iterator __position, size_type __n, const value_type& __x)
00612       { _M_fill_insert(__position, __n, __x); }
00613 
00628       template<typename _InputIterator>
00629         void
00630         insert(iterator __position, _InputIterator __first,
00631            _InputIterator __last)
00632         {
00633       // Check whether it's an integral type.  If so, it's not an iterator.
00634       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00635       _M_insert_dispatch(__position, __first, __last, _Integral());
00636     }
00637 
00653       iterator
00654       erase(iterator __position);
00655 
00674       iterator
00675       erase(iterator __first, iterator __last);
00676 
00686       void
00687       swap(vector& __x)
00688       {
00689     std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
00690     std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
00691     std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage);
00692       }
00693 
00700       void
00701       clear() { erase(begin(), end()); }
00702 
00703     protected:
00710       template<typename _ForwardIterator>
00711         pointer
00712         _M_allocate_and_copy(size_type __n,
00713                  _ForwardIterator __first, _ForwardIterator __last)
00714         {
00715       pointer __result = this->_M_allocate(__n);
00716       try
00717         {
00718           std::uninitialized_copy(__first, __last, __result);
00719           return __result;
00720         }
00721       catch(...)
00722         {
00723           _M_deallocate(__result, __n);
00724           __throw_exception_again;
00725         }
00726     }
00727 
00728 
00729       // Internal constructor functions follow.
00730 
00731       // Called by the range constructor to implement [23.1.1]/9
00732       template<typename _Integer>
00733         void
00734         _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
00735         {
00736       this->_M_impl._M_start = _M_allocate(__n);
00737       this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00738       this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
00739                               __n, __value);
00740     }
00741 
00742       // Called by the range constructor to implement [23.1.1]/9
00743       template<typename _InputIterator>
00744         void
00745         _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
00746                    __false_type)
00747         {
00748       typedef typename iterator_traits<_InputIterator>::iterator_category
00749         _IterCategory;
00750       _M_range_initialize(__first, __last, _IterCategory());
00751     }
00752 
00753       // Called by the second initialize_dispatch above
00754       template<typename _InputIterator>
00755         void
00756         _M_range_initialize(_InputIterator __first,
00757                 _InputIterator __last, input_iterator_tag)
00758         {
00759       for ( ; __first != __last; ++__first)
00760         push_back(*__first);
00761     }
00762 
00763       // Called by the second initialize_dispatch above
00764       template<typename _ForwardIterator>
00765         void
00766         _M_range_initialize(_ForwardIterator __first,
00767                 _ForwardIterator __last, forward_iterator_tag)
00768         {
00769       size_type __n = std::distance(__first, __last);
00770       this->_M_impl._M_start = this->_M_allocate(__n);
00771       this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00772       this->_M_impl._M_finish = std::uninitialized_copy(__first, __last,
00773                             this->_M_impl._M_start);
00774     }
00775 
00776 
00777       // Internal assign functions follow.  The *_aux functions do the actual
00778       // assignment work for the range versions.
00779 
00780       // Called by the range assign to implement [23.1.1]/9
00781       template<typename _Integer>
00782         void
00783         _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
00784         {
00785       _M_fill_assign(static_cast<size_type>(__n),
00786              static_cast<value_type>(__val));
00787     }
00788 
00789       // Called by the range assign to implement [23.1.1]/9
00790       template<typename _InputIterator>
00791         void
00792         _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00793                __false_type)
00794         {
00795       typedef typename iterator_traits<_InputIterator>::iterator_category
00796         _IterCategory;
00797       _M_assign_aux(__first, __last, _IterCategory());
00798     }
00799 
00800       // Called by the second assign_dispatch above
00801       template<typename _InputIterator>
00802         void
00803         _M_assign_aux(_InputIterator __first, _InputIterator __last,
00804               input_iterator_tag);
00805 
00806       // Called by the second assign_dispatch above
00807       template<typename _ForwardIterator>
00808         void
00809         _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00810               forward_iterator_tag);
00811 
00812       // Called by assign(n,t), and the range assign when it turns out
00813       // to be the same thing.
00814       void
00815       _M_fill_assign(size_type __n, const value_type& __val);
00816 
00817 
00818       // Internal insert functions follow.
00819 
00820       // Called by the range insert to implement [23.1.1]/9
00821       template<typename _Integer>
00822         void
00823         _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
00824                __true_type)
00825         {
00826       _M_fill_insert(__pos, static_cast<size_type>(__n),
00827              static_cast<value_type>(__val));
00828     }
00829 
00830       // Called by the range insert to implement [23.1.1]/9
00831       template<typename _InputIterator>
00832         void
00833         _M_insert_dispatch(iterator __pos, _InputIterator __first,
00834                _InputIterator __last, __false_type)
00835         {
00836       typedef typename iterator_traits<_InputIterator>::iterator_category
00837         _IterCategory;
00838       _M_range_insert(__pos, __first, __last, _IterCategory());
00839     }
00840 
00841       // Called by the second insert_dispatch above
00842       template<typename _InputIterator>
00843         void
00844         _M_range_insert(iterator __pos, _InputIterator __first,
00845             _InputIterator __last, input_iterator_tag);
00846 
00847       // Called by the second insert_dispatch above
00848       template<typename _ForwardIterator>
00849         void
00850         _M_range_insert(iterator __pos, _ForwardIterator __first,
00851             _ForwardIterator __last, forward_iterator_tag);
00852 
00853       // Called by insert(p,n,x), and the range insert when it turns out to be
00854       // the same thing.
00855       void
00856       _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
00857 
00858       // Called by insert(p,x)
00859       void
00860       _M_insert_aux(iterator __position, const value_type& __x);
00861     };
00862 
00863 
00874   template<typename _Tp, typename _Alloc>
00875     inline bool
00876     operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00877     {
00878       return __x.size() == __y.size() &&
00879              std::equal(__x.begin(), __x.end(), __y.begin());
00880     }
00881 
00893   template<typename _Tp, typename _Alloc>
00894     inline bool
00895     operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00896     {
00897       return std::lexicographical_compare(__x.begin(), __x.end(),
00898                       __y.begin(), __y.end());
00899     }
00900 
00902   template<typename _Tp, typename _Alloc>
00903     inline bool
00904     operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00905     { return !(__x == __y); }
00906 
00908   template<typename _Tp, typename _Alloc>
00909     inline bool
00910     operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00911     { return __y < __x; }
00912 
00914   template<typename _Tp, typename _Alloc>
00915     inline bool
00916     operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00917     { return !(__y < __x); }
00918 
00920   template<typename _Tp, typename _Alloc>
00921     inline bool
00922     operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
00923     { return !(__x < __y); }
00924 
00926   template<typename _Tp, typename _Alloc>
00927     inline void
00928     swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
00929     { __x.swap(__y); }
00930 } // namespace std
00931 
00932 #endif /* _VECTOR_H */

Generated on Tue Jan 30 17:31:55 2007 for GNU C++ STL by doxygen 1.3.6