Home | History | Annotate | Download | only in profile
      1 // Profiling vector implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 2, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // You should have received a copy of the GNU General Public License along
     17 // with this library; see the file COPYING.  If not, write to the Free
     18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
     19 // USA.
     20 
     21 // As a special exception, you may use this file as part of a free software
     22 // library without restriction.  Specifically, if other files instantiate
     23 // templates or use macros or inline functions from this file, or you compile
     24 // this file and link it with other files to produce an executable, this
     25 // file does not by itself cause the resulting executable to be covered by
     26 // the GNU General Public License.  This exception does not however
     27 // invalidate any other reasons why the executable file might be covered by
     28 // the GNU General Public License.
     29 
     30 /** @file profile/vector
     31  *  This file is a GNU profile extension to the Standard C++ Library.
     32  */
     33 
     34 #ifndef _GLIBCXX_PROFILE_VECTOR
     35 #define _GLIBCXX_PROFILE_VECTOR 1
     36 
     37 #include <vector>
     38 #include <utility>
     39 #include <profile/base.h>
     40 #include <profile/iterator_tracker.h>
     41 
     42 namespace std _GLIBCXX_VISIBILITY(default)
     43 {
     44 namespace __profile
     45 {
     46   template<typename _Tp,
     47 	   typename _Allocator = std::allocator<_Tp> >
     48     class vector
     49     : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
     50     {
     51       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
     52 
     53     public:
     54       typedef typename _Base::reference             reference;
     55       typedef typename _Base::const_reference       const_reference;
     56 
     57       typedef __iterator_tracker<typename _Base::iterator, vector>
     58                                                     iterator;
     59       typedef __iterator_tracker<typename _Base::const_iterator, vector>
     60 				                    const_iterator;
     61 
     62       typedef typename _Base::size_type             size_type;
     63       typedef typename _Base::difference_type       difference_type;
     64 
     65       typedef _Tp				    value_type;
     66       typedef _Allocator			    allocator_type;
     67       typedef typename _Base::pointer               pointer;
     68       typedef typename _Base::const_pointer         const_pointer;
     69       typedef std::reverse_iterator<iterator>       reverse_iterator;
     70       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     71       
     72       _Base&
     73       _M_base()       { return *this; }
     74 
     75       const _Base&
     76       _M_base() const { return *this; }
     77 
     78       // 23.2.4.1 construct/copy/destroy:
     79       explicit
     80       vector(const _Allocator& __a = _Allocator())
     81       : _Base(__a)
     82       { 
     83         __profcxx_vector_construct(this, this->capacity());
     84         __profcxx_vector_construct2(this);
     85       }
     86 
     87 #ifdef __GXX_EXPERIMENTAL_CXX0X__
     88       explicit
     89       vector(size_type __n)
     90       :  _Base(__n)
     91       { 
     92         __profcxx_vector_construct(this, this->capacity());
     93         __profcxx_vector_construct2(this);
     94       }
     95 
     96       vector(size_type __n, const _Tp& __value,
     97 	     const _Allocator& __a = _Allocator())
     98       :  _Base(__n, __value, __a)
     99       { 
    100         __profcxx_vector_construct(this, this->capacity());
    101         __profcxx_vector_construct2(this);
    102       }
    103 #else
    104       explicit
    105       vector(size_type __n, const _Tp& __value = _Tp(),
    106 	     const _Allocator& __a = _Allocator())
    107       :  _Base(__n, __value, __a)
    108       { 
    109         __profcxx_vector_construct(this, this->capacity());
    110         __profcxx_vector_construct2(this);
    111       }
    112 #endif
    113 
    114       template<class _InputIterator>
    115         vector(_InputIterator __first, _InputIterator __last,
    116 	       const _Allocator& __a = _Allocator())
    117 	: _Base(__first, __last, __a)
    118       { 
    119         __profcxx_vector_construct(this, this->capacity());
    120         __profcxx_vector_construct2(this);
    121       }
    122 
    123       vector(const vector& __x)
    124       : _Base(__x) 
    125       { 
    126         __profcxx_vector_construct(this, this->capacity());
    127         __profcxx_vector_construct2(this);
    128       }
    129 
    130       /// Construction from a release-mode vector
    131       vector(const _Base& __x)
    132       : _Base(__x) 
    133       { 
    134         __profcxx_vector_construct(this, this->capacity());
    135         __profcxx_vector_construct2(this);
    136       }
    137 
    138 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    139       vector(vector&& __x)
    140       : _Base(std::move(__x))
    141       {
    142         __profcxx_vector_construct(this, this->capacity());
    143         __profcxx_vector_construct2(this);
    144       }
    145 
    146       vector(initializer_list<value_type> __l,
    147 	     const allocator_type& __a = allocator_type())
    148       : _Base(__l, __a) { }
    149 #endif
    150 
    151       ~vector() {
    152         __profcxx_vector_destruct(this, this->capacity(), this->size());
    153         __profcxx_vector_destruct2(this);
    154       }
    155 
    156       vector&
    157       operator=(const vector& __x)
    158       {
    159         static_cast<_Base&>(*this) = __x;
    160         return *this;
    161       }
    162 
    163 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    164       vector&
    165       operator=(vector&& __x)
    166       {
    167 	// NB: DR 1204.
    168 	// NB: DR 675.
    169 	this->clear();
    170 	this->swap(__x);
    171 	return *this;
    172       }
    173 
    174       vector&
    175       operator=(initializer_list<value_type> __l)
    176       {
    177 	static_cast<_Base&>(*this) = __l;
    178 	return *this;
    179       }
    180 #endif
    181 
    182       using _Base::assign;
    183       using _Base::get_allocator;
    184 
    185 
    186       // iterators:
    187       iterator
    188       begin()
    189       { return iterator(_Base::begin(), this); }
    190 
    191       const_iterator
    192       begin() const
    193       { return const_iterator(_Base::begin(), this); }
    194 
    195       iterator
    196       end()
    197       { return iterator(_Base::end(), this); }
    198 
    199       const_iterator
    200       end() const
    201       { return const_iterator(_Base::end(), this); }
    202 
    203       reverse_iterator
    204       rbegin()
    205       { return reverse_iterator(end()); }
    206 
    207       const_reverse_iterator
    208       rbegin() const
    209       { return const_reverse_iterator(end()); }
    210 
    211       reverse_iterator
    212       rend()
    213       { return reverse_iterator(begin()); }
    214 
    215       const_reverse_iterator
    216       rend() const
    217       { return const_reverse_iterator(begin()); }
    218 
    219 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    220       const_iterator
    221       cbegin() const
    222       { return const_iterator(_Base::begin(), this); }
    223 
    224       const_iterator
    225       cend() const
    226       { return const_iterator(_Base::end(), this); }
    227 
    228       const_reverse_iterator
    229       crbegin() const
    230       { return const_reverse_iterator(end()); }
    231 
    232       const_reverse_iterator
    233       crend() const
    234       { return const_reverse_iterator(begin()); }
    235 #endif
    236 
    237       // 23.2.4.2 capacity:
    238       using _Base::size;
    239       using _Base::max_size;
    240 
    241 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    242       void
    243       resize(size_type __sz)
    244       {
    245         __profcxx_vector_invalid_operator(this);
    246         _M_profile_resize(this, this->capacity(), __sz);
    247         _Base::resize(__sz);
    248       }
    249 
    250       void
    251       resize(size_type __sz, const _Tp& __c)
    252       {
    253         __profcxx_vector_invalid_operator(this);
    254         _M_profile_resize(this, this->capacity(), __sz);
    255         _Base::resize(__sz, __c);
    256       }
    257 #else
    258       void
    259       resize(size_type __sz, _Tp __c = _Tp())
    260       {
    261         __profcxx_vector_invalid_operator(this);
    262         _M_profile_resize(this, this->capacity(), __sz);
    263         _Base::resize(__sz, __c);
    264       }
    265 #endif
    266 
    267 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    268       using _Base::shrink_to_fit;
    269 #endif
    270 
    271       using _Base::empty;
    272 
    273       // element access:
    274       reference
    275       operator[](size_type __n)
    276       {
    277         __profcxx_vector_invalid_operator(this);
    278         return _M_base()[__n];
    279       }
    280       const_reference
    281       operator[](size_type __n) const
    282       {
    283         __profcxx_vector_invalid_operator(this);
    284         return _M_base()[__n];
    285       }
    286 
    287       using _Base::at;
    288 
    289       reference
    290       front()
    291       { 
    292         return _Base::front();
    293       }
    294 
    295       const_reference
    296       front() const
    297       {
    298 	return _Base::front();
    299       }
    300 
    301       reference
    302       back()
    303       {
    304 	return _Base::back();
    305       }
    306 
    307       const_reference
    308       back() const
    309       {
    310 	return _Base::back();
    311       }
    312 
    313       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    314       // DR 464. Suggestion for new member functions in standard containers.
    315       using _Base::data;
    316 
    317       // 23.2.4.3 modifiers:
    318       void
    319       push_back(const _Tp& __x)
    320       {
    321         size_type __old_size = this->capacity();
    322 	_Base::push_back(__x);
    323         _M_profile_resize(this, __old_size, this->capacity());
    324       }
    325 
    326 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    327       void
    328       push_back(_Tp&& __x)
    329       {
    330         size_type __old_size = this->capacity();
    331         _Base::push_back(__x);
    332         _M_profile_resize(this, __old_size, this->capacity());
    333       }
    334 
    335 #endif
    336 
    337       iterator
    338       insert(iterator __position, const _Tp& __x)
    339       {
    340         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
    341                                 this->size());
    342         size_type __old_size = this->capacity();
    343 	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
    344         _M_profile_resize(this, __old_size, this->capacity());
    345 	return iterator(__res, this);
    346       }
    347 
    348 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    349       iterator
    350       insert(iterator __position, _Tp&& __x)
    351       {
    352         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
    353                                 this->size());
    354         size_type __old_size = this->capacity();
    355 	typename _Base::iterator __res = _Base::insert(__position.base(), __x);
    356         _M_profile_resize(this, __old_size, this->capacity());
    357 	return iterator(__res, this);
    358       }
    359 
    360       void
    361       insert(iterator __position, initializer_list<value_type> __l)
    362       { this->insert(__position, __l.begin(), __l.end()); }
    363 #endif
    364 
    365 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    366       void
    367       swap(vector&& __x)
    368       {
    369         _Base::swap(__x);
    370       }
    371 #endif
    372 
    373       void
    374       swap(vector& __x)
    375       {
    376         _Base::swap(__x);
    377       }
    378 
    379       void
    380       insert(iterator __position, size_type __n, const _Tp& __x)
    381       {
    382         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
    383                                 this->size());
    384         size_type __old_size = this->capacity();
    385         _Base::insert(__position, __n, __x);
    386         _M_profile_resize(this, __old_size, this->capacity());
    387       }
    388 
    389       template<class _InputIterator>
    390       void
    391       insert(iterator __position,
    392              _InputIterator __first, _InputIterator __last)
    393       {
    394         __profcxx_vector_insert(this, __position.base()-_Base::begin(),
    395                                 this->size());
    396         size_type __old_size = this->capacity();
    397         _Base::insert(__position, __first, __last);
    398         _M_profile_resize(this, __old_size, this->capacity());
    399       }
    400 
    401 
    402       iterator
    403       erase(iterator __position)
    404       {
    405 	typename _Base::iterator __res = _Base::erase(__position.base());
    406 	return iterator(__res, this);
    407       }
    408 
    409       iterator
    410       erase(iterator __first, iterator __last)
    411       {
    412 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
    413 	// 151. can't currently clear() empty container
    414 	typename _Base::iterator __res = _Base::erase(__first.base(),
    415                                                       __last.base());
    416 	return iterator(__res, this);
    417       }
    418 
    419       void
    420       clear()
    421       {
    422         __profcxx_vector_destruct(this, this->capacity(), this->size());
    423         __profcxx_vector_destruct2(this);
    424         _Base::clear();
    425       }
    426 
    427       inline void _M_profile_find() const 
    428       { 
    429         __profcxx_vector_find(this, size()); 
    430       }
    431 
    432       inline void _M_profile_iterate(int __rewind = 0) const 
    433       { 
    434         __profcxx_vector_iterate(this); 
    435       }
    436 
    437     private:
    438       void _M_profile_resize(void* obj, size_type __old_size, 
    439                              size_type __new_size)
    440       {
    441         if (__old_size < __new_size) {
    442           __profcxx_vector_resize(this, this->size(), __new_size);
    443           __profcxx_vector_resize2(this, this->size(), __new_size);
    444         }
    445       }
    446     };
    447 
    448   template<typename _Tp, typename _Alloc>
    449     inline bool
    450     operator==(const vector<_Tp, _Alloc>& __lhs,
    451            const vector<_Tp, _Alloc>& __rhs)
    452     { return __lhs._M_base() == __rhs._M_base(); }
    453 
    454   template<typename _Tp, typename _Alloc>
    455     inline bool
    456     operator!=(const vector<_Tp, _Alloc>& __lhs,
    457            const vector<_Tp, _Alloc>& __rhs)
    458     { return __lhs._M_base() != __rhs._M_base(); }
    459 
    460   template<typename _Tp, typename _Alloc>
    461     inline bool
    462     operator<(const vector<_Tp, _Alloc>& __lhs,
    463           const vector<_Tp, _Alloc>& __rhs)
    464     { return __lhs._M_base() < __rhs._M_base(); }
    465 
    466   template<typename _Tp, typename _Alloc>
    467     inline bool
    468     operator<=(const vector<_Tp, _Alloc>& __lhs,
    469            const vector<_Tp, _Alloc>& __rhs)
    470     { return __lhs._M_base() <= __rhs._M_base(); }
    471 
    472   template<typename _Tp, typename _Alloc>
    473     inline bool
    474     operator>=(const vector<_Tp, _Alloc>& __lhs,
    475            const vector<_Tp, _Alloc>& __rhs)
    476     { return __lhs._M_base() >= __rhs._M_base(); }
    477 
    478   template<typename _Tp, typename _Alloc>
    479     inline bool
    480     operator>(const vector<_Tp, _Alloc>& __lhs,
    481           const vector<_Tp, _Alloc>& __rhs)
    482     { return __lhs._M_base() > __rhs._M_base(); }
    483 
    484   template<typename _Tp, typename _Alloc>
    485     inline void
    486     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
    487     { __lhs.swap(__rhs); }
    488 
    489 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    490   template<typename _Tp, typename _Alloc>
    491     inline void
    492     swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
    493     { __lhs.swap(__rhs); }
    494 
    495   template<typename _Tp, typename _Alloc>
    496     inline void
    497     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
    498     { __lhs.swap(__rhs); }
    499 #endif
    500 
    501 } // namespace __profile
    502 
    503 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    504   // DR 1182.
    505   /// std::hash specialization for vector<bool>.
    506   template<typename _Alloc>
    507     struct hash<__profile::vector<bool, _Alloc>>
    508     : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
    509     {
    510       size_t
    511       operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
    512       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
    513 	  (__b._M_base()); }
    514     };
    515 #endif
    516 
    517 } // namespace std
    518 
    519 #endif
    520