# 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