Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Profiling vector implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2009-2013 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 3, 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. // 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.
  19.  
  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/>.
  23.  
  24. /** @file profile/vector
  25.  *  This file is a GNU profile extension to the Standard C++ Library.
  26.  */
  27.  
  28. #ifndef _GLIBCXX_PROFILE_VECTOR
  29. #define _GLIBCXX_PROFILE_VECTOR 1
  30.  
  31. #include <vector>
  32. #include <utility>
  33. #include <profile/base.h>
  34. #include <profile/iterator_tracker.h>
  35.  
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. namespace __profile
  39. {
  40.   template<typename _Tp,
  41.            typename _Allocator = std::allocator<_Tp> >
  42.     class vector
  43.     : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
  44.     {
  45.       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
  46.  
  47. #if __cplusplus >= 201103L
  48.       typedef __gnu_cxx::__alloc_traits<_Allocator>  _Alloc_traits;
  49. #endif
  50.  
  51.     public:
  52.       typedef typename _Base::reference             reference;
  53.       typedef typename _Base::const_reference       const_reference;
  54.  
  55.       typedef __iterator_tracker<typename _Base::iterator, vector>
  56.                                                     iterator;
  57.       typedef __iterator_tracker<typename _Base::const_iterator, vector>
  58.                                                     const_iterator;
  59.  
  60.       typedef typename _Base::size_type             size_type;
  61.       typedef typename _Base::difference_type       difference_type;
  62.  
  63.       typedef _Tp                                   value_type;
  64.       typedef _Allocator                            allocator_type;
  65.       typedef typename _Base::pointer               pointer;
  66.       typedef typename _Base::const_pointer         const_pointer;
  67.       typedef std::reverse_iterator<iterator>       reverse_iterator;
  68.       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  69.      
  70.       _Base&
  71.       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  72.  
  73.       const _Base&
  74.       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  75.  
  76.       // 23.2.4.1 construct/copy/destroy:
  77.       explicit
  78.       vector(const _Allocator& __a = _Allocator())
  79.       : _Base(__a)
  80.       {
  81.         __profcxx_vector_construct(this, this->capacity());
  82.         __profcxx_vector_construct2(this);
  83.       }
  84.  
  85. #if __cplusplus >= 201103L
  86.       explicit
  87.       vector(size_type __n, const _Allocator& __a = _Allocator())
  88.       : _Base(__n, __a)
  89.       {
  90.         __profcxx_vector_construct(this, this->capacity());
  91.         __profcxx_vector_construct2(this);
  92.       }
  93.  
  94.       vector(size_type __n, const _Tp& __value,
  95.              const _Allocator& __a = _Allocator())
  96.       :  _Base(__n, __value, __a)
  97.       {
  98.         __profcxx_vector_construct(this, this->capacity());
  99.         __profcxx_vector_construct2(this);
  100.       }
  101. #else
  102.       explicit
  103.       vector(size_type __n, const _Tp& __value = _Tp(),
  104.              const _Allocator& __a = _Allocator())
  105.       : _Base(__n, __value, __a)
  106.       {
  107.         __profcxx_vector_construct(this, this->capacity());
  108.         __profcxx_vector_construct2(this);
  109.       }
  110. #endif
  111.  
  112. #if __cplusplus >= 201103L
  113.       template<typename _InputIterator,
  114.                typename = std::_RequireInputIter<_InputIterator>>
  115. #else
  116.       template<typename _InputIterator>
  117. #endif
  118.         vector(_InputIterator __first, _InputIterator __last,
  119.                const _Allocator& __a = _Allocator())
  120.         : _Base(__first, __last, __a)
  121.         {
  122.           __profcxx_vector_construct(this, this->capacity());
  123.           __profcxx_vector_construct2(this);
  124.         }
  125.  
  126.       vector(const vector& __x)
  127.       : _Base(__x)
  128.       {
  129.         __profcxx_vector_construct(this, this->capacity());
  130.         __profcxx_vector_construct2(this);
  131.       }
  132.  
  133.       /// Construction from a release-mode vector
  134.       vector(const _Base& __x)
  135.       : _Base(__x)
  136.       {
  137.         __profcxx_vector_construct(this, this->capacity());
  138.         __profcxx_vector_construct2(this);
  139.       }
  140.  
  141. #if __cplusplus >= 201103L
  142.       vector(vector&& __x) noexcept
  143.       : _Base(std::move(__x))
  144.       {
  145.         __profcxx_vector_construct(this, this->capacity());
  146.         __profcxx_vector_construct2(this);
  147.       }
  148.  
  149.       vector(const _Base& __x, const _Allocator& __a)
  150.       : _Base(__x, __a)
  151.       {
  152.         __profcxx_vector_construct(this, this->capacity());
  153.         __profcxx_vector_construct2(this);
  154.       }
  155.  
  156.       vector(vector&& __x, const _Allocator& __a) noexcept
  157.       : _Base(std::move(__x), __a)
  158.       {
  159.         __profcxx_vector_construct(this, this->capacity());
  160.         __profcxx_vector_construct2(this);
  161.       }
  162.  
  163.       vector(initializer_list<value_type> __l,
  164.              const allocator_type& __a = allocator_type())
  165.       : _Base(__l, __a) { }
  166. #endif
  167.  
  168.       ~vector() _GLIBCXX_NOEXCEPT
  169.       {
  170.         __profcxx_vector_destruct(this, this->capacity(), this->size());
  171.         __profcxx_vector_destruct2(this);
  172.       }
  173.  
  174.       vector&
  175.       operator=(const vector& __x)
  176.       {
  177.         static_cast<_Base&>(*this) = __x;
  178.         return *this;
  179.       }
  180.  
  181. #if __cplusplus >= 201103L
  182.       vector&
  183.       operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
  184.       {
  185.         __profcxx_vector_destruct(this, this->capacity(), this->size());
  186.         __profcxx_vector_destruct2(this);
  187.         static_cast<_Base&>(*this) = std::move(__x);
  188.         return *this;
  189.       }
  190.  
  191.       vector&
  192.       operator=(initializer_list<value_type> __l)
  193.       {
  194.         static_cast<_Base&>(*this) = __l;
  195.         return *this;
  196.       }
  197. #endif
  198.  
  199.       using _Base::assign;
  200.       using _Base::get_allocator;
  201.  
  202.  
  203.       // iterators:
  204.       iterator
  205.       begin() _GLIBCXX_NOEXCEPT
  206.       { return iterator(_Base::begin(), this); }
  207.  
  208.       const_iterator
  209.       begin() const _GLIBCXX_NOEXCEPT
  210.       { return const_iterator(_Base::begin(), this); }
  211.  
  212.       iterator
  213.       end() _GLIBCXX_NOEXCEPT
  214.       { return iterator(_Base::end(), this); }
  215.  
  216.       const_iterator
  217.       end() const _GLIBCXX_NOEXCEPT
  218.       { return const_iterator(_Base::end(), this); }
  219.  
  220.       reverse_iterator
  221.       rbegin() _GLIBCXX_NOEXCEPT
  222.       { return reverse_iterator(end()); }
  223.  
  224.       const_reverse_iterator
  225.       rbegin() const _GLIBCXX_NOEXCEPT
  226.       { return const_reverse_iterator(end()); }
  227.  
  228.       reverse_iterator
  229.       rend() _GLIBCXX_NOEXCEPT
  230.       { return reverse_iterator(begin()); }
  231.  
  232.       const_reverse_iterator
  233.       rend() const _GLIBCXX_NOEXCEPT
  234.       { return const_reverse_iterator(begin()); }
  235.  
  236. #if __cplusplus >= 201103L
  237.       const_iterator
  238.       cbegin() const noexcept
  239.       { return const_iterator(_Base::begin(), this); }
  240.  
  241.       const_iterator
  242.       cend() const noexcept
  243.       { return const_iterator(_Base::end(), this); }
  244.  
  245.       const_reverse_iterator
  246.       crbegin() const noexcept
  247.       { return const_reverse_iterator(end()); }
  248.  
  249.       const_reverse_iterator
  250.       crend() const noexcept
  251.       { return const_reverse_iterator(begin()); }
  252. #endif
  253.  
  254.       // 23.2.4.2 capacity:
  255.       using _Base::size;
  256.       using _Base::max_size;
  257.  
  258. #if __cplusplus >= 201103L
  259.       void
  260.       resize(size_type __sz)
  261.       {
  262.         __profcxx_vector_invalid_operator(this);
  263.         _M_profile_resize(this, this->capacity(), __sz);
  264.         _Base::resize(__sz);
  265.       }
  266.  
  267.       void
  268.       resize(size_type __sz, const _Tp& __c)
  269.       {
  270.         __profcxx_vector_invalid_operator(this);
  271.         _M_profile_resize(this, this->capacity(), __sz);
  272.         _Base::resize(__sz, __c);
  273.       }
  274. #else
  275.       void
  276.       resize(size_type __sz, _Tp __c = _Tp())
  277.       {
  278.         __profcxx_vector_invalid_operator(this);
  279.         _M_profile_resize(this, this->capacity(), __sz);
  280.         _Base::resize(__sz, __c);
  281.       }
  282. #endif
  283.  
  284. #if __cplusplus >= 201103L
  285.       using _Base::shrink_to_fit;
  286. #endif
  287.  
  288.       using _Base::empty;
  289.  
  290.       // element access:
  291.       reference
  292.       operator[](size_type __n)
  293.       {
  294.         __profcxx_vector_invalid_operator(this);
  295.         return _M_base()[__n];
  296.       }
  297.       const_reference
  298.       operator[](size_type __n) const
  299.       {
  300.         __profcxx_vector_invalid_operator(this);
  301.         return _M_base()[__n];
  302.       }
  303.  
  304.       using _Base::at;
  305.  
  306.       reference
  307.       front()
  308.       {
  309.         return _Base::front();
  310.       }
  311.  
  312.       const_reference
  313.       front() const
  314.       {
  315.         return _Base::front();
  316.       }
  317.  
  318.       reference
  319.       back()
  320.       {
  321.         return _Base::back();
  322.       }
  323.  
  324.       const_reference
  325.       back() const
  326.       {
  327.         return _Base::back();
  328.       }
  329.  
  330.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  331.       // DR 464. Suggestion for new member functions in standard containers.
  332.       using _Base::data;
  333.  
  334.       // 23.2.4.3 modifiers:
  335.       void
  336.       push_back(const _Tp& __x)
  337.       {
  338.         size_type __old_size = this->capacity();
  339.         _Base::push_back(__x);
  340.         _M_profile_resize(this, __old_size, this->capacity());
  341.       }
  342.  
  343. #if __cplusplus >= 201103L
  344.       void
  345.       push_back(_Tp&& __x)
  346.       {
  347.         size_type __old_size = this->capacity();
  348.         _Base::push_back(std::move(__x));
  349.         _M_profile_resize(this, __old_size, this->capacity());
  350.       }
  351.  
  352. #endif
  353.  
  354.       iterator
  355.       insert(iterator __position, const _Tp& __x)
  356.       {
  357.         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
  358.                                 this->size());
  359.         size_type __old_size = this->capacity();
  360.         typename _Base::iterator __res = _Base::insert(__position.base(), __x);
  361.         _M_profile_resize(this, __old_size, this->capacity());
  362.         return iterator(__res, this);
  363.       }
  364.  
  365. #if __cplusplus >= 201103L
  366.       iterator
  367.       insert(iterator __position, _Tp&& __x)
  368.       {
  369.         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
  370.                                 this->size());
  371.         size_type __old_size = this->capacity();
  372.         typename _Base::iterator __res = _Base::insert(__position.base(), __x);
  373.         _M_profile_resize(this, __old_size, this->capacity());
  374.         return iterator(__res, this);
  375.       }
  376.  
  377.       template<typename... _Args>
  378.         iterator
  379.         emplace(iterator __position, _Args&&... __args)
  380.         {
  381.           typename _Base::iterator __res
  382.             = _Base::emplace(__position.base(),
  383.                              std::forward<_Args>(__args)...);
  384.           return iterator(__res, this);
  385.         }
  386.  
  387.       void
  388.       insert(iterator __position, initializer_list<value_type> __l)
  389.       { this->insert(__position, __l.begin(), __l.end()); }
  390. #endif
  391.  
  392. #if __cplusplus >= 201103L
  393.       void
  394.       swap(vector&& __x)
  395.       {
  396.         _Base::swap(__x);
  397.       }
  398. #endif
  399.  
  400.       void
  401.       swap(vector& __x)
  402. #if __cplusplus >= 201103L
  403.                         noexcept(_Alloc_traits::_S_nothrow_swap())
  404. #endif
  405.       {
  406.         _Base::swap(__x);
  407.       }
  408.  
  409.       void
  410.       insert(iterator __position, size_type __n, const _Tp& __x)
  411.       {
  412.         __profcxx_vector_insert(this, __position.base() - _Base::begin(),
  413.                                 this->size());
  414.         size_type __old_size = this->capacity();
  415.         _Base::insert(__position, __n, __x);
  416.         _M_profile_resize(this, __old_size, this->capacity());
  417.       }
  418.  
  419. #if __cplusplus >= 201103L
  420.       template<typename _InputIterator,
  421.                typename = std::_RequireInputIter<_InputIterator>>
  422. #else
  423.       template<typename _InputIterator>
  424. #endif
  425.       void
  426.       insert(iterator __position,
  427.              _InputIterator __first, _InputIterator __last)
  428.       {
  429.         __profcxx_vector_insert(this, __position.base()-_Base::begin(),
  430.                                 this->size());
  431.         size_type __old_size = this->capacity();
  432.         _Base::insert(__position, __first, __last);
  433.         _M_profile_resize(this, __old_size, this->capacity());
  434.       }
  435.  
  436.  
  437.       iterator
  438.       erase(iterator __position)
  439.       {
  440.         typename _Base::iterator __res = _Base::erase(__position.base());
  441.         return iterator(__res, this);
  442.       }
  443.  
  444.       iterator
  445.       erase(iterator __first, iterator __last)
  446.       {
  447.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  448.         // 151. can't currently clear() empty container
  449.         typename _Base::iterator __res = _Base::erase(__first.base(),
  450.                                                       __last.base());
  451.         return iterator(__res, this);
  452.       }
  453.  
  454.       void
  455.       clear() _GLIBCXX_NOEXCEPT
  456.       {
  457.         __profcxx_vector_destruct(this, this->capacity(), this->size());
  458.         __profcxx_vector_destruct2(this);
  459.         _Base::clear();
  460.       }
  461.  
  462.       inline void _M_profile_find() const
  463.       {
  464.         __profcxx_vector_find(this, size());
  465.       }
  466.  
  467.       inline void _M_profile_iterate(int __rewind = 0) const
  468.       {
  469.         __profcxx_vector_iterate(this);
  470.       }
  471.  
  472.     private:
  473.       void _M_profile_resize(void* obj, size_type __old_size,
  474.                              size_type __new_size)
  475.       {
  476.         if (__old_size < __new_size) {
  477.           __profcxx_vector_resize(this, this->size(), __new_size);
  478.           __profcxx_vector_resize2(this, this->size(), __new_size);
  479.         }
  480.       }
  481.     };
  482.  
  483.   template<typename _Tp, typename _Alloc>
  484.     inline bool
  485.     operator==(const vector<_Tp, _Alloc>& __lhs,
  486.            const vector<_Tp, _Alloc>& __rhs)
  487.     { return __lhs._M_base() == __rhs._M_base(); }
  488.  
  489.   template<typename _Tp, typename _Alloc>
  490.     inline bool
  491.     operator!=(const vector<_Tp, _Alloc>& __lhs,
  492.            const vector<_Tp, _Alloc>& __rhs)
  493.     { return __lhs._M_base() != __rhs._M_base(); }
  494.  
  495.   template<typename _Tp, typename _Alloc>
  496.     inline bool
  497.     operator<(const vector<_Tp, _Alloc>& __lhs,
  498.           const vector<_Tp, _Alloc>& __rhs)
  499.     { return __lhs._M_base() < __rhs._M_base(); }
  500.  
  501.   template<typename _Tp, typename _Alloc>
  502.     inline bool
  503.     operator<=(const vector<_Tp, _Alloc>& __lhs,
  504.            const vector<_Tp, _Alloc>& __rhs)
  505.     { return __lhs._M_base() <= __rhs._M_base(); }
  506.  
  507.   template<typename _Tp, typename _Alloc>
  508.     inline bool
  509.     operator>=(const vector<_Tp, _Alloc>& __lhs,
  510.            const vector<_Tp, _Alloc>& __rhs)
  511.     { return __lhs._M_base() >= __rhs._M_base(); }
  512.  
  513.   template<typename _Tp, typename _Alloc>
  514.     inline bool
  515.     operator>(const vector<_Tp, _Alloc>& __lhs,
  516.           const vector<_Tp, _Alloc>& __rhs)
  517.     { return __lhs._M_base() > __rhs._M_base(); }
  518.  
  519.   template<typename _Tp, typename _Alloc>
  520.     inline void
  521.     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
  522.     { __lhs.swap(__rhs); }
  523.  
  524. #if __cplusplus >= 201103L
  525.   template<typename _Tp, typename _Alloc>
  526.     inline void
  527.     swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
  528.     { __lhs.swap(__rhs); }
  529.  
  530.   template<typename _Tp, typename _Alloc>
  531.     inline void
  532.     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
  533.     { __lhs.swap(__rhs); }
  534. #endif
  535.  
  536. } // namespace __profile
  537.  
  538. #if __cplusplus >= 201103L
  539.   // DR 1182.
  540.   /// std::hash specialization for vector<bool>.
  541.   template<typename _Alloc>
  542.     struct hash<__profile::vector<bool, _Alloc>>
  543.     : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
  544.     {
  545.       size_t
  546.       operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
  547.       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
  548.           (__b._M_base()); }
  549.     };
  550. #endif
  551.  
  552. } // namespace std
  553.  
  554. #endif
  555.