libstdc++

profile/vector

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