1 // Profiling vector implementation -*- C++ -*-
 
    3 // Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
    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 3, or (at your option)
 
   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.
 
   16 // Under Section 7 of GPL version 3, you are granted additional
 
   17 // permissions described in the GCC Runtime Library Exception, version
 
   18 // 3.1, as published by the Free Software Foundation.
 
   20 // You should have received a copy of the GNU General Public License along
 
   21 // with this library; see the file COPYING3.  If not see
 
   22 // <http://www.gnu.org/licenses/>.
 
   24 /** @file profile/vector
 
   25  *  This file is a GNU profile extension to the Standard C++ Library.
 
   28 #ifndef _GLIBCXX_PROFILE_VECTOR
 
   29 #define _GLIBCXX_PROFILE_VECTOR 1
 
   33 #include <profile/base.h>
 
   34 #include <profile/iterator_tracker.h>
 
   36 namespace std _GLIBCXX_VISIBILITY(default)
 
   40   template<typename _Tp,
 
   41       typename _Allocator = std::allocator<_Tp> >
 
   43     : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
 
   45       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
 
   47       typedef typename _Base::iterator _Base_iterator;
 
   48       typedef typename _Base::const_iterator _Base_const_iterator;
 
   50 #if __cplusplus >= 201103L
 
   51       typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
 
   55       typedef typename _Base::reference             reference;
 
   56       typedef typename _Base::const_reference       const_reference;
 
   58       typedef __iterator_tracker<_Base_iterator, vector>
 
   60       typedef __iterator_tracker<_Base_const_iterator, vector>
 
   63       typedef typename _Base::size_type             size_type;
 
   64       typedef typename _Base::difference_type       difference_type;
 
   66       typedef _Tp                  value_type;
 
   67       typedef _Allocator               allocator_type;
 
   68       typedef typename _Base::pointer               pointer;
 
   69       typedef typename _Base::const_pointer         const_pointer;
 
   70       typedef std::reverse_iterator<iterator>       reverse_iterator;
 
   71       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
   74       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
 
   77       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
 
   79       // 23.2.4.1 construct/copy/destroy:
 
   81       vector() _GLIBCXX_NOEXCEPT
 
   84         __profcxx_vector_construct(this, this->capacity());
 
   85         __profcxx_vector_construct2(this);
 
   89       vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
 
   92         __profcxx_vector_construct(this, this->capacity());
 
   93         __profcxx_vector_construct2(this);
 
   96 #if __cplusplus >= 201103L
 
   98       vector(size_type __n, const _Allocator& __a = _Allocator())
 
  101         __profcxx_vector_construct(this, this->capacity());
 
  102         __profcxx_vector_construct2(this);
 
  105       vector(size_type __n, const _Tp& __value,
 
  106         const _Allocator& __a = _Allocator())
 
  107       :  _Base(__n, __value, __a)
 
  109         __profcxx_vector_construct(this, this->capacity());
 
  110         __profcxx_vector_construct2(this);
 
  114       vector(size_type __n, const _Tp& __value = _Tp(),
 
  115         const _Allocator& __a = _Allocator())
 
  116       : _Base(__n, __value, __a)
 
  118         __profcxx_vector_construct(this, this->capacity());
 
  119         __profcxx_vector_construct2(this);
 
  123 #if __cplusplus >= 201103L
 
  124       template<typename _InputIterator,
 
  125           typename = std::_RequireInputIter<_InputIterator>>
 
  127       template<typename _InputIterator>
 
  129         vector(_InputIterator __first, _InputIterator __last,
 
  130           const _Allocator& __a = _Allocator())
 
  131    : _Base(__first, __last, __a)
 
  133      __profcxx_vector_construct(this, this->capacity());
 
  134      __profcxx_vector_construct2(this);
 
  137       vector(const vector& __x)
 
  140         __profcxx_vector_construct(this, this->capacity());
 
  141         __profcxx_vector_construct2(this);
 
  144       /// Construction from a release-mode vector
 
  145       vector(const _Base& __x)
 
  148         __profcxx_vector_construct(this, this->capacity());
 
  149         __profcxx_vector_construct2(this);
 
  152 #if __cplusplus >= 201103L
 
  153       vector(vector&& __x) noexcept
 
  154       : _Base(std::move(__x))
 
  156         __profcxx_vector_construct(this, this->capacity());
 
  157         __profcxx_vector_construct2(this);
 
  160       vector(const _Base& __x, const _Allocator& __a)
 
  163         __profcxx_vector_construct(this, this->capacity());
 
  164         __profcxx_vector_construct2(this);
 
  167       vector(vector&& __x, const _Allocator& __a)
 
  168       : _Base(std::move(__x), __a)
 
  170         __profcxx_vector_construct(this, this->capacity());
 
  171         __profcxx_vector_construct2(this);
 
  174       vector(initializer_list<value_type> __l,
 
  175         const allocator_type& __a = allocator_type())
 
  176       : _Base(__l, __a) { }
 
  179       ~vector() _GLIBCXX_NOEXCEPT
 
  181         __profcxx_vector_destruct(this, this->capacity(), this->size());
 
  182         __profcxx_vector_destruct2(this);
 
  186       operator=(const vector& __x)
 
  188         static_cast<_Base&>(*this) = __x;
 
  192 #if __cplusplus >= 201103L
 
  194       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
 
  196    __profcxx_vector_destruct(this, this->capacity(), this->size());
 
  197    __profcxx_vector_destruct2(this);
 
  198    static_cast<_Base&>(*this) = std::move(__x);
 
  203       operator=(initializer_list<value_type> __l)
 
  205    static_cast<_Base&>(*this) = __l;
 
  211       using _Base::get_allocator;
 
  216       begin() _GLIBCXX_NOEXCEPT
 
  217       { return iterator(_Base::begin(), this); }
 
  220       begin() const _GLIBCXX_NOEXCEPT
 
  221       { return const_iterator(_Base::begin(), this); }
 
  224       end() _GLIBCXX_NOEXCEPT
 
  225       { return iterator(_Base::end(), this); }
 
  228       end() const _GLIBCXX_NOEXCEPT
 
  229       { return const_iterator(_Base::end(), this); }
 
  232       rbegin() _GLIBCXX_NOEXCEPT
 
  233       { return reverse_iterator(end()); }
 
  235       const_reverse_iterator
 
  236       rbegin() const _GLIBCXX_NOEXCEPT
 
  237       { return const_reverse_iterator(end()); }
 
  240       rend() _GLIBCXX_NOEXCEPT
 
  241       { return reverse_iterator(begin()); }
 
  243       const_reverse_iterator
 
  244       rend() const _GLIBCXX_NOEXCEPT
 
  245       { return const_reverse_iterator(begin()); }
 
  247 #if __cplusplus >= 201103L
 
  249       cbegin() const noexcept
 
  250       { return const_iterator(_Base::begin(), this); }
 
  253       cend() const noexcept
 
  254       { return const_iterator(_Base::end(), this); }
 
  256       const_reverse_iterator
 
  257       crbegin() const noexcept
 
  258       { return const_reverse_iterator(end()); }
 
  260       const_reverse_iterator
 
  261       crend() const noexcept
 
  262       { return const_reverse_iterator(begin()); }
 
  265       // 23.2.4.2 capacity:
 
  267       using _Base::max_size;
 
  269 #if __cplusplus >= 201103L
 
  271       resize(size_type __sz)
 
  273         __profcxx_vector_invalid_operator(this);
 
  274         _M_profile_resize(this, this->capacity(), __sz);
 
  279       resize(size_type __sz, const _Tp& __c)
 
  281         __profcxx_vector_invalid_operator(this);
 
  282         _M_profile_resize(this, this->capacity(), __sz);
 
  283         _Base::resize(__sz, __c);
 
  287       resize(size_type __sz, _Tp __c = _Tp())
 
  289         __profcxx_vector_invalid_operator(this);
 
  290         _M_profile_resize(this, this->capacity(), __sz);
 
  291         _Base::resize(__sz, __c);
 
  295 #if __cplusplus >= 201103L
 
  296       using _Base::shrink_to_fit;
 
  303       operator[](size_type __n) _GLIBCXX_NOEXCEPT
 
  305         __profcxx_vector_invalid_operator(this);
 
  306         return _M_base()[__n];
 
  309       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
 
  311         __profcxx_vector_invalid_operator(this);
 
  312         return _M_base()[__n];
 
  318       front() _GLIBCXX_NOEXCEPT
 
  320         return _Base::front();
 
  324       front() const _GLIBCXX_NOEXCEPT
 
  326    return _Base::front();
 
  330       back() _GLIBCXX_NOEXCEPT
 
  332    return _Base::back();
 
  336       back() const _GLIBCXX_NOEXCEPT
 
  338    return _Base::back();
 
  341       // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  342       // DR 464. Suggestion for new member functions in standard containers.
 
  345       // 23.2.4.3 modifiers:
 
  347       push_back(const _Tp& __x)
 
  349         size_type __old_size = this->capacity();
 
  350    _Base::push_back(__x);
 
  351         _M_profile_resize(this, __old_size, this->capacity());
 
  354 #if __cplusplus >= 201103L
 
  358         size_type __old_size = this->capacity();
 
  359         _Base::push_back(std::move(__x));
 
  360         _M_profile_resize(this, __old_size, this->capacity());
 
  366 #if __cplusplus >= 201103L
 
  367       insert(const_iterator __position, const _Tp& __x)
 
  369       insert(iterator __position, const _Tp& __x)
 
  372         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
 
  374         size_type __old_size = this->capacity();
 
  375    _Base_iterator __res = _Base::insert(__position.base(), __x);
 
  376         _M_profile_resize(this, __old_size, this->capacity());
 
  377    return iterator(__res, this);
 
  380 #if __cplusplus >= 201103L
 
  382       insert(const_iterator __position, _Tp&& __x)
 
  384         __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
 
  386         size_type __old_size = this->capacity();
 
  387    _Base_iterator __res = _Base::insert(__position.base(), __x);
 
  388         _M_profile_resize(this, __old_size, this->capacity());
 
  389    return iterator(__res, this);
 
  392       template<typename... _Args>
 
  394         emplace(const_iterator __position, _Args&&... __args)
 
  396      _Base_iterator __res = _Base::emplace(__position.base(),
 
  397                        std::forward<_Args>(__args)...);
 
  398      return iterator(__res, this);
 
  402       insert(const_iterator __position, initializer_list<value_type> __l)
 
  403       { return this->insert(__position, __l.begin(), __l.end()); }
 
  406 #if __cplusplus >= 201103L
 
  416 #if __cplusplus >= 201103L
 
  417       noexcept(_Alloc_traits::_S_nothrow_swap())
 
  423 #if __cplusplus >= 201103L
 
  425       insert(const_iterator __position, size_type __n, const _Tp& __x)
 
  427         __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
 
  429         size_type __old_size = this->capacity();
 
  430         _Base_iterator __res = _Base::insert(__position, __n, __x);
 
  431         _M_profile_resize(this, __old_size, this->capacity());
 
  432    return iterator(__res, this);
 
  436       insert(iterator __position, size_type __n, const _Tp& __x)
 
  438         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
 
  440         size_type __old_size = this->capacity();
 
  441         _Base::insert(__position, __n, __x);
 
  442         _M_profile_resize(this, __old_size, this->capacity());
 
  446 #if __cplusplus >= 201103L
 
  447       template<typename _InputIterator,
 
  448           typename = std::_RequireInputIter<_InputIterator>>
 
  450    insert(const_iterator __position,
 
  451           _InputIterator __first, _InputIterator __last)
 
  453      __profcxx_vector_insert(this, __position.base() - _Base::cbegin(),
 
  455      size_type __old_size = this->capacity();
 
  456      _Base_iterator __res = _Base::insert(__position, __first, __last);
 
  457      _M_profile_resize(this, __old_size, this->capacity());
 
  458      return iterator(__res, this);
 
  461       template<typename _InputIterator>
 
  463    insert(iterator __position,
 
  464           _InputIterator __first, _InputIterator __last)
 
  466      __profcxx_vector_insert(this, __position.base() - _Base::begin(),
 
  468      size_type __old_size = this->capacity();
 
  469      _Base::insert(__position, __first, __last);
 
  470      _M_profile_resize(this, __old_size, this->capacity());
 
  475 #if __cplusplus >= 201103L
 
  476       erase(const_iterator __position)
 
  478       erase(iterator __position)   
 
  481    _Base_iterator __res = _Base::erase(__position.base());
 
  482    return iterator(__res, this);
 
  486 #if __cplusplus >= 201103L
 
  487       erase(const_iterator __first, const_iterator __last)
 
  489       erase(iterator __first, iterator __last)
 
  492    // _GLIBCXX_RESOLVE_LIB_DEFECTS
 
  493    // 151. can't currently clear() empty container
 
  494    _Base_iterator __res = _Base::erase(__first.base(), __last.base());
 
  495    return iterator(__res, this);
 
  499       clear() _GLIBCXX_NOEXCEPT
 
  501         __profcxx_vector_destruct(this, this->capacity(), this->size());
 
  502         __profcxx_vector_destruct2(this);
 
  506       inline void _M_profile_find() const 
 
  508         __profcxx_vector_find(this, size()); 
 
  511       inline void _M_profile_iterate(int __rewind = 0) const 
 
  513         __profcxx_vector_iterate(this); 
 
  517       void _M_profile_resize(void* obj, size_type __old_size, 
 
  518                              size_type __new_size)
 
  520         if (__old_size < __new_size) {
 
  521           __profcxx_vector_resize(this, this->size(), __new_size);
 
  522           __profcxx_vector_resize2(this, this->size(), __new_size);
 
  527   template<typename _Tp, typename _Alloc>
 
  529     operator==(const vector<_Tp, _Alloc>& __lhs,
 
  530            const vector<_Tp, _Alloc>& __rhs)
 
  531     { return __lhs._M_base() == __rhs._M_base(); }
 
  533   template<typename _Tp, typename _Alloc>
 
  535     operator!=(const vector<_Tp, _Alloc>& __lhs,
 
  536            const vector<_Tp, _Alloc>& __rhs)
 
  537     { return __lhs._M_base() != __rhs._M_base(); }
 
  539   template<typename _Tp, typename _Alloc>
 
  541     operator<(const vector<_Tp, _Alloc>& __lhs,
 
  542           const vector<_Tp, _Alloc>& __rhs)
 
  543     { return __lhs._M_base() < __rhs._M_base(); }
 
  545   template<typename _Tp, typename _Alloc>
 
  547     operator<=(const vector<_Tp, _Alloc>& __lhs,
 
  548            const vector<_Tp, _Alloc>& __rhs)
 
  549     { return __lhs._M_base() <= __rhs._M_base(); }
 
  551   template<typename _Tp, typename _Alloc>
 
  553     operator>=(const vector<_Tp, _Alloc>& __lhs,
 
  554            const vector<_Tp, _Alloc>& __rhs)
 
  555     { return __lhs._M_base() >= __rhs._M_base(); }
 
  557   template<typename _Tp, typename _Alloc>
 
  559     operator>(const vector<_Tp, _Alloc>& __lhs,
 
  560           const vector<_Tp, _Alloc>& __rhs)
 
  561     { return __lhs._M_base() > __rhs._M_base(); }
 
  563   template<typename _Tp, typename _Alloc>
 
  565     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
 
  566     { __lhs.swap(__rhs); }
 
  568 #if __cplusplus >= 201103L
 
  569   template<typename _Tp, typename _Alloc>
 
  571     swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
 
  572     { __lhs.swap(__rhs); }
 
  574   template<typename _Tp, typename _Alloc>
 
  576     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
 
  577     { __lhs.swap(__rhs); }
 
  580 } // namespace __profile
 
  582 #if __cplusplus >= 201103L
 
  584   /// std::hash specialization for vector<bool>.
 
  585   template<typename _Alloc>
 
  586     struct hash<__profile::vector<bool, _Alloc>>
 
  587     : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
 
  590       operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
 
  591       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()