Home | History | Annotate | Download | only in trie_policy
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2005, 2006, 2009 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 trie_policy_base.hpp
     38  * Contains an implementation of trie_policy_base.
     39  */
     40 
     41 #ifndef PB_DS_TRIE_POLICY_BASE_HPP
     42 #define PB_DS_TRIE_POLICY_BASE_HPP
     43 
     44 #include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp>
     45 
     46 namespace __gnu_pbds
     47 {
     48   namespace detail
     49   {
     50 
     51 #define PB_DS_CLASS_T_DEC						\
     52     template<								\
     53 						class Const_Node_Iterator, \
     54 						class Node_Iterator,	\
     55 						class E_Access_Traits,	\
     56 						typename Allocator>
     57 
     58 #define PB_DS_CLASS_C_DEC						\
     59     trie_policy_base<							\
     60 						Const_Node_Iterator,	\
     61 						Node_Iterator,		\
     62 						E_Access_Traits,	\
     63 						Allocator>
     64 
     65 #define PB_DS_BASE_C_DEC						\
     66     basic_tree_policy_base<				\
     67 								Const_Node_Iterator, \
     68 								Node_Iterator, \
     69 								Allocator>
     70 
     71     template<typename Const_Node_Iterator,
     72 	     class Node_Iterator,
     73 	     class E_Access_Traits,
     74 	     class Allocator>
     75     class trie_policy_base : public PB_DS_BASE_C_DEC
     76     {
     77 
     78     public:
     79 
     80       typedef E_Access_Traits e_access_traits;
     81 
     82       typedef Allocator allocator_type;
     83 
     84       typedef typename allocator_type::size_type size_type;
     85 
     86       typedef null_node_metadata metadata_type;
     87 
     88       typedef Const_Node_Iterator const_node_iterator;
     89 
     90       typedef Node_Iterator node_iterator;
     91 
     92       typedef typename const_node_iterator::value_type const_iterator;
     93 
     94       typedef typename node_iterator::value_type iterator;
     95 
     96     public:
     97 
     98       typedef typename PB_DS_BASE_C_DEC::key_type key_type;
     99 
    100       typedef
    101       typename PB_DS_BASE_C_DEC::const_key_reference
    102       const_key_reference;
    103 
    104     protected:
    105 
    106       virtual const_iterator
    107       end() const = 0;
    108 
    109       virtual iterator
    110       end() = 0;
    111 
    112       virtual const_node_iterator
    113       node_begin() const = 0;
    114 
    115       virtual node_iterator
    116       node_begin() = 0;
    117 
    118       virtual const_node_iterator
    119       node_end() const = 0;
    120 
    121       virtual node_iterator
    122       node_end() = 0;
    123 
    124       virtual const e_access_traits&
    125       get_e_access_traits() const = 0;
    126 
    127     private:
    128       typedef
    129       std::pair<
    130       typename e_access_traits::const_iterator,
    131       typename e_access_traits::const_iterator>
    132       prefix_range_t;
    133 
    134       typedef PB_DS_BASE_C_DEC base_type;
    135 
    136     protected:
    137       static size_type
    138       common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits);
    139 
    140       static iterator
    141       leftmost_it(node_iterator nd_it);
    142 
    143       static iterator
    144       rightmost_it(node_iterator nd_it);
    145 
    146       static bool
    147       less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits);
    148     };
    149 
    150     PB_DS_CLASS_T_DEC
    151     typename PB_DS_CLASS_C_DEC::size_type
    152     PB_DS_CLASS_C_DEC::
    153     common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits)
    154     {
    155       prefix_range_t pref_range = nd_it.valid_prefix();
    156 
    157       typename e_access_traits::const_iterator b_l = pref_range.first;
    158       typename e_access_traits::const_iterator e_l = pref_range.second;
    159 
    160       const size_type range_length_l =
    161 	std::distance(b_l, e_l);
    162 
    163       const size_type range_length_r =
    164 	std::distance(b_r, e_r);
    165 
    166       if (range_length_r < range_length_l)
    167 	{
    168 	  std::swap(b_l, b_r);
    169 
    170 	  std::swap(e_l, e_r);
    171 	}
    172 
    173       size_type ret = 0;
    174 
    175       while (b_l != e_l)
    176 	{
    177 	  if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r))
    178 	    return (ret);
    179 
    180 	  ++ret;
    181 
    182 	  ++b_l;
    183 
    184 	  ++b_r;
    185 	}
    186 
    187       return (ret);
    188     }
    189 
    190     PB_DS_CLASS_T_DEC
    191     typename PB_DS_CLASS_C_DEC::iterator
    192     PB_DS_CLASS_C_DEC::
    193     leftmost_it(node_iterator nd_it)
    194     {
    195       if (nd_it.num_children() == 0)
    196 	return (*nd_it);
    197 
    198       return (leftmost_it(nd_it.get_child(0)));
    199     }
    200 
    201     PB_DS_CLASS_T_DEC
    202     typename PB_DS_CLASS_C_DEC::iterator
    203     PB_DS_CLASS_C_DEC::
    204     rightmost_it(node_iterator nd_it)
    205     {
    206       const size_type num_children = nd_it.num_children();
    207 
    208       if (num_children == 0)
    209 	return (*nd_it);
    210 
    211       return (rightmost_it(nd_it.get_child(num_children - 1)));
    212     }
    213 
    214     PB_DS_CLASS_T_DEC
    215     bool
    216     PB_DS_CLASS_C_DEC::
    217     less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits)
    218     {
    219       while (b_l != e_l)
    220 	{
    221 	  if (b_r == e_r)
    222 	    return (false);
    223 
    224 	  size_type l_pos =
    225 	    r_traits.e_pos(*b_l);
    226 	  size_type r_pos =
    227 	    r_traits.e_pos(*b_r);
    228 
    229 	  if (l_pos != r_pos)
    230 	    return (l_pos < r_pos);
    231 
    232 	  ++b_l;
    233 	  ++b_r;
    234 	}
    235 
    236       return (b_r != e_r);
    237     }
    238 
    239 #undef PB_DS_CLASS_T_DEC
    240 
    241 #undef PB_DS_CLASS_C_DEC
    242 
    243 #undef PB_DS_BASE_C_DEC
    244 
    245   } // namespace detail
    246 } // namespace __gnu_pbds
    247 
    248 #endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP
    249 
    250