Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*-
  2.  
  3. // Copyright (C) 2005-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 terms
  7. // of the GNU General Public License as published by the Free Software
  8. // Foundation; either version 3, or (at your option) any later
  9. // version.
  10.  
  11. // This library is distributed in the hope that it will be useful, but
  12. // WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. // 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. // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
  26.  
  27. // Permission to use, copy, modify, sell, and distribute this software
  28. // is hereby granted without fee, provided that the above copyright
  29. // notice appears in all copies, and that both that copyright notice
  30. // and this permission notice appear in supporting documentation. None
  31. // of the above authors, nor IBM Haifa Research Laboratories, make any
  32. // representation about the suitability of this software for any
  33. // purpose. It is provided "as is" without express or implied
  34. // warranty.
  35.  
  36. /**
  37.  * @file binary_heap_/erase_fn_imps.hpp
  38.  * Contains an implementation class for a binary_heap.
  39.  */
  40.  
  41. PB_DS_CLASS_T_DEC
  42. void
  43. PB_DS_CLASS_C_DEC::
  44. clear()
  45. {
  46.   for (size_type i = 0; i < m_size; ++i)
  47.     erase_at(m_a_entries, i, s_no_throw_copies_ind);
  48.  
  49.   __try
  50.     {
  51.       const size_type new_size = resize_policy::get_new_size_for_arbitrary(0);
  52.       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
  53.       resize_policy::notify_arbitrary(new_size);
  54.       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
  55.       m_actual_size = new_size;
  56.       m_a_entries = new_entries;
  57.     }
  58.   __catch(...)
  59.     { }
  60.  
  61.   m_size = 0;
  62.   PB_DS_ASSERT_VALID((*this))
  63. }
  64.  
  65. PB_DS_CLASS_T_DEC
  66. void
  67. PB_DS_CLASS_C_DEC::
  68. erase_at(entry_pointer a_entries, size_type i, false_type)
  69. {
  70.   a_entries[i]->~value_type();
  71.   s_value_allocator.deallocate(a_entries[i], 1);
  72. }
  73.  
  74. PB_DS_CLASS_T_DEC
  75. void
  76. PB_DS_CLASS_C_DEC::
  77. erase_at(entry_pointer, size_type, true_type)
  78. { }
  79.  
  80. PB_DS_CLASS_T_DEC
  81. inline void
  82. PB_DS_CLASS_C_DEC::
  83. pop()
  84. {
  85.   PB_DS_ASSERT_VALID((*this))
  86.   _GLIBCXX_DEBUG_ASSERT(!empty());
  87.  
  88.   pop_heap();
  89.   erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind);
  90.   resize_for_erase_if_needed();
  91.   _GLIBCXX_DEBUG_ASSERT(m_size > 0);
  92.   --m_size;
  93.  
  94.   PB_DS_ASSERT_VALID((*this))
  95. }
  96.  
  97. PB_DS_CLASS_T_DEC
  98. template<typename Pred>
  99. typename PB_DS_CLASS_C_DEC::size_type
  100. PB_DS_CLASS_C_DEC::
  101. erase_if(Pred pred)
  102. {
  103.   PB_DS_ASSERT_VALID((*this))
  104.  
  105.   typedef typename entry_pred<value_type, Pred, _Alloc, simple_value>::type
  106.     pred_t;
  107.  
  108.   const size_type left = partition(pred_t(pred));
  109.   _GLIBCXX_DEBUG_ASSERT(m_size >= left);
  110.   const size_type ersd = m_size - left;
  111.   for (size_type i = left; i < m_size; ++i)
  112.     erase_at(m_a_entries, i, s_no_throw_copies_ind);
  113.  
  114.   __try
  115.     {
  116.       const size_type new_size =
  117.         resize_policy::get_new_size_for_arbitrary(left);
  118.  
  119.       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
  120.       std::copy(m_a_entries, m_a_entries + left, new_entries);
  121.       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
  122.       m_actual_size = new_size;
  123.       resize_policy::notify_arbitrary(m_actual_size);
  124.     }
  125.   __catch(...)
  126.     { };
  127.  
  128.   m_size = left;
  129.   make_heap();
  130.   PB_DS_ASSERT_VALID((*this))
  131.   return ersd;
  132. }
  133.  
  134. PB_DS_CLASS_T_DEC
  135. inline void
  136. PB_DS_CLASS_C_DEC::
  137. erase(point_iterator it)
  138. {
  139.   PB_DS_ASSERT_VALID((*this))
  140.   _GLIBCXX_DEBUG_ASSERT(!empty());
  141.  
  142.   const size_type fix_pos = it.m_p_e - m_a_entries;
  143.   std::swap(*it.m_p_e, m_a_entries[m_size - 1]);
  144.   erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind);
  145.   resize_for_erase_if_needed();
  146.  
  147.   _GLIBCXX_DEBUG_ASSERT(m_size > 0);
  148.   --m_size;
  149.   _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size);
  150.  
  151.   if (fix_pos != m_size)
  152.     fix(m_a_entries + fix_pos);
  153.  
  154.   PB_DS_ASSERT_VALID((*this))
  155. }
  156.  
  157. PB_DS_CLASS_T_DEC
  158. inline void
  159. PB_DS_CLASS_C_DEC::
  160. resize_for_erase_if_needed()
  161. {
  162.   if (!resize_policy::resize_needed_for_shrink(m_size))
  163.     return;
  164.  
  165.   __try
  166.     {
  167.       const size_type new_size = resize_policy::get_new_size_for_shrink();
  168.       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
  169.       resize_policy::notify_shrink_resize();
  170.  
  171.       _GLIBCXX_DEBUG_ASSERT(m_size > 0);
  172.       std::copy(m_a_entries, m_a_entries + m_size - 1, new_entries);
  173.       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
  174.       m_actual_size = new_size;
  175.       m_a_entries = new_entries;
  176.     }
  177.   __catch(...)
  178.     { }
  179. }
  180.  
  181. PB_DS_CLASS_T_DEC
  182. template<typename Pred>
  183. typename PB_DS_CLASS_C_DEC::size_type
  184. PB_DS_CLASS_C_DEC::
  185. partition(Pred pred)
  186. {
  187.   size_type left = 0;
  188.   size_type right = m_size - 1;
  189.  
  190.   while (right + 1 != left)
  191.     {
  192.       _GLIBCXX_DEBUG_ASSERT(left <= m_size);
  193.  
  194.       if (!pred(m_a_entries[left]))
  195.         ++left;
  196.       else if (pred(m_a_entries[right]))
  197.         --right;
  198.       else
  199.         {
  200.           _GLIBCXX_DEBUG_ASSERT(left < right);
  201.           std::swap(m_a_entries[left], m_a_entries[right]);
  202.           ++left;
  203.           --right;
  204.         }
  205.     }
  206.  
  207.   return left;
  208. }
  209.