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