Subversion Repositories Kolibri OS

Rev

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

  1. // List implementation (out of line) -*- C++ -*-
  2.  
  3. // Copyright (C) 2001-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 and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /*
  26.  *
  27.  * Copyright (c) 1994
  28.  * Hewlett-Packard Company
  29.  *
  30.  * Permission to use, copy, modify, distribute and sell this software
  31.  * and its documentation for any purpose is hereby granted without fee,
  32.  * provided that the above copyright notice appear in all copies and
  33.  * that both that copyright notice and this permission notice appear
  34.  * in supporting documentation.  Hewlett-Packard Company makes no
  35.  * representations about the suitability of this software for any
  36.  * purpose.  It is provided "as is" without express or implied warranty.
  37.  *
  38.  *
  39.  * Copyright (c) 1996,1997
  40.  * Silicon Graphics Computer Systems, Inc.
  41.  *
  42.  * Permission to use, copy, modify, distribute and sell this software
  43.  * and its documentation for any purpose is hereby granted without fee,
  44.  * provided that the above copyright notice appear in all copies and
  45.  * that both that copyright notice and this permission notice appear
  46.  * in supporting documentation.  Silicon Graphics makes no
  47.  * representations about the suitability of this software for any
  48.  * purpose.  It is provided "as is" without express or implied warranty.
  49.  */
  50.  
  51. /** @file bits/list.tcc
  52.  *  This is an internal header file, included by other library headers.
  53.  *  Do not attempt to use it directly. @headername{list}
  54.  */
  55.  
  56. #ifndef _LIST_TCC
  57. #define _LIST_TCC 1
  58.  
  59. namespace std _GLIBCXX_VISIBILITY(default)
  60. {
  61. _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  62.  
  63.   template<typename _Tp, typename _Alloc>
  64.     void
  65.     _List_base<_Tp, _Alloc>::
  66.     _M_clear()
  67.     {
  68.       typedef _List_node<_Tp>  _Node;
  69.       _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next);
  70.       while (__cur != &_M_impl._M_node)
  71.         {
  72.           _Node* __tmp = __cur;
  73.           __cur = static_cast<_Node*>(__cur->_M_next);
  74. #if __cplusplus >= 201103L
  75.           _M_get_Node_allocator().destroy(__tmp);
  76. #else
  77.           _M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data));
  78. #endif
  79.           _M_put_node(__tmp);
  80.         }
  81.     }
  82.  
  83. #if __cplusplus >= 201103L
  84.   template<typename _Tp, typename _Alloc>
  85.     template<typename... _Args>
  86.       typename list<_Tp, _Alloc>::iterator
  87.       list<_Tp, _Alloc>::
  88.       emplace(iterator __position, _Args&&... __args)
  89.       {
  90.         _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
  91.         __tmp->_M_hook(__position._M_node);
  92.         return iterator(__tmp);
  93.       }
  94. #endif
  95.  
  96.   template<typename _Tp, typename _Alloc>
  97.     typename list<_Tp, _Alloc>::iterator
  98.     list<_Tp, _Alloc>::
  99.     insert(iterator __position, const value_type& __x)
  100.     {
  101.       _Node* __tmp = _M_create_node(__x);
  102.       __tmp->_M_hook(__position._M_node);
  103.       return iterator(__tmp);
  104.     }
  105.  
  106.   template<typename _Tp, typename _Alloc>
  107.     typename list<_Tp, _Alloc>::iterator
  108.     list<_Tp, _Alloc>::
  109.     erase(iterator __position)
  110.     {
  111.       iterator __ret = iterator(__position._M_node->_M_next);
  112.       _M_erase(__position);
  113.       return __ret;
  114.     }
  115.  
  116. #if __cplusplus >= 201103L
  117.   template<typename _Tp, typename _Alloc>
  118.     void
  119.     list<_Tp, _Alloc>::
  120.     _M_default_append(size_type __n)
  121.     {
  122.       size_type __i = 0;
  123.       __try
  124.         {
  125.           for (; __i < __n; ++__i)
  126.             emplace_back();
  127.         }
  128.       __catch(...)
  129.         {
  130.           for (; __i; --__i)
  131.             pop_back();
  132.           __throw_exception_again;
  133.         }
  134.     }
  135.  
  136.   template<typename _Tp, typename _Alloc>
  137.     void
  138.     list<_Tp, _Alloc>::
  139.     resize(size_type __new_size)
  140.     {
  141.       iterator __i = begin();
  142.       size_type __len = 0;
  143.       for (; __i != end() && __len < __new_size; ++__i, ++__len)
  144.         ;
  145.       if (__len == __new_size)
  146.         erase(__i, end());
  147.       else                          // __i == end()
  148.         _M_default_append(__new_size - __len);
  149.     }
  150.  
  151.   template<typename _Tp, typename _Alloc>
  152.     void
  153.     list<_Tp, _Alloc>::
  154.     resize(size_type __new_size, const value_type& __x)
  155.     {
  156.       iterator __i = begin();
  157.       size_type __len = 0;
  158.       for (; __i != end() && __len < __new_size; ++__i, ++__len)
  159.         ;
  160.       if (__len == __new_size)
  161.         erase(__i, end());
  162.       else                          // __i == end()
  163.         insert(end(), __new_size - __len, __x);
  164.     }
  165. #else
  166.   template<typename _Tp, typename _Alloc>
  167.     void
  168.     list<_Tp, _Alloc>::
  169.     resize(size_type __new_size, value_type __x)
  170.     {
  171.       iterator __i = begin();
  172.       size_type __len = 0;
  173.       for (; __i != end() && __len < __new_size; ++__i, ++__len)
  174.         ;
  175.       if (__len == __new_size)
  176.         erase(__i, end());
  177.       else                          // __i == end()
  178.         insert(end(), __new_size - __len, __x);
  179.     }
  180. #endif
  181.  
  182.   template<typename _Tp, typename _Alloc>
  183.     list<_Tp, _Alloc>&
  184.     list<_Tp, _Alloc>::
  185.     operator=(const list& __x)
  186.     {
  187.       if (this != &__x)
  188.         {
  189.           iterator __first1 = begin();
  190.           iterator __last1 = end();
  191.           const_iterator __first2 = __x.begin();
  192.           const_iterator __last2 = __x.end();
  193.           for (; __first1 != __last1 && __first2 != __last2;
  194.                ++__first1, ++__first2)
  195.             *__first1 = *__first2;
  196.           if (__first2 == __last2)
  197.             erase(__first1, __last1);
  198.           else
  199.             insert(__last1, __first2, __last2);
  200.         }
  201.       return *this;
  202.     }
  203.  
  204.   template<typename _Tp, typename _Alloc>
  205.     void
  206.     list<_Tp, _Alloc>::
  207.     _M_fill_assign(size_type __n, const value_type& __val)
  208.     {
  209.       iterator __i = begin();
  210.       for (; __i != end() && __n > 0; ++__i, --__n)
  211.         *__i = __val;
  212.       if (__n > 0)
  213.         insert(end(), __n, __val);
  214.       else
  215.         erase(__i, end());
  216.     }
  217.  
  218.   template<typename _Tp, typename _Alloc>
  219.     template <typename _InputIterator>
  220.       void
  221.       list<_Tp, _Alloc>::
  222.       _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2,
  223.                          __false_type)
  224.       {
  225.         iterator __first1 = begin();
  226.         iterator __last1 = end();
  227.         for (; __first1 != __last1 && __first2 != __last2;
  228.              ++__first1, ++__first2)
  229.           *__first1 = *__first2;
  230.         if (__first2 == __last2)
  231.           erase(__first1, __last1);
  232.         else
  233.           insert(__last1, __first2, __last2);
  234.       }
  235.  
  236.   template<typename _Tp, typename _Alloc>
  237.     void
  238.     list<_Tp, _Alloc>::
  239.     remove(const value_type& __value)
  240.     {
  241.       iterator __first = begin();
  242.       iterator __last = end();
  243.       iterator __extra = __last;
  244.       while (__first != __last)
  245.         {
  246.           iterator __next = __first;
  247.           ++__next;
  248.           if (*__first == __value)
  249.             {
  250.               // _GLIBCXX_RESOLVE_LIB_DEFECTS
  251.               // 526. Is it undefined if a function in the standard changes
  252.               // in parameters?
  253.               if (std::__addressof(*__first) != std::__addressof(__value))
  254.                 _M_erase(__first);
  255.               else
  256.                 __extra = __first;
  257.             }
  258.           __first = __next;
  259.         }
  260.       if (__extra != __last)
  261.         _M_erase(__extra);
  262.     }
  263.  
  264.   template<typename _Tp, typename _Alloc>
  265.     void
  266.     list<_Tp, _Alloc>::
  267.     unique()
  268.     {
  269.       iterator __first = begin();
  270.       iterator __last = end();
  271.       if (__first == __last)
  272.         return;
  273.       iterator __next = __first;
  274.       while (++__next != __last)
  275.         {
  276.           if (*__first == *__next)
  277.             _M_erase(__next);
  278.           else
  279.             __first = __next;
  280.           __next = __first;
  281.         }
  282.     }
  283.  
  284.   template<typename _Tp, typename _Alloc>
  285.     void
  286.     list<_Tp, _Alloc>::
  287. #if __cplusplus >= 201103L
  288.     merge(list&& __x)
  289. #else
  290.     merge(list& __x)
  291. #endif
  292.     {
  293.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  294.       // 300. list::merge() specification incomplete
  295.       if (this != &__x)
  296.         {
  297.           _M_check_equal_allocators(__x);
  298.  
  299.           iterator __first1 = begin();
  300.           iterator __last1 = end();
  301.           iterator __first2 = __x.begin();
  302.           iterator __last2 = __x.end();
  303.           while (__first1 != __last1 && __first2 != __last2)
  304.             if (*__first2 < *__first1)
  305.               {
  306.                 iterator __next = __first2;
  307.                 _M_transfer(__first1, __first2, ++__next);
  308.                 __first2 = __next;
  309.               }
  310.             else
  311.               ++__first1;
  312.           if (__first2 != __last2)
  313.             _M_transfer(__last1, __first2, __last2);
  314.         }
  315.     }
  316.  
  317.   template<typename _Tp, typename _Alloc>
  318.     template <typename _StrictWeakOrdering>
  319.       void
  320.       list<_Tp, _Alloc>::
  321. #if __cplusplus >= 201103L
  322.       merge(list&& __x, _StrictWeakOrdering __comp)
  323. #else
  324.       merge(list& __x, _StrictWeakOrdering __comp)
  325. #endif
  326.       {
  327.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  328.         // 300. list::merge() specification incomplete
  329.         if (this != &__x)
  330.           {
  331.             _M_check_equal_allocators(__x);
  332.  
  333.             iterator __first1 = begin();
  334.             iterator __last1 = end();
  335.             iterator __first2 = __x.begin();
  336.             iterator __last2 = __x.end();
  337.             while (__first1 != __last1 && __first2 != __last2)
  338.               if (__comp(*__first2, *__first1))
  339.                 {
  340.                   iterator __next = __first2;
  341.                   _M_transfer(__first1, __first2, ++__next);
  342.                   __first2 = __next;
  343.                 }
  344.               else
  345.                 ++__first1;
  346.             if (__first2 != __last2)
  347.               _M_transfer(__last1, __first2, __last2);
  348.           }
  349.       }
  350.  
  351.   template<typename _Tp, typename _Alloc>
  352.     void
  353.     list<_Tp, _Alloc>::
  354.     sort()
  355.     {
  356.       // Do nothing if the list has length 0 or 1.
  357.       if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  358.           && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  359.       {
  360.         list __carry;
  361.         list __tmp[64];
  362.         list * __fill = &__tmp[0];
  363.         list * __counter;
  364.  
  365.         do
  366.           {
  367.             __carry.splice(__carry.begin(), *this, begin());
  368.  
  369.             for(__counter = &__tmp[0];
  370.                 __counter != __fill && !__counter->empty();
  371.                 ++__counter)
  372.               {
  373.                 __counter->merge(__carry);
  374.                 __carry.swap(*__counter);
  375.               }
  376.             __carry.swap(*__counter);
  377.             if (__counter == __fill)
  378.               ++__fill;
  379.           }
  380.         while ( !empty() );
  381.  
  382.         for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
  383.           __counter->merge(*(__counter - 1));
  384.         swap( *(__fill - 1) );
  385.       }
  386.     }
  387.  
  388.   template<typename _Tp, typename _Alloc>
  389.     template <typename _Predicate>
  390.       void
  391.       list<_Tp, _Alloc>::
  392.       remove_if(_Predicate __pred)
  393.       {
  394.         iterator __first = begin();
  395.         iterator __last = end();
  396.         while (__first != __last)
  397.           {
  398.             iterator __next = __first;
  399.             ++__next;
  400.             if (__pred(*__first))
  401.               _M_erase(__first);
  402.             __first = __next;
  403.           }
  404.       }
  405.  
  406.   template<typename _Tp, typename _Alloc>
  407.     template <typename _BinaryPredicate>
  408.       void
  409.       list<_Tp, _Alloc>::
  410.       unique(_BinaryPredicate __binary_pred)
  411.       {
  412.         iterator __first = begin();
  413.         iterator __last = end();
  414.         if (__first == __last)
  415.           return;
  416.         iterator __next = __first;
  417.         while (++__next != __last)
  418.           {
  419.             if (__binary_pred(*__first, *__next))
  420.               _M_erase(__next);
  421.             else
  422.               __first = __next;
  423.             __next = __first;
  424.           }
  425.       }
  426.  
  427.   template<typename _Tp, typename _Alloc>
  428.     template <typename _StrictWeakOrdering>
  429.       void
  430.       list<_Tp, _Alloc>::
  431.       sort(_StrictWeakOrdering __comp)
  432.       {
  433.         // Do nothing if the list has length 0 or 1.
  434.         if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
  435.             && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
  436.           {
  437.             list __carry;
  438.             list __tmp[64];
  439.             list * __fill = &__tmp[0];
  440.             list * __counter;
  441.  
  442.             do
  443.               {
  444.                 __carry.splice(__carry.begin(), *this, begin());
  445.  
  446.                 for(__counter = &__tmp[0];
  447.                     __counter != __fill && !__counter->empty();
  448.                     ++__counter)
  449.                   {
  450.                     __counter->merge(__carry, __comp);
  451.                     __carry.swap(*__counter);
  452.                   }
  453.                 __carry.swap(*__counter);
  454.                 if (__counter == __fill)
  455.                   ++__fill;
  456.               }
  457.             while ( !empty() );
  458.  
  459.             for (__counter = &__tmp[1]; __counter != __fill; ++__counter)
  460.               __counter->merge(*(__counter - 1), __comp);
  461.             swap(*(__fill - 1));
  462.           }
  463.       }
  464.  
  465. _GLIBCXX_END_NAMESPACE_CONTAINER
  466. } // namespace std
  467.  
  468. #endif /* _LIST_TCC */
  469.  
  470.