163d1a8abSmrg // -*- C++ -*-
263d1a8abSmrg 
3*ec02198aSmrg // Copyright (C) 2005-2020 Free Software Foundation, Inc.
463d1a8abSmrg //
563d1a8abSmrg // This file is part of the GNU ISO C++ Library.  This library is free
663d1a8abSmrg // software; you can redistribute it and/or modify it under the terms
763d1a8abSmrg // of the GNU General Public License as published by the Free Software
863d1a8abSmrg // Foundation; either version 3, or (at your option) any later
963d1a8abSmrg // version.
1063d1a8abSmrg 
1163d1a8abSmrg // This library is distributed in the hope that it will be useful, but
1263d1a8abSmrg // WITHOUT ANY WARRANTY; without even the implied warranty of
1363d1a8abSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1463d1a8abSmrg // General Public License for more details.
1563d1a8abSmrg 
1663d1a8abSmrg // Under Section 7 of GPL version 3, you are granted additional
1763d1a8abSmrg // permissions described in the GCC Runtime Library Exception, version
1863d1a8abSmrg // 3.1, as published by the Free Software Foundation.
1963d1a8abSmrg 
2063d1a8abSmrg // You should have received a copy of the GNU General Public License and
2163d1a8abSmrg // a copy of the GCC Runtime Library Exception along with this program;
2263d1a8abSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2363d1a8abSmrg // <http://www.gnu.org/licenses/>.
2463d1a8abSmrg 
2563d1a8abSmrg // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
2663d1a8abSmrg 
2763d1a8abSmrg // Permission to use, copy, modify, sell, and distribute this software
2863d1a8abSmrg // is hereby granted without fee, provided that the above copyright
2963d1a8abSmrg // notice appears in all copies, and that both that copyright notice
3063d1a8abSmrg // and this permission notice appear in supporting documentation. None
3163d1a8abSmrg // of the above authors, nor IBM Haifa Research Laboratories, make any
3263d1a8abSmrg // representation about the suitability of this software for any
3363d1a8abSmrg // purpose. It is provided "as is" without express or implied
3463d1a8abSmrg // warranty.
3563d1a8abSmrg 
3663d1a8abSmrg /**
3763d1a8abSmrg  * @file binary_heap_/erase_fn_imps.hpp
3863d1a8abSmrg  * Contains an implementation class for a binary_heap.
3963d1a8abSmrg  */
4063d1a8abSmrg 
41*ec02198aSmrg #ifdef PB_DS_CLASS_C_DEC
42*ec02198aSmrg 
4363d1a8abSmrg PB_DS_CLASS_T_DEC
4463d1a8abSmrg void
4563d1a8abSmrg PB_DS_CLASS_C_DEC::
clear()4663d1a8abSmrg clear()
4763d1a8abSmrg {
4863d1a8abSmrg   for (size_type i = 0; i < m_size; ++i)
4963d1a8abSmrg     erase_at(m_a_entries, i, s_no_throw_copies_ind);
5063d1a8abSmrg 
5163d1a8abSmrg   __try
5263d1a8abSmrg     {
5363d1a8abSmrg       const size_type new_size = resize_policy::get_new_size_for_arbitrary(0);
5463d1a8abSmrg       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
5563d1a8abSmrg       resize_policy::notify_arbitrary(new_size);
5663d1a8abSmrg       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
5763d1a8abSmrg       m_actual_size = new_size;
5863d1a8abSmrg       m_a_entries = new_entries;
5963d1a8abSmrg     }
6063d1a8abSmrg   __catch(...)
6163d1a8abSmrg     { }
6263d1a8abSmrg 
6363d1a8abSmrg   m_size = 0;
6463d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
6563d1a8abSmrg }
6663d1a8abSmrg 
6763d1a8abSmrg PB_DS_CLASS_T_DEC
6863d1a8abSmrg void
6963d1a8abSmrg PB_DS_CLASS_C_DEC::
erase_at(entry_pointer a_entries,size_type i,false_type)7063d1a8abSmrg erase_at(entry_pointer a_entries, size_type i, false_type)
7163d1a8abSmrg {
7263d1a8abSmrg   a_entries[i]->~value_type();
7363d1a8abSmrg   s_value_allocator.deallocate(a_entries[i], 1);
7463d1a8abSmrg }
7563d1a8abSmrg 
7663d1a8abSmrg PB_DS_CLASS_T_DEC
7763d1a8abSmrg void
7863d1a8abSmrg PB_DS_CLASS_C_DEC::
erase_at(entry_pointer,size_type,true_type)7963d1a8abSmrg erase_at(entry_pointer, size_type, true_type)
8063d1a8abSmrg { }
8163d1a8abSmrg 
8263d1a8abSmrg PB_DS_CLASS_T_DEC
8363d1a8abSmrg inline void
8463d1a8abSmrg PB_DS_CLASS_C_DEC::
pop()8563d1a8abSmrg pop()
8663d1a8abSmrg {
8763d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
8863d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(!empty());
8963d1a8abSmrg 
9063d1a8abSmrg   pop_heap();
9163d1a8abSmrg   erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind);
9263d1a8abSmrg   resize_for_erase_if_needed();
9363d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(m_size > 0);
9463d1a8abSmrg   --m_size;
9563d1a8abSmrg 
9663d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
9763d1a8abSmrg }
9863d1a8abSmrg 
9963d1a8abSmrg PB_DS_CLASS_T_DEC
10063d1a8abSmrg template<typename Pred>
10163d1a8abSmrg typename PB_DS_CLASS_C_DEC::size_type
10263d1a8abSmrg PB_DS_CLASS_C_DEC::
erase_if(Pred pred)10363d1a8abSmrg erase_if(Pred pred)
10463d1a8abSmrg {
10563d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
10663d1a8abSmrg 
10763d1a8abSmrg   typedef typename entry_pred<value_type, Pred, _Alloc, simple_value>::type
10863d1a8abSmrg     pred_t;
10963d1a8abSmrg 
11063d1a8abSmrg   const size_type left = partition(pred_t(pred));
11163d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(m_size >= left);
11263d1a8abSmrg   const size_type ersd = m_size - left;
11363d1a8abSmrg   for (size_type i = left; i < m_size; ++i)
11463d1a8abSmrg     erase_at(m_a_entries, i, s_no_throw_copies_ind);
11563d1a8abSmrg 
11663d1a8abSmrg   __try
11763d1a8abSmrg     {
11863d1a8abSmrg       const size_type new_size =
11963d1a8abSmrg 	resize_policy::get_new_size_for_arbitrary(left);
12063d1a8abSmrg 
12163d1a8abSmrg       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
12263d1a8abSmrg       std::copy(m_a_entries, m_a_entries + left, new_entries);
12363d1a8abSmrg       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
12463d1a8abSmrg       m_actual_size = new_size;
12563d1a8abSmrg       resize_policy::notify_arbitrary(m_actual_size);
12663d1a8abSmrg     }
12763d1a8abSmrg   __catch(...)
12863d1a8abSmrg     { };
12963d1a8abSmrg 
13063d1a8abSmrg   m_size = left;
13163d1a8abSmrg   make_heap();
13263d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
13363d1a8abSmrg   return ersd;
13463d1a8abSmrg }
13563d1a8abSmrg 
13663d1a8abSmrg PB_DS_CLASS_T_DEC
13763d1a8abSmrg inline void
13863d1a8abSmrg PB_DS_CLASS_C_DEC::
erase(point_iterator it)13963d1a8abSmrg erase(point_iterator it)
14063d1a8abSmrg {
14163d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
14263d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(!empty());
14363d1a8abSmrg 
14463d1a8abSmrg   const size_type fix_pos = it.m_p_e - m_a_entries;
14563d1a8abSmrg   std::swap(*it.m_p_e, m_a_entries[m_size - 1]);
14663d1a8abSmrg   erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind);
14763d1a8abSmrg   resize_for_erase_if_needed();
14863d1a8abSmrg 
14963d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(m_size > 0);
15063d1a8abSmrg   --m_size;
15163d1a8abSmrg   _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size);
15263d1a8abSmrg 
15363d1a8abSmrg   if (fix_pos != m_size)
15463d1a8abSmrg     fix(m_a_entries + fix_pos);
15563d1a8abSmrg 
15663d1a8abSmrg   PB_DS_ASSERT_VALID((*this))
15763d1a8abSmrg }
15863d1a8abSmrg 
15963d1a8abSmrg PB_DS_CLASS_T_DEC
16063d1a8abSmrg inline void
16163d1a8abSmrg PB_DS_CLASS_C_DEC::
resize_for_erase_if_needed()16263d1a8abSmrg resize_for_erase_if_needed()
16363d1a8abSmrg {
16463d1a8abSmrg   if (!resize_policy::resize_needed_for_shrink(m_size))
16563d1a8abSmrg     return;
16663d1a8abSmrg 
16763d1a8abSmrg   __try
16863d1a8abSmrg     {
16963d1a8abSmrg       const size_type new_size = resize_policy::get_new_size_for_shrink();
17063d1a8abSmrg       entry_pointer new_entries = s_entry_allocator.allocate(new_size);
17163d1a8abSmrg       resize_policy::notify_shrink_resize();
17263d1a8abSmrg 
17363d1a8abSmrg       _GLIBCXX_DEBUG_ASSERT(m_size > 0);
17463d1a8abSmrg       std::copy(m_a_entries, m_a_entries + m_size - 1, new_entries);
17563d1a8abSmrg       s_entry_allocator.deallocate(m_a_entries, m_actual_size);
17663d1a8abSmrg       m_actual_size = new_size;
17763d1a8abSmrg       m_a_entries = new_entries;
17863d1a8abSmrg     }
17963d1a8abSmrg   __catch(...)
18063d1a8abSmrg     { }
18163d1a8abSmrg }
18263d1a8abSmrg 
18363d1a8abSmrg PB_DS_CLASS_T_DEC
18463d1a8abSmrg template<typename Pred>
18563d1a8abSmrg typename PB_DS_CLASS_C_DEC::size_type
18663d1a8abSmrg PB_DS_CLASS_C_DEC::
partition(Pred pred)18763d1a8abSmrg partition(Pred pred)
18863d1a8abSmrg {
18963d1a8abSmrg   size_type left = 0;
19063d1a8abSmrg   size_type right = m_size - 1;
19163d1a8abSmrg 
19263d1a8abSmrg   while (right + 1 != left)
19363d1a8abSmrg     {
19463d1a8abSmrg       _GLIBCXX_DEBUG_ASSERT(left <= m_size);
19563d1a8abSmrg 
19663d1a8abSmrg       if (!pred(m_a_entries[left]))
19763d1a8abSmrg 	++left;
19863d1a8abSmrg       else if (pred(m_a_entries[right]))
19963d1a8abSmrg 	--right;
20063d1a8abSmrg       else
20163d1a8abSmrg 	{
20263d1a8abSmrg 	  _GLIBCXX_DEBUG_ASSERT(left < right);
20363d1a8abSmrg 	  std::swap(m_a_entries[left], m_a_entries[right]);
20463d1a8abSmrg 	  ++left;
20563d1a8abSmrg 	  --right;
20663d1a8abSmrg 	}
20763d1a8abSmrg     }
20863d1a8abSmrg 
20963d1a8abSmrg   return left;
21063d1a8abSmrg }
211*ec02198aSmrg #endif
212