Home | History | Annotate | Download | only in pat_trie_
      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 pat_trie_/constructors_destructor_fn_imps.hpp
     38  * Contains an implementation class for pat_trie.
     39  */
     40 
     41 PB_DS_CLASS_T_DEC
     42 typename PB_DS_CLASS_C_DEC::head_allocator
     43 PB_DS_CLASS_C_DEC::s_head_allocator;
     44 
     45 PB_DS_CLASS_T_DEC
     46 typename PB_DS_CLASS_C_DEC::inode_allocator
     47 PB_DS_CLASS_C_DEC::s_inode_allocator;
     48 
     49 PB_DS_CLASS_T_DEC
     50 typename PB_DS_CLASS_C_DEC::leaf_allocator
     51 PB_DS_CLASS_C_DEC::s_leaf_allocator;
     52 
     53 PB_DS_CLASS_T_DEC
     54 PB_DS_CLASS_C_DEC::
     55 PB_DS_PAT_TRIE_NAME() :
     56   m_p_head(s_head_allocator.allocate(1)),
     57   m_size(0)
     58 {
     59   initialize();
     60   PB_DS_ASSERT_VALID((*this))
     61 }
     62 
     63 PB_DS_CLASS_T_DEC
     64 PB_DS_CLASS_C_DEC::
     65 PB_DS_PAT_TRIE_NAME(const access_traits& r_access_traits) :
     66   synth_access_traits(r_access_traits),
     67   m_p_head(s_head_allocator.allocate(1)),
     68   m_size(0)
     69 {
     70   initialize();
     71   PB_DS_ASSERT_VALID((*this))
     72 }
     73 
     74 PB_DS_CLASS_T_DEC
     75 PB_DS_CLASS_C_DEC::
     76 PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC& other) :
     77 #ifdef _GLIBCXX_DEBUG
     78   debug_base(other),
     79 #endif
     80   synth_access_traits(other),
     81   node_update(other),
     82   m_p_head(s_head_allocator.allocate(1)),
     83   m_size(0)
     84 {
     85   initialize();
     86   m_size = other.m_size;
     87   PB_DS_ASSERT_VALID(other)
     88     if (other.m_p_head->m_p_parent == 0)
     89       {
     90 	PB_DS_ASSERT_VALID((*this))
     91 	return;
     92       }
     93   __try
     94     {
     95       m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent);
     96     }
     97   __catch(...)
     98     {
     99       s_head_allocator.deallocate(m_p_head, 1);
    100       __throw_exception_again;
    101     }
    102 
    103   m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent);
    104   m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent);
    105   m_p_head->m_p_parent->m_p_parent = m_p_head;
    106   PB_DS_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_ASSERT_VALID((*this))
    115   PB_DS_ASSERT_VALID(other)
    116   value_swap(other);
    117   std::swap((access_traits& )(*this), (access_traits& )other);
    118   PB_DS_ASSERT_VALID((*this))
    119   PB_DS_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_PAT_TRIE_NAME()
    135 {
    136   clear();
    137   s_head_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   new (m_p_head) head();
    146   m_p_head->m_p_parent = 0;
    147   m_p_head->m_p_min = m_p_head;
    148   m_p_head->m_p_max = m_p_head;
    149   m_size = 0;
    150 }
    151 
    152 PB_DS_CLASS_T_DEC
    153 template<typename It>
    154 void
    155 PB_DS_CLASS_C_DEC::
    156 copy_from_range(It first_it, It last_it)
    157 {
    158   while (first_it != last_it)
    159     insert(*(first_it++));
    160 }
    161 
    162 PB_DS_CLASS_T_DEC
    163 typename PB_DS_CLASS_C_DEC::node_pointer
    164 PB_DS_CLASS_C_DEC::
    165 recursive_copy_node(node_const_pointer p_ncp)
    166 {
    167   _GLIBCXX_DEBUG_ASSERT(p_ncp != 0);
    168   if (p_ncp->m_type == leaf_node)
    169     {
    170       leaf_const_pointer p_other_lf = static_cast<leaf_const_pointer>(p_ncp);
    171       leaf_pointer p_new_lf = s_leaf_allocator.allocate(1);
    172       cond_dealtor cond(p_new_lf);
    173       new (p_new_lf) leaf(p_other_lf->value());
    174       apply_update(p_new_lf, (node_update*)this);
    175       cond.set_no_action_dtor();
    176       return (p_new_lf);
    177     }
    178 
    179   _GLIBCXX_DEBUG_ASSERT(p_ncp->m_type == i_node);
    180   node_pointer a_p_children[inode::arr_size];
    181   size_type child_i = 0;
    182   inode_const_pointer p_icp = static_cast<inode_const_pointer>(p_ncp);
    183 
    184   typename inode::const_iterator child_it = p_icp->begin();
    185 
    186   inode_pointer p_ret;
    187   __try
    188     {
    189       while (child_it != p_icp->end())
    190 	{
    191 	  a_p_children[child_i] = recursive_copy_node(*(child_it));
    192 	  child_i++;
    193 	  child_it++;
    194 	}
    195       p_ret = s_inode_allocator.allocate(1);
    196     }
    197   __catch(...)
    198     {
    199       while (child_i-- > 0)
    200 	clear_imp(a_p_children[child_i]);
    201       __throw_exception_again;
    202     }
    203 
    204   new (p_ret) inode(p_icp->get_e_ind(), pref_begin(a_p_children[0]));
    205 
    206   --child_i;
    207   _GLIBCXX_DEBUG_ASSERT(child_i >= 1);
    208   do
    209     p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]),
    210 		     pref_end(a_p_children[child_i]), this);
    211   while (child_i-- > 0);
    212   apply_update(p_ret, (node_update*)this);
    213   return p_ret;
    214 }
    215