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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
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 typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
00079
00080 struct _Vector_impl
00081 : public _Tp_alloc_type
00082 {
00083 _Tp* _M_start;
00084 _Tp* _M_finish;
00085 _Tp* _M_end_of_storage;
00086 _Vector_impl(_Tp_alloc_type const& __a)
00087 : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
00088 { }
00089 };
00090
00091 public:
00092 typedef _Alloc allocator_type;
00093
00094 _Tp_alloc_type&
00095 _M_get_Tp_allocator()
00096 { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
00097
00098 const _Tp_alloc_type&
00099 _M_get_Tp_allocator() const
00100 { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
00101
00102 allocator_type
00103 get_allocator() const
00104 { return _M_get_Tp_allocator(); }
00105
00106 _Vector_base(const allocator_type& __a)
00107 : _M_impl(__a)
00108 { }
00109
00110 _Vector_base(size_t __n, const allocator_type& __a)
00111 : _M_impl(__a)
00112 {
00113 this->_M_impl._M_start = this->_M_allocate(__n);
00114 this->_M_impl._M_finish = this->_M_impl._M_start;
00115 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00116 }
00117
00118 ~_Vector_base()
00119 { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
00120 - this->_M_impl._M_start); }
00121
00122 public:
00123 _Vector_impl _M_impl;
00124
00125 _Tp*
00126 _M_allocate(size_t __n)
00127 { return _M_impl.allocate(__n); }
00128
00129 void
00130 _M_deallocate(_Tp* __p, size_t __n)
00131 {
00132 if (__p)
00133 _M_impl.deallocate(__p, __n);
00134 }
00135 };
00136
00137
00157 template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
00158 class vector : protected _Vector_base<_Tp, _Alloc>
00159 {
00160
00161 typedef typename _Alloc::value_type _Alloc_value_type;
00162 __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
00163 __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
00164
00165 typedef _Vector_base<_Tp, _Alloc> _Base;
00166 typedef vector<_Tp, _Alloc> vector_type;
00167 typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
00168
00169 public:
00170 typedef _Tp value_type;
00171 typedef typename _Tp_alloc_type::pointer pointer;
00172 typedef typename _Tp_alloc_type::const_pointer const_pointer;
00173 typedef typename _Tp_alloc_type::reference reference;
00174 typedef typename _Tp_alloc_type::const_reference const_reference;
00175 typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
00176 typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
00177 const_iterator;
00178 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00179 typedef std::reverse_iterator<iterator> reverse_iterator;
00180 typedef size_t size_type;
00181 typedef ptrdiff_t difference_type;
00182 typedef _Alloc allocator_type;
00183
00184 protected:
00190 using _Base::_M_allocate;
00191 using _Base::_M_deallocate;
00192 using _Base::_M_impl;
00193 using _Base::_M_get_Tp_allocator;
00194
00195 public:
00196
00197
00201 explicit
00202 vector(const allocator_type& __a = allocator_type())
00203 : _Base(__a)
00204 { }
00205
00213 explicit
00214 vector(size_type __n, const value_type& __value = value_type(),
00215 const allocator_type& __a = allocator_type())
00216 : _Base(__n, __a)
00217 {
00218 std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
00219 _M_get_Tp_allocator());
00220 this->_M_impl._M_finish = this->_M_impl._M_start + __n;
00221 }
00222
00232 vector(const vector& __x)
00233 : _Base(__x.size(), __x.get_allocator())
00234 { this->_M_impl._M_finish =
00235 std::__uninitialized_copy_a(__x.begin(), __x.end(),
00236 this->_M_impl._M_start,
00237 _M_get_Tp_allocator());
00238 }
00239
00255 template<typename _InputIterator>
00256 vector(_InputIterator __first, _InputIterator __last,
00257 const allocator_type& __a = allocator_type())
00258 : _Base(__a)
00259 {
00260
00261 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
00262 _M_initialize_dispatch(__first, __last, _Integral());
00263 }
00264
00271 ~vector()
00272 { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
00273 _M_get_Tp_allocator());
00274 }
00275
00284 vector&
00285 operator=(const vector& __x);
00286
00297 void
00298 assign(size_type __n, const value_type& __val)
00299 { _M_fill_assign(__n, __val); }
00300
00313 template<typename _InputIterator>
00314 void
00315 assign(_InputIterator __first, _InputIterator __last)
00316 {
00317
00318 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
00319 _M_assign_dispatch(__first, __last, _Integral());
00320 }
00321
00323 using _Base::get_allocator;
00324
00325
00331 iterator
00332 begin()
00333 { return iterator (this->_M_impl._M_start); }
00334
00340 const_iterator
00341 begin() const
00342 { return const_iterator (this->_M_impl._M_start); }
00343
00349 iterator
00350 end()
00351 { return iterator (this->_M_impl._M_finish); }
00352
00358 const_iterator
00359 end() const
00360 { return const_iterator (this->_M_impl._M_finish); }
00361
00367 reverse_iterator
00368 rbegin()
00369 { return reverse_iterator(end()); }
00370
00376 const_reverse_iterator
00377 rbegin() const
00378 { return const_reverse_iterator(end()); }
00379
00385 reverse_iterator
00386 rend()
00387 { return reverse_iterator(begin()); }
00388
00394 const_reverse_iterator
00395 rend() const
00396 { return const_reverse_iterator(begin()); }
00397
00398
00400 size_type
00401 size() const
00402 { return size_type(end() - begin()); }
00403
00405 size_type
00406 max_size() const
00407 { return size_type(-1) / sizeof(value_type); }
00408
00420 void
00421 resize(size_type __new_size, value_type __x = value_type())
00422 {
00423 if (__new_size < size())
00424 erase(begin() + __new_size, end());
00425 else
00426 insert(end(), __new_size - size(), __x);
00427 }
00428
00433 size_type
00434 capacity() const
00435 { return size_type(const_iterator(this->_M_impl._M_end_of_storage)
00436 - begin()); }
00437
00442 bool
00443 empty() const
00444 { return begin() == end(); }
00445
00463 void
00464 reserve(size_type __n);
00465
00466
00478 reference
00479 operator[](size_type __n)
00480 { return *(begin() + __n); }
00481
00493 const_reference
00494 operator[](size_type __n) const
00495 { return *(begin() + __n); }
00496
00497 protected:
00499 void
00500 _M_range_check(size_type __n) const
00501 {
00502 if (__n >= this->size())
00503 __throw_out_of_range(__N("vector::_M_range_check"));
00504 }
00505
00506 public:
00518 reference
00519 at(size_type __n)
00520 {
00521 _M_range_check(__n);
00522 return (*this)[__n];
00523 }
00524
00536 const_reference
00537 at(size_type __n) const
00538 {
00539 _M_range_check(__n);
00540 return (*this)[__n];
00541 }
00542
00547 reference
00548 front()
00549 { return *begin(); }
00550
00555 const_reference
00556 front() const
00557 { return *begin(); }
00558
00563 reference
00564 back()
00565 { return *(end() - 1); }
00566
00571 const_reference
00572 back() const
00573 { return *(end() - 1); }
00574
00575
00576
00577
00582 pointer
00583 data()
00584 { return pointer(this->_M_impl._M_start); }
00585
00586 const_pointer
00587 data() const
00588 { return const_pointer(this->_M_impl._M_start); }
00589
00590
00601 void
00602 push_back(const value_type& __x)
00603 {
00604 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
00605 {
00606 this->_M_impl.construct(this->_M_impl._M_finish, __x);
00607 ++this->_M_impl._M_finish;
00608 }
00609 else
00610 _M_insert_aux(end(), __x);
00611 }
00612
00622 void
00623 pop_back()
00624 {
00625 --this->_M_impl._M_finish;
00626 this->_M_impl.destroy(this->_M_impl._M_finish);
00627 }
00628
00640 iterator
00641 insert(iterator __position, const value_type& __x);
00642
00656 void
00657 insert(iterator __position, size_type __n, const value_type& __x)
00658 { _M_fill_insert(__position, __n, __x); }
00659
00674 template<typename _InputIterator>
00675 void
00676 insert(iterator __position, _InputIterator __first,
00677 _InputIterator __last)
00678 {
00679
00680 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
00681 _M_insert_dispatch(__position, __first, __last, _Integral());
00682 }
00683
00699 iterator
00700 erase(iterator __position);
00701
00720 iterator
00721 erase(iterator __first, iterator __last);
00722
00732 void
00733 swap(vector& __x)
00734 {
00735 std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
00736 std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
00737 std::swap(this->_M_impl._M_end_of_storage,
00738 __x._M_impl._M_end_of_storage);
00739 }
00740
00747 void
00748 clear()
00749 {
00750 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
00751 _M_get_Tp_allocator());
00752 this->_M_impl._M_finish = this->_M_impl._M_start;
00753 }
00754
00755 protected:
00762 template<typename _ForwardIterator>
00763 pointer
00764 _M_allocate_and_copy(size_type __n,
00765 _ForwardIterator __first, _ForwardIterator __last)
00766 {
00767 pointer __result = this->_M_allocate(__n);
00768 try
00769 {
00770 std::__uninitialized_copy_a(__first, __last, __result,
00771 _M_get_Tp_allocator());
00772 return __result;
00773 }
00774 catch(...)
00775 {
00776 _M_deallocate(__result, __n);
00777 __throw_exception_again;
00778 }
00779 }
00780
00781
00782
00783
00784
00785 template<typename _Integer>
00786 void
00787 _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
00788 {
00789 this->_M_impl._M_start = _M_allocate(__n);
00790 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00791 std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
00792 _M_get_Tp_allocator());
00793 this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
00794 }
00795
00796
00797 template<typename _InputIterator>
00798 void
00799 _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
00800 __false_type)
00801 {
00802 typedef typename std::iterator_traits<_InputIterator>::
00803 iterator_category _IterCategory;
00804 _M_range_initialize(__first, __last, _IterCategory());
00805 }
00806
00807
00808 template<typename _InputIterator>
00809 void
00810 _M_range_initialize(_InputIterator __first,
00811 _InputIterator __last, std::input_iterator_tag)
00812 {
00813 for (; __first != __last; ++__first)
00814 push_back(*__first);
00815 }
00816
00817
00818 template<typename _ForwardIterator>
00819 void
00820 _M_range_initialize(_ForwardIterator __first,
00821 _ForwardIterator __last, std::forward_iterator_tag)
00822 {
00823 const size_type __n = std::distance(__first, __last);
00824 this->_M_impl._M_start = this->_M_allocate(__n);
00825 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
00826 this->_M_impl._M_finish =
00827 std::__uninitialized_copy_a(__first, __last,
00828 this->_M_impl._M_start,
00829 _M_get_Tp_allocator());
00830 }
00831
00832
00833
00834
00835
00836
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
00846 template<typename _InputIterator>
00847 void
00848 _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
00849 __false_type)
00850 {
00851 typedef typename std::iterator_traits<_InputIterator>::
00852 iterator_category _IterCategory;
00853 _M_assign_aux(__first, __last, _IterCategory());
00854 }
00855
00856
00857 template<typename _InputIterator>
00858 void
00859 _M_assign_aux(_InputIterator __first, _InputIterator __last,
00860 std::input_iterator_tag);
00861
00862
00863 template<typename _ForwardIterator>
00864 void
00865 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
00866 std::forward_iterator_tag);
00867
00868
00869
00870 void
00871 _M_fill_assign(size_type __n, const value_type& __val);
00872
00873
00874
00875
00876
00877 template<typename _Integer>
00878 void
00879 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
00880 __true_type)
00881 {
00882 _M_fill_insert(__pos, static_cast<size_type>(__n),
00883 static_cast<value_type>(__val));
00884 }
00885
00886
00887 template<typename _InputIterator>
00888 void
00889 _M_insert_dispatch(iterator __pos, _InputIterator __first,
00890 _InputIterator __last, __false_type)
00891 {
00892 typedef typename std::iterator_traits<_InputIterator>::
00893 iterator_category _IterCategory;
00894 _M_range_insert(__pos, __first, __last, _IterCategory());
00895 }
00896
00897
00898 template<typename _InputIterator>
00899 void
00900 _M_range_insert(iterator __pos, _InputIterator __first,
00901 _InputIterator __last, std::input_iterator_tag);
00902
00903
00904 template<typename _ForwardIterator>
00905 void
00906 _M_range_insert(iterator __pos, _ForwardIterator __first,
00907 _ForwardIterator __last, std::forward_iterator_tag);
00908
00909
00910
00911 void
00912 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
00913
00914
00915 void
00916 _M_insert_aux(iterator __position, const value_type& __x);
00917 };
00918
00919
00930 template<typename _Tp, typename _Alloc>
00931 inline bool
00932 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00933 { return (__x.size() == __y.size()
00934 && std::equal(__x.begin(), __x.end(), __y.begin())); }
00935
00947 template<typename _Tp, typename _Alloc>
00948 inline bool
00949 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00950 { return std::lexicographical_compare(__x.begin(), __x.end(),
00951 __y.begin(), __y.end()); }
00952
00954 template<typename _Tp, typename _Alloc>
00955 inline bool
00956 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00957 { return !(__x == __y); }
00958
00960 template<typename _Tp, typename _Alloc>
00961 inline bool
00962 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00963 { return __y < __x; }
00964
00966 template<typename _Tp, typename _Alloc>
00967 inline bool
00968 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00969 { return !(__y < __x); }
00970
00972 template<typename _Tp, typename _Alloc>
00973 inline bool
00974 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
00975 { return !(__x < __y); }
00976
00978 template<typename _Tp, typename _Alloc>
00979 inline void
00980 swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
00981 { __x.swap(__y); }
00982 }
00983
00984 #endif