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