Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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