Home | History | Annotate | Download | only in binomial_heap_base_
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005-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 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 binomial_heap_base_/split_join_fn_imps.hpp
     38  * Contains an implementation class for a base of binomial heaps.
     39  */
     40 
     41 PB_DS_CLASS_T_DEC
     42 template<typename Pred>
     43 void
     44 PB_DS_CLASS_C_DEC::
     45 split(Pred pred, PB_DS_CLASS_C_DEC& other)
     46 {
     47   PB_DS_ASSERT_VALID_COND((*this),true)
     48   PB_DS_ASSERT_VALID_COND(other,true)
     49 
     50   other.clear();
     51   if (base_type::empty())
     52     {
     53       PB_DS_ASSERT_VALID_COND((*this),true)
     54       PB_DS_ASSERT_VALID_COND(other,true)
     55       return;
     56     }
     57 
     58   base_type::to_linked_list();
     59   node_pointer p_out = base_type::prune(pred);
     60   while (p_out != 0)
     61     {
     62       _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0);
     63       --base_type::m_size;
     64       ++other.m_size;
     65 
     66       node_pointer p_next = p_out->m_p_next_sibling;
     67       p_out->m_p_l_child = p_out->m_p_prev_or_parent = 0;
     68       p_out->m_metadata = 0;
     69 
     70       p_out->m_p_next_sibling = other.m_p_root;
     71       if (other.m_p_root != 0)
     72 	other.m_p_root->m_p_prev_or_parent = p_out;
     73 
     74       other.m_p_root = p_out;
     75       other.m_p_root = other.fix(other.m_p_root);
     76       p_out = p_next;
     77     }
     78 
     79   PB_DS_ASSERT_VALID_COND(other,true)
     80   node_pointer p_cur = base_type::m_p_root;
     81   base_type::m_p_root = 0;
     82 
     83   while (p_cur != 0)
     84     {
     85       node_pointer p_next = p_cur->m_p_next_sibling;
     86       p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0;
     87       p_cur->m_metadata = 0;
     88       p_cur->m_p_next_sibling = base_type::m_p_root;
     89 
     90       if (base_type::m_p_root != 0)
     91 	base_type::m_p_root->m_p_prev_or_parent = p_cur;
     92 
     93       base_type::m_p_root = p_cur;
     94       base_type::m_p_root = fix(base_type::m_p_root);
     95       p_cur = p_next;
     96     }
     97 
     98   m_p_max = 0;
     99   PB_DS_ASSERT_VALID_COND((*this),true)
    100   PB_DS_ASSERT_VALID_COND(other,true)
    101 }
    102 
    103 PB_DS_CLASS_T_DEC
    104 inline void
    105 PB_DS_CLASS_C_DEC::
    106 join(PB_DS_CLASS_C_DEC& other)
    107 {
    108   PB_DS_ASSERT_VALID_COND((*this),true)
    109   PB_DS_ASSERT_VALID_COND(other,true)
    110 
    111   node_pointer p_other = other.m_p_root;
    112   if (p_other != 0)
    113     do
    114       {
    115 	node_pointer p_next = p_other->m_p_next_sibling;
    116 	std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent);
    117 	p_other = p_next;
    118       }
    119     while (p_other != 0);
    120 
    121   base_type::m_p_root = join(base_type::m_p_root, other.m_p_root);
    122   base_type::m_size += other.m_size;
    123   m_p_max = 0;
    124 
    125   other.m_p_root = 0;
    126   other.m_size = 0;
    127   other.m_p_max = 0;
    128 
    129   PB_DS_ASSERT_VALID_COND((*this),true)
    130   PB_DS_ASSERT_VALID_COND(other,true)
    131 }
    132 
    133 PB_DS_CLASS_T_DEC
    134 inline typename PB_DS_CLASS_C_DEC::node_pointer
    135 PB_DS_CLASS_C_DEC::
    136 join(node_pointer p_lhs, node_pointer p_rhs) const
    137 {
    138   node_pointer p_ret = 0;
    139   node_pointer p_cur = 0;
    140 
    141   while (p_lhs != 0 || p_rhs != 0)
    142     {
    143       if (p_rhs == 0)
    144 	{
    145 	  if (p_cur == 0)
    146 	    p_ret = p_cur = p_lhs;
    147 	  else
    148 	    {
    149 	      p_cur->m_p_next_sibling = p_lhs;
    150 	      p_lhs->m_p_prev_or_parent = p_cur;
    151 	    }
    152 	  p_cur = p_lhs = 0;
    153 	}
    154       else if (p_lhs == 0 || p_rhs->m_metadata < p_lhs->m_metadata)
    155 	{
    156 	  if (p_cur == 0)
    157 	    {
    158 	      p_ret = p_cur = p_rhs;
    159 	      p_rhs = p_rhs->m_p_prev_or_parent;
    160 	    }
    161 	  else
    162 	    {
    163 	      p_cur->m_p_next_sibling = p_rhs;
    164 	      p_rhs = p_rhs->m_p_prev_or_parent;
    165 	      p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur;
    166 	      p_cur = p_cur->m_p_next_sibling;
    167 	    }
    168 	}
    169       else if (p_lhs->m_metadata < p_rhs->m_metadata)
    170 	{
    171 	  if (p_cur == 0)
    172 	    p_ret = p_cur = p_lhs;
    173 	  else
    174 	    {
    175 	      p_cur->m_p_next_sibling = p_lhs;
    176 	      p_lhs->m_p_prev_or_parent = p_cur;
    177 	      p_cur = p_cur->m_p_next_sibling;
    178 	    }
    179 	  p_lhs = p_cur->m_p_next_sibling;
    180 	}
    181       else
    182 	{
    183 	  node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent;
    184 	  p_rhs->m_p_next_sibling = p_lhs;
    185 	  p_lhs = fix(p_rhs);
    186 	  p_rhs = p_next_rhs;
    187 	}
    188     }
    189 
    190   if (p_cur != 0)
    191     p_cur->m_p_next_sibling = 0;
    192 
    193   if (p_ret != 0)
    194     p_ret->m_p_prev_or_parent = 0;
    195 
    196   return p_ret;
    197 }
    198