Home | History | Annotate | Download | only in bin_search_tree_
      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 bin_search_tree_/constructors_destructor_fn_imps.hpp
     38  * Contains an implementation class for bin_search_tree_.
     39  */
     40 
     41 PB_DS_CLASS_T_DEC
     42 typename PB_DS_CLASS_C_DEC::node_allocator
     43 PB_DS_CLASS_C_DEC::s_node_allocator;
     44 
     45 PB_DS_CLASS_T_DEC
     46 PB_DS_CLASS_C_DEC::
     47 PB_DS_BIN_TREE_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0)
     48 {
     49   initialize();
     50   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
     51 }
     52 
     53 PB_DS_CLASS_T_DEC
     54 PB_DS_CLASS_C_DEC::
     55 PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn) :
     56   Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0)
     57 {
     58   initialize();
     59   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
     60 }
     61 
     62 PB_DS_CLASS_T_DEC
     63 PB_DS_CLASS_C_DEC::
     64 PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) :
     65   Cmp_Fn(r_cmp_fn),
     66   node_update(r_node_update),
     67   m_p_head(s_node_allocator.allocate(1)),
     68   m_size(0)
     69 {
     70   initialize();
     71   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
     72 }
     73 
     74 PB_DS_CLASS_T_DEC
     75 PB_DS_CLASS_C_DEC::
     76 PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC& other) :
     77 #ifdef _GLIBCXX_DEBUG
     78   debug_base(other),
     79 #endif
     80 #ifdef PB_DS_TREE_TRACE
     81   PB_DS_TREE_TRACE_BASE_C_DEC(other),
     82 #endif
     83   Cmp_Fn(other),
     84   node_update(other),
     85   m_p_head(s_node_allocator.allocate(1)),
     86   m_size(0)
     87 {
     88   initialize();
     89   m_size = other.m_size;
     90   PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
     91 
     92     __try
     93       {
     94         m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent);
     95         if (m_p_head->m_p_parent != 0)
     96 	  m_p_head->m_p_parent->m_p_parent = m_p_head;
     97         m_size = other.m_size;
     98         initialize_min_max();
     99       }
    100     __catch(...)
    101       {
    102         _GLIBCXX_DEBUG_ONLY(debug_base::clear();)
    103 	s_node_allocator.deallocate(m_p_head, 1);
    104         __throw_exception_again;
    105       }
    106   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
    107 }
    108 
    109 PB_DS_CLASS_T_DEC
    110 void
    111 PB_DS_CLASS_C_DEC::
    112 swap(PB_DS_CLASS_C_DEC& other)
    113 {
    114   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
    115   PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
    116   value_swap(other);
    117   std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other);
    118   PB_DS_STRUCT_ONLY_ASSERT_VALID((*this))
    119   PB_DS_STRUCT_ONLY_ASSERT_VALID(other)
    120 }
    121 
    122 PB_DS_CLASS_T_DEC
    123 void
    124 PB_DS_CLASS_C_DEC::
    125 value_swap(PB_DS_CLASS_C_DEC& other)
    126 {
    127   _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);)
    128   std::swap(m_p_head, other.m_p_head);
    129   std::swap(m_size, other.m_size);
    130 }
    131 
    132 PB_DS_CLASS_T_DEC
    133 PB_DS_CLASS_C_DEC::
    134 ~PB_DS_BIN_TREE_NAME()
    135 {
    136   clear();
    137   s_node_allocator.deallocate(m_p_head, 1);
    138 }
    139 
    140 PB_DS_CLASS_T_DEC
    141 void
    142 PB_DS_CLASS_C_DEC::
    143 initialize()
    144 {
    145   m_p_head->m_p_parent = 0;
    146   m_p_head->m_p_left = m_p_head;
    147   m_p_head->m_p_right = m_p_head;
    148   m_size = 0;
    149 }
    150 
    151 PB_DS_CLASS_T_DEC
    152 typename PB_DS_CLASS_C_DEC::node_pointer
    153 PB_DS_CLASS_C_DEC::
    154 recursive_copy_node(const node_pointer p_nd)
    155 {
    156   if (p_nd == 0)
    157     return (0);
    158 
    159   node_pointer p_ret = s_node_allocator.allocate(1);
    160   __try
    161     {
    162       new (p_ret) node(*p_nd);
    163     }
    164   __catch(...)
    165     {
    166       s_node_allocator.deallocate(p_ret, 1);
    167       __throw_exception_again;
    168     }
    169 
    170   p_ret->m_p_left = p_ret->m_p_right = 0;
    171 
    172   __try
    173     {
    174       p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left);
    175       p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right);
    176     }
    177   __catch(...)
    178     {
    179       clear_imp(p_ret);
    180       __throw_exception_again;
    181     }
    182 
    183   if (p_ret->m_p_left != 0)
    184     p_ret->m_p_left->m_p_parent = p_ret;
    185 
    186   if (p_ret->m_p_right != 0)
    187     p_ret->m_p_right->m_p_parent = p_ret;
    188 
    189   PB_DS_ASSERT_NODE_CONSISTENT(p_ret)
    190   return p_ret;
    191 }
    192 
    193 PB_DS_CLASS_T_DEC
    194 void
    195 PB_DS_CLASS_C_DEC::
    196 initialize_min_max()
    197 {
    198   if (m_p_head->m_p_parent == 0)
    199     {
    200       m_p_head->m_p_left = m_p_head->m_p_right = m_p_head;
    201       return;
    202     }
    203 
    204   {
    205     node_pointer p_min = m_p_head->m_p_parent;
    206     while (p_min->m_p_left != 0)
    207       p_min = p_min->m_p_left;
    208     m_p_head->m_p_left = p_min;
    209   }
    210 
    211   {
    212     node_pointer p_max = m_p_head->m_p_parent;
    213     while (p_max->m_p_right != 0)
    214       p_max = p_max->m_p_right;
    215     m_p_head->m_p_right = p_max;
    216   }
    217 }
    218 
    219