# stl_vector.h

Go to the documentation of this file.

    00001 // Vector implementation -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002 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 __GLIBCPP_INTERNAL_VECTOR_H
    00062 #define __GLIBCPP_INTERNAL_VECTOR_H
    00063
    00064 #include <bits/stl_iterator_base_funcs.h>
    00065 #include <bits/functexcept.h>
    00066 #include <bits/concept_check.h>
    00067
    00068 namespace std
    00069 {
    00071
    00076   template<typename _Tp, typename _Allocator, bool _IsStatic>
    00077     class _Vector_alloc_base
    00078     {
    00079     public:
    00080       typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
    00081       allocator_type;
    00082
    00083       allocator_type
    00084       get_allocator() const { return _M_data_allocator; }
    00085
    00086       _Vector_alloc_base(const allocator_type& __a)
    00087       : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
    00088       { }
    00089
    00090     protected:
    00091       allocator_type _M_data_allocator;
    00092       _Tp*           _M_start;
    00093       _Tp*           _M_finish;
    00094       _Tp*           _M_end_of_storage;
    00095
    00096       _Tp*
    00097       _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
    00098
    00099       void
    00100       _M_deallocate(_Tp* __p, size_t __n)
    00101       { if (__p) _M_data_allocator.deallocate(__p, __n); }
    00102     };
    00103
    00105   template<typename _Tp, typename _Allocator>
    00106     class _Vector_alloc_base<_Tp, _Allocator, true>
    00107     {
    00108     public:
    00109       typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
    00110              allocator_type;
    00111
    00112       allocator_type
    00113       get_allocator() const { return allocator_type(); }
    00114
    00115       _Vector_alloc_base(const allocator_type&)
    00116       : _M_start(0), _M_finish(0), _M_end_of_storage(0)
    00117       { }
    00118
    00119     protected:
    00120       _Tp* _M_start;
    00121       _Tp* _M_finish;
    00122       _Tp* _M_end_of_storage;
    00123
    00124       typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
    00125
    00126       _Tp*
    00127       _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
    00128
    00129       void
    00130       _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
    00131     };
    00132
    00133
    00139   template<typename _Tp, typename _Alloc>
    00140     struct _Vector_base
    00141     : public _Vector_alloc_base<_Tp, _Alloc,
    00142                                 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
    00143     {
    00144     public:
    00145       typedef _Vector_alloc_base<_Tp, _Alloc,
    00146                  _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
    00147          _Base;
    00148       typedef typename _Base::allocator_type allocator_type;
    00149
    00150       _Vector_base(const allocator_type& __a)
    00151       : _Base(__a) { }
    00152
    00153       _Vector_base(size_t __n, const allocator_type& __a)
    00154       : _Base(__a)
    00155       {
    00156     _M_start = _M_allocate(__n);
    00157     _M_finish = _M_start;
    00158     _M_end_of_storage = _M_start + __n;
    00159       }
    00160
    00161       ~_Vector_base()
    00162       { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
    00163     };
    00164
    00165
    00184   template<typename _Tp, typename _Alloc = allocator<_Tp> >
    00185     class vector : protected _Vector_base<_Tp, _Alloc>
    00186     {
    00187       // Concept requirements.
    00188       __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
    00189
    00190       typedef _Vector_base<_Tp, _Alloc>                     _Base;
    00191       typedef vector<_Tp, _Alloc>                           vector_type;
    00192
    00193     public:
    00194       typedef _Tp                       value_type;
    00195       typedef value_type*                   pointer;
    00196       typedef const value_type*                 const_pointer;
    00197       typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
    00198       typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
    00199       const_iterator;
    00200       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
    00201       typedef std::reverse_iterator<iterator>                reverse_iterator;
    00202       typedef value_type&                   reference;
    00203       typedef const value_type&                 const_reference;
    00204       typedef size_t                    size_type;
    00205       typedef ptrdiff_t                     difference_type;
    00206       typedef typename _Base::allocator_type                allocator_type;
    00207
    00208     protected:
    00215       using _Base::_M_allocate;
    00216       using _Base::_M_deallocate;
    00217       using _Base::_M_start;
    00218       using _Base::_M_finish;
    00219       using _Base::_M_end_of_storage;
    00220
    00221     public:
    00222       // [23.2.4.1] construct/copy/destroy
    00223       // (assign() and get_allocator() are also listed in this section)
    00227       explicit
    00228       vector(const allocator_type& __a = allocator_type())
    00229       : _Base(__a) { }
    00230
    00238       vector(size_type __n, const value_type& __value,
    00239          const allocator_type& __a = allocator_type())
    00240       : _Base(__n, __a)
    00241       { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
    00242
    00250       explicit
    00251       vector(size_type __n)
    00252       : _Base(__n, allocator_type())
    00253       { _M_finish = uninitialized_fill_n(_M_start, __n, value_type()); }
    00254
    00264       vector(const vector& __x)
    00265       : _Base(__x.size(), __x.get_allocator())
    00266       { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
    00267
    00282       template<typename _InputIterator>
    00283         vector(_InputIterator __first, _InputIterator __last,
    00284            const allocator_type& __a = allocator_type())
    00285     : _Base(__a)
    00286         {
    00287       // Check whether it's an integral type.  If so, it's not an iterator.
    00288       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
    00289       _M_initialize_dispatch(__first, __last, _Integral());
    00290     }
    00291
    00297       ~vector() { _Destroy(_M_start, _M_finish); }
    00298
    00307       vector&
    00308       operator=(const vector& __x);
    00309
    00320       void
    00321       assign(size_type __n, const value_type& __val)
    00322       { _M_fill_assign(__n, __val); }
    00323
    00336       template<typename _InputIterator>
    00337         void
    00338         assign(_InputIterator __first, _InputIterator __last)
    00339         {
    00340       // Check whether it's an integral type.  If so, it's not an iterator.
    00341       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
    00342       _M_assign_dispatch(__first, __last, _Integral());
    00343     }
    00344
    00346       allocator_type
    00347       get_allocator() const { return _Base::get_allocator(); }
    00348
    00349       // iterators
    00354       iterator
    00355       begin() { return iterator (_M_start); }
    00356
    00362       const_iterator
    00363       begin() const { return const_iterator (_M_start); }
    00364
    00370       iterator
    00371       end() { return iterator (_M_finish); }
    00372
    00377       const_iterator
    00378       end() const { return const_iterator (_M_finish); }
    00379
    00385       reverse_iterator
    00386       rbegin() { return reverse_iterator(end()); }
    00387
    00393       const_reverse_iterator
    00394       rbegin() const { return const_reverse_iterator(end()); }
    00395
    00401       reverse_iterator
    00402       rend() { return reverse_iterator(begin()); }
    00403
    00409       const_reverse_iterator
    00410       rend() const { return const_reverse_iterator(begin()); }
    00411
    00412       // [23.2.4.2] capacity
    00414       size_type
    00415       size() const { return size_type(end() - begin()); }
    00416
    00418       size_type
    00419       max_size() const { return size_type(-1) / sizeof(value_type); }
    00420
    00432       void
    00433       resize(size_type __new_size, const value_type& __x)
    00434       {
    00435     if (__new_size < size())
    00436       erase(begin() + __new_size, end());
    00437     else
    00438       insert(end(), __new_size - size(), __x);
    00439       }
    00440
    00451       void
    00452       resize(size_type __new_size) { resize(__new_size, value_type()); }
    00453
    00458       size_type
    00459       capacity() const
    00460       { return size_type(const_iterator(_M_end_of_storage) - begin()); }
    00461
    00466       bool
    00467       empty() const { return begin() == end(); }
    00468
    00486       void
    00487       reserve(size_type __n);
    00488
    00489       // element access
    00500       reference
    00501       operator[](size_type __n) { return *(begin() + __n); }
    00502
    00514       const_reference
    00515       operator[](size_type __n) const { return *(begin() + __n); }
    00516
    00517     protected:
    00519       void
    00520       _M_range_check(size_type __n) const
    00521       {
    00522     if (__n >= this->size())
    00523       __throw_out_of_range("vector [] access out of range");
    00524       }
    00525
    00526     public:
    00538       reference
    00539       at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
    00540
    00552       const_reference
    00553       at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
    00554
    00559       reference
    00560       front() { return *begin(); }
    00561
    00566       const_reference
    00567       front() const { return *begin(); }
    00568
    00573       reference
    00574       back() { return *(end() - 1); }
    00575
    00580       const_reference
    00581       back() const { return *(end() - 1); }
    00582
    00583       // [23.2.4.3] modifiers
    00594       void
    00595       push_back(const value_type& __x)
    00596       {
    00597     if (_M_finish != _M_end_of_storage)
    00598       {
    00599         _Construct(_M_finish, __x);
    00600         ++_M_finish;
    00601       }
    00602     else
    00603       _M_insert_aux(end(), __x);
    00604       }
    00605
    00614       void
    00615       pop_back()
    00616       {
    00617     --_M_finish;
    00618     _Destroy(_M_finish);
    00619       }
    00620
    00632       iterator
    00633       insert(iterator __position, const value_type& __x);
    00634
    00635 #ifdef _GLIBCPP_DEPRECATED
    00636
    00651       iterator
    00652       insert(iterator __position)
    00653       { return insert(__position, value_type()); }
    00654 #endif
    00655
    00669       void
    00670       insert(iterator __pos, size_type __n, const value_type& __x)
    00671       { _M_fill_insert(__pos, __n, __x); }
    00672
    00687       template<typename _InputIterator>
    00688         void
    00689         insert(iterator __pos, _InputIterator __first, _InputIterator __last)
    00690         {
    00691       // Check whether it's an integral type.  If so, it's not an iterator.
    00692       typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
    00693       _M_insert_dispatch(__pos, __first, __last, _Integral());
    00694     }
    00695
    00711       iterator
    00712       erase(iterator __position);
    00713
    00732       iterator
    00733       erase(iterator __first, iterator __last);
    00734
    00744       void
    00745       swap(vector& __x)
    00746       {
    00747     std::swap(_M_start, __x._M_start);
    00748     std::swap(_M_finish, __x._M_finish);
    00749     std::swap(_M_end_of_storage, __x._M_end_of_storage);
    00750       }
    00751
    00758       void
    00759       clear() { erase(begin(), end()); }
    00760
    00761     protected:
    00768       template<typename _ForwardIterator>
    00769         pointer
    00770         _M_allocate_and_copy(size_type __n,
    00771                  _ForwardIterator __first, _ForwardIterator __last)
    00772         {
    00773       pointer __result = _M_allocate(__n);
    00774       try
    00775         {
    00776           uninitialized_copy(__first, __last, __result);
    00777           return __result;
    00778         }
    00779       catch(...)
    00780         {
    00781           _M_deallocate(__result, __n);
    00782           __throw_exception_again;
    00783         }
    00784     }
    00785
    00786
    00787       // Internal constructor functions follow.
    00788
    00789       // Called by the range constructor to implement [23.1.1]/9
    00790       template<typename _Integer>
    00791         void
    00792         _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
    00793         {
    00794       _M_start = _M_allocate(__n);
    00795       _M_end_of_storage = _M_start + __n;
    00796       _M_finish = uninitialized_fill_n(_M_start, __n, __value);
    00797     }
    00798
    00799       // Called by the range constructor to implement [23.1.1]/9
    00800       template<typename _InputIter>
    00801         void
    00802         _M_initialize_dispatch(_InputIter __first, _InputIter __last,
    00803                    __false_type)
    00804         {
    00805       typedef typename iterator_traits<_InputIter>::iterator_category
    00806         _IterCategory;
    00807       _M_range_initialize(__first, __last, _IterCategory());
    00808     }
    00809
    00810       // Called by the second initialize_dispatch above
    00811       template<typename _InputIterator>
    00812         void
    00813         _M_range_initialize(_InputIterator __first,
    00814                 _InputIterator __last, input_iterator_tag)
    00815         {
    00816       for ( ; __first != __last; ++__first)
    00817         push_back(*__first);
    00818     }
    00819
    00820       // Called by the second initialize_dispatch above
    00821       template<typename _ForwardIterator>
    00822         void
    00823         _M_range_initialize(_ForwardIterator __first,
    00824                 _ForwardIterator __last, forward_iterator_tag)
    00825         {
    00826       size_type __n = distance(__first, __last);
    00827       _M_start = _M_allocate(__n);
    00828       _M_end_of_storage = _M_start + __n;
    00829       _M_finish = uninitialized_copy(__first, __last, _M_start);
    00830     }
    00831
    00832
    00833       // Internal assign functions follow.  The *_aux functions do the actual
    00834       // assignment work for the range versions.
    00835
    00836       // Called by the range assign to implement [23.1.1]/9
    00837       template<typename _Integer>
    00838         void
    00839         _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
    00840         {
    00841       _M_fill_assign(static_cast<size_type>(__n),
    00842              static_cast<value_type>(__val));
    00843     }
    00844
    00845       // Called by the range assign to implement [23.1.1]/9
    00846       template<typename _InputIter>
    00847         void
    00848         _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
    00849         {
    00850       typedef typename iterator_traits<_InputIter>::iterator_category
    00851         _IterCategory;
    00852       _M_assign_aux(__first, __last, _IterCategory());
    00853     }
    00854
    00855       // Called by the second assign_dispatch above
    00856       template<typename _InputIterator>
    00857         void
    00858         _M_assign_aux(_InputIterator __first, _InputIterator __last,
    00859               input_iterator_tag);
    00860
    00861       // Called by the second assign_dispatch above
    00862       template<typename _ForwardIterator>
    00863         void
    00864         _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
    00865               forward_iterator_tag);
    00866
    00867       // Called by assign(n,t), and the range assign when it turns out
    00868       // to be the same thing.
    00869       void
    00870       _M_fill_assign(size_type __n, const value_type& __val);
    00871
    00872
    00873       // Internal insert functions follow.
    00874
    00875       // Called by the range insert to implement [23.1.1]/9
    00876       template<typename _Integer>
    00877         void
    00878         _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
    00879                __true_type)
    00880         {
    00881       _M_fill_insert(__pos, static_cast<size_type>(__n),
    00882              static_cast<value_type>(__val));
    00883     }
    00884
    00885       // Called by the range insert to implement [23.1.1]/9
    00886       template<typename _InputIterator>
    00887         void
    00888         _M_insert_dispatch(iterator __pos, _InputIterator __first,
    00889                _InputIterator __last, __false_type)
    00890         {
    00891       typedef typename iterator_traits<_InputIterator>::iterator_category
    00892         _IterCategory;
    00893       _M_range_insert(__pos, __first, __last, _IterCategory());
    00894     }
    00895
    00896       // Called by the second insert_dispatch above
    00897       template<typename _InputIterator>
    00898         void
    00899         _M_range_insert(iterator __pos, _InputIterator __first,
    00900             _InputIterator __last, input_iterator_tag);
    00901
    00902       // Called by the second insert_dispatch above
    00903       template<typename _ForwardIterator>
    00904         void
    00905         _M_range_insert(iterator __pos, _ForwardIterator __first,
    00906             _ForwardIterator __last, forward_iterator_tag);
    00907
    00908       // Called by insert(p,n,x), and the range insert when it turns out to be
    00909       // the same thing.
    00910       void
    00911       _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
    00912
    00913       // Called by insert(p,x)
    00914       void
    00915       _M_insert_aux(iterator __position, const value_type& __x);
    00916
    00917 #ifdef _GLIBCPP_DEPRECATED
    00918       // Unused now (same situation as in deque)
    00919       void _M_insert_aux(iterator __position);
    00920 #endif
    00921     };
    00922
    00923
    00934   template<typename _Tp, typename _Alloc>
    00935     inline bool
    00936     operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00937     {
    00938       return __x.size() == __y.size() &&
    00939              equal(__x.begin(), __x.end(), __y.begin());
    00940     }
    00941
    00953   template<typename _Tp, typename _Alloc>
    00954     inline bool
    00955     operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00956     {
    00957       return lexicographical_compare(__x.begin(), __x.end(),
    00958                                      __y.begin(), __y.end());
    00959     }
    00960
    00962   template<typename _Tp, typename _Alloc>
    00963     inline bool
    00964     operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00965     { return !(__x == __y); }
    00966
    00968   template<typename _Tp, typename _Alloc>
    00969     inline bool
    00970     operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00971     { return __y < __x; }
    00972
    00974   template<typename _Tp, typename _Alloc>
    00975     inline bool
    00976     operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00977     { return !(__y < __x); }
    00978
    00980   template<typename _Tp, typename _Alloc>
    00981     inline bool
    00982     operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
    00983     { return !(__x < __y); }
    00984
    00986   template<typename _Tp, typename _Alloc>
    00987     inline void
    00988     swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
    00989     { __x.swap(__y); }
    00990 } // namespace std
    00991
    00992 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */