libstdc++
profile/vector
Go to the documentation of this file.
00001 // Profiling vector implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2009, 2010, 2011 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License along
00021 // with this library; see the file COPYING3.  If not see
00022 // <http://www.gnu.org/licenses/>.
00023 
00024 /** @file profile/vector
00025  *  This file is a GNU profile extension to the Standard C++ Library.
00026  */
00027 
00028 #ifndef _GLIBCXX_PROFILE_VECTOR
00029 #define _GLIBCXX_PROFILE_VECTOR 1
00030 
00031 #include <vector>
00032 #include <utility>
00033 #include <profile/base.h>
00034 #include <profile/iterator_tracker.h>
00035 
00036 namespace std _GLIBCXX_VISIBILITY(default)
00037 {
00038 namespace __profile
00039 {
00040   template<typename _Tp,
00041        typename _Allocator = std::allocator<_Tp> >
00042     class vector
00043     : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
00044     {
00045       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
00046 
00047 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00048       typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
00049 #endif
00050 
00051     public:
00052       typedef typename _Base::reference             reference;
00053       typedef typename _Base::const_reference       const_reference;
00054 
00055       typedef __iterator_tracker<typename _Base::iterator, vector>
00056                                                     iterator;
00057       typedef __iterator_tracker<typename _Base::const_iterator, vector>
00058                                     const_iterator;
00059 
00060       typedef typename _Base::size_type             size_type;
00061       typedef typename _Base::difference_type       difference_type;
00062 
00063       typedef _Tp                   value_type;
00064       typedef _Allocator                allocator_type;
00065       typedef typename _Base::pointer               pointer;
00066       typedef typename _Base::const_pointer         const_pointer;
00067       typedef std::reverse_iterator<iterator>       reverse_iterator;
00068       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00069       
00070       _Base&
00071       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
00072 
00073       const _Base&
00074       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00075 
00076       // 23.2.4.1 construct/copy/destroy:
00077       explicit
00078       vector(const _Allocator& __a = _Allocator())
00079       : _Base(__a)
00080       {
00081         __profcxx_vector_construct(this, this->capacity());
00082         __profcxx_vector_construct2(this);
00083       }
00084 
00085 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00086       explicit
00087       vector(size_type __n)
00088       : _Base(__n)
00089       {
00090         __profcxx_vector_construct(this, this->capacity());
00091         __profcxx_vector_construct2(this);
00092       }
00093 
00094       vector(size_type __n, const _Tp& __value,
00095          const _Allocator& __a = _Allocator())
00096       :  _Base(__n, __value, __a)
00097       {
00098         __profcxx_vector_construct(this, this->capacity());
00099         __profcxx_vector_construct2(this);
00100       }
00101 #else
00102       explicit
00103       vector(size_type __n, const _Tp& __value = _Tp(),
00104          const _Allocator& __a = _Allocator())
00105       : _Base(__n, __value, __a)
00106       {
00107         __profcxx_vector_construct(this, this->capacity());
00108         __profcxx_vector_construct2(this);
00109       }
00110 #endif
00111 
00112       template<class _InputIterator>
00113         vector(_InputIterator __first, _InputIterator __last,
00114            const _Allocator& __a = _Allocator())
00115     : _Base(__first, __last, __a)
00116         {
00117       __profcxx_vector_construct(this, this->capacity());
00118       __profcxx_vector_construct2(this);
00119     }
00120 
00121       vector(const vector& __x)
00122       : _Base(__x) 
00123       {
00124         __profcxx_vector_construct(this, this->capacity());
00125         __profcxx_vector_construct2(this);
00126       }
00127 
00128       /// Construction from a release-mode vector
00129       vector(const _Base& __x)
00130       : _Base(__x) 
00131       { 
00132         __profcxx_vector_construct(this, this->capacity());
00133         __profcxx_vector_construct2(this);
00134       }
00135 
00136 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00137       vector(vector&& __x) noexcept
00138       : _Base(std::move(__x))
00139       {
00140         __profcxx_vector_construct(this, this->capacity());
00141         __profcxx_vector_construct2(this);
00142       }
00143 
00144       vector(const _Base& __x, const _Allocator& __a)
00145       : _Base(__x) 
00146       { 
00147         __profcxx_vector_construct(this, this->capacity());
00148         __profcxx_vector_construct2(this);
00149       }
00150 
00151       vector(vector&& __x, const _Allocator& __a) noexcept
00152       : _Base(std::move(__x), __a)
00153       {
00154         __profcxx_vector_construct(this, this->capacity());
00155         __profcxx_vector_construct2(this);
00156       }
00157 
00158       vector(initializer_list<value_type> __l,
00159          const allocator_type& __a = allocator_type())
00160       : _Base(__l, __a) { }
00161 #endif
00162 
00163       ~vector() _GLIBCXX_NOEXCEPT
00164       {
00165         __profcxx_vector_destruct(this, this->capacity(), this->size());
00166         __profcxx_vector_destruct2(this);
00167       }
00168 
00169       vector&
00170       operator=(const vector& __x)
00171       {
00172         static_cast<_Base&>(*this) = __x;
00173         return *this;
00174       }
00175 
00176 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00177       vector&
00178       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
00179       {
00180     __profcxx_vector_destruct(this, this->capacity(), this->size());
00181     __profcxx_vector_destruct2(this);
00182     static_cast<_Base&>(*this) = std::move(__x);
00183     return *this;
00184       }
00185 
00186       vector&
00187       operator=(initializer_list<value_type> __l)
00188       {
00189     static_cast<_Base&>(*this) = __l;
00190     return *this;
00191       }
00192 #endif
00193 
00194       using _Base::assign;
00195       using _Base::get_allocator;
00196 
00197 
00198       // iterators:
00199       iterator
00200       begin() _GLIBCXX_NOEXCEPT
00201       { return iterator(_Base::begin(), this); }
00202 
00203       const_iterator
00204       begin() const _GLIBCXX_NOEXCEPT
00205       { return const_iterator(_Base::begin(), this); }
00206 
00207       iterator
00208       end() _GLIBCXX_NOEXCEPT
00209       { return iterator(_Base::end(), this); }
00210 
00211       const_iterator
00212       end() const _GLIBCXX_NOEXCEPT
00213       { return const_iterator(_Base::end(), this); }
00214 
00215       reverse_iterator
00216       rbegin() _GLIBCXX_NOEXCEPT
00217       { return reverse_iterator(end()); }
00218 
00219       const_reverse_iterator
00220       rbegin() const _GLIBCXX_NOEXCEPT
00221       { return const_reverse_iterator(end()); }
00222 
00223       reverse_iterator
00224       rend() _GLIBCXX_NOEXCEPT
00225       { return reverse_iterator(begin()); }
00226 
00227       const_reverse_iterator
00228       rend() const _GLIBCXX_NOEXCEPT
00229       { return const_reverse_iterator(begin()); }
00230 
00231 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00232       const_iterator
00233       cbegin() const noexcept
00234       { return const_iterator(_Base::begin(), this); }
00235 
00236       const_iterator
00237       cend() const noexcept
00238       { return const_iterator(_Base::end(), this); }
00239 
00240       const_reverse_iterator
00241       crbegin() const noexcept
00242       { return const_reverse_iterator(end()); }
00243 
00244       const_reverse_iterator
00245       crend() const noexcept
00246       { return const_reverse_iterator(begin()); }
00247 #endif
00248 
00249       // 23.2.4.2 capacity:
00250       using _Base::size;
00251       using _Base::max_size;
00252 
00253 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00254       void
00255       resize(size_type __sz)
00256       {
00257         __profcxx_vector_invalid_operator(this);
00258         _M_profile_resize(this, this->capacity(), __sz);
00259         _Base::resize(__sz);
00260       }
00261 
00262       void
00263       resize(size_type __sz, const _Tp& __c)
00264       {
00265         __profcxx_vector_invalid_operator(this);
00266         _M_profile_resize(this, this->capacity(), __sz);
00267         _Base::resize(__sz, __c);
00268       }
00269 #else
00270       void
00271       resize(size_type __sz, _Tp __c = _Tp())
00272       {
00273         __profcxx_vector_invalid_operator(this);
00274         _M_profile_resize(this, this->capacity(), __sz);
00275         _Base::resize(__sz, __c);
00276       }
00277 #endif
00278 
00279 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00280       using _Base::shrink_to_fit;
00281 #endif
00282 
00283       using _Base::empty;
00284 
00285       // element access:
00286       reference
00287       operator[](size_type __n)
00288       {
00289         __profcxx_vector_invalid_operator(this);
00290         return _M_base()[__n];
00291       }
00292       const_reference
00293       operator[](size_type __n) const
00294       {
00295         __profcxx_vector_invalid_operator(this);
00296         return _M_base()[__n];
00297       }
00298 
00299       using _Base::at;
00300 
00301       reference
00302       front()
00303       { 
00304         return _Base::front();
00305       }
00306 
00307       const_reference
00308       front() const
00309       {
00310     return _Base::front();
00311       }
00312 
00313       reference
00314       back()
00315       {
00316     return _Base::back();
00317       }
00318 
00319       const_reference
00320       back() const
00321       {
00322     return _Base::back();
00323       }
00324 
00325       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00326       // DR 464. Suggestion for new member functions in standard containers.
00327       using _Base::data;
00328 
00329       // 23.2.4.3 modifiers:
00330       void
00331       push_back(const _Tp& __x)
00332       {
00333         size_type __old_size = this->capacity();
00334     _Base::push_back(__x);
00335         _M_profile_resize(this, __old_size, this->capacity());
00336       }
00337 
00338 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00339       void
00340       push_back(_Tp&& __x)
00341       {
00342         size_type __old_size = this->capacity();
00343         _Base::push_back(std::move(__x));
00344         _M_profile_resize(this, __old_size, this->capacity());
00345       }
00346 
00347 #endif
00348 
00349       iterator
00350       insert(iterator __position, const _Tp& __x)
00351       {
00352         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
00353                                 this->size());
00354         size_type __old_size = this->capacity();
00355     typename _Base::iterator __res = _Base::insert(__position.base(), __x);
00356         _M_profile_resize(this, __old_size, this->capacity());
00357     return iterator(__res, this);
00358       }
00359 
00360 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00361       iterator
00362       insert(iterator __position, _Tp&& __x)
00363       {
00364         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
00365                                 this->size());
00366         size_type __old_size = this->capacity();
00367     typename _Base::iterator __res = _Base::insert(__position.base(), __x);
00368         _M_profile_resize(this, __old_size, this->capacity());
00369     return iterator(__res, this);
00370       }
00371 
00372       void
00373       insert(iterator __position, initializer_list<value_type> __l)
00374       { this->insert(__position, __l.begin(), __l.end()); }
00375 #endif
00376 
00377 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00378       void
00379       swap(vector&& __x)
00380       {
00381         _Base::swap(__x);
00382       }
00383 #endif
00384 
00385       void
00386       swap(vector& __x)
00387 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00388             noexcept(_Alloc_traits::_S_nothrow_swap())
00389 #endif
00390       {
00391         _Base::swap(__x);
00392       }
00393 
00394       void
00395       insert(iterator __position, size_type __n, const _Tp& __x)
00396       {
00397         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
00398                                 this->size());
00399         size_type __old_size = this->capacity();
00400         _Base::insert(__position, __n, __x);
00401         _M_profile_resize(this, __old_size, this->capacity());
00402       }
00403 
00404       template<class _InputIterator>
00405       void
00406       insert(iterator __position,
00407              _InputIterator __first, _InputIterator __last)
00408       {
00409         __profcxx_vector_insert(this, __position.base()-_Base::begin(),
00410                                 this->size());
00411         size_type __old_size = this->capacity();
00412         _Base::insert(__position, __first, __last);
00413         _M_profile_resize(this, __old_size, this->capacity());
00414       }
00415 
00416 
00417       iterator
00418       erase(iterator __position)
00419       {
00420     typename _Base::iterator __res = _Base::erase(__position.base());
00421     return iterator(__res, this);
00422       }
00423 
00424       iterator
00425       erase(iterator __first, iterator __last)
00426       {
00427     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00428     // 151. can't currently clear() empty container
00429     typename _Base::iterator __res = _Base::erase(__first.base(),
00430                                                       __last.base());
00431     return iterator(__res, this);
00432       }
00433 
00434       void
00435       clear() _GLIBCXX_NOEXCEPT
00436       {
00437         __profcxx_vector_destruct(this, this->capacity(), this->size());
00438         __profcxx_vector_destruct2(this);
00439         _Base::clear();
00440       }
00441 
00442       inline void _M_profile_find() const 
00443       { 
00444         __profcxx_vector_find(this, size()); 
00445       }
00446 
00447       inline void _M_profile_iterate(int __rewind = 0) const 
00448       { 
00449         __profcxx_vector_iterate(this); 
00450       }
00451 
00452     private:
00453       void _M_profile_resize(void* obj, size_type __old_size, 
00454                              size_type __new_size)
00455       {
00456         if (__old_size < __new_size) {
00457           __profcxx_vector_resize(this, this->size(), __new_size);
00458           __profcxx_vector_resize2(this, this->size(), __new_size);
00459         }
00460       }
00461     };
00462 
00463   template<typename _Tp, typename _Alloc>
00464     inline bool
00465     operator==(const vector<_Tp, _Alloc>& __lhs,
00466            const vector<_Tp, _Alloc>& __rhs)
00467     { return __lhs._M_base() == __rhs._M_base(); }
00468 
00469   template<typename _Tp, typename _Alloc>
00470     inline bool
00471     operator!=(const vector<_Tp, _Alloc>& __lhs,
00472            const vector<_Tp, _Alloc>& __rhs)
00473     { return __lhs._M_base() != __rhs._M_base(); }
00474 
00475   template<typename _Tp, typename _Alloc>
00476     inline bool
00477     operator<(const vector<_Tp, _Alloc>& __lhs,
00478           const vector<_Tp, _Alloc>& __rhs)
00479     { return __lhs._M_base() < __rhs._M_base(); }
00480 
00481   template<typename _Tp, typename _Alloc>
00482     inline bool
00483     operator<=(const vector<_Tp, _Alloc>& __lhs,
00484            const vector<_Tp, _Alloc>& __rhs)
00485     { return __lhs._M_base() <= __rhs._M_base(); }
00486 
00487   template<typename _Tp, typename _Alloc>
00488     inline bool
00489     operator>=(const vector<_Tp, _Alloc>& __lhs,
00490            const vector<_Tp, _Alloc>& __rhs)
00491     { return __lhs._M_base() >= __rhs._M_base(); }
00492 
00493   template<typename _Tp, typename _Alloc>
00494     inline bool
00495     operator>(const vector<_Tp, _Alloc>& __lhs,
00496           const vector<_Tp, _Alloc>& __rhs)
00497     { return __lhs._M_base() > __rhs._M_base(); }
00498 
00499   template<typename _Tp, typename _Alloc>
00500     inline void
00501     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00502     { __lhs.swap(__rhs); }
00503 
00504 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00505   template<typename _Tp, typename _Alloc>
00506     inline void
00507     swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
00508     { __lhs.swap(__rhs); }
00509 
00510   template<typename _Tp, typename _Alloc>
00511     inline void
00512     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
00513     { __lhs.swap(__rhs); }
00514 #endif
00515 
00516 } // namespace __profile
00517 
00518 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00519   // DR 1182.
00520   /// std::hash specialization for vector<bool>.
00521   template<typename _Alloc>
00522     struct hash<__profile::vector<bool, _Alloc>>
00523     : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
00524     {
00525       size_t
00526       operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
00527       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
00528       (__b._M_base()); }
00529     };
00530 #endif
00531 
00532 } // namespace std
00533 
00534 #endif