libstdc++
thin_heap_.hpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2009, 2011 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00026 
00027 // Permission to use, copy, modify, sell, and distribute this software
00028 // is hereby granted without fee, provided that the above copyright
00029 // notice appears in all copies, and that both that copyright notice
00030 // and this permission notice appear in supporting documentation. None
00031 // of the above authors, nor IBM Haifa Research Laboratories, make any
00032 // representation about the suitability of this software for any
00033 // purpose. It is provided "as is" without express or implied
00034 // warranty.
00035 
00036 /**
00037  * @file thin_heap_/thin_heap_.hpp
00038  * Contains an implementation class for a thin heap.
00039  */
00040 
00041 #ifndef PB_DS_THIN_HEAP_HPP
00042 #define PB_DS_THIN_HEAP_HPP
00043 
00044 #include <algorithm>
00045 #include <ext/pb_ds/detail/cond_dealtor.hpp>
00046 #include <ext/pb_ds/detail/type_utils.hpp>
00047 #include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp>
00048 #include <debug/debug.h>
00049 
00050 namespace __gnu_pbds
00051 {
00052   namespace detail
00053   {
00054 #define PB_DS_CLASS_T_DEC \
00055     template<typename Value_Type, typename Cmp_Fn, typename _Alloc>
00056 
00057 #define PB_DS_CLASS_C_DEC \
00058     thin_heap<Value_Type, Cmp_Fn, _Alloc>
00059 
00060 #ifdef _GLIBCXX_DEBUG
00061 #define PB_DS_BASE_T_P \
00062     <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc, true>
00063 #else
00064 #define PB_DS_BASE_T_P \
00065     <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc>
00066 #endif
00067 
00068 
00069     /**
00070      *  Thin heap.
00071      *
00072      *  @ingroup heap-detail
00073      *
00074      *  See Tarjan and Kaplan.
00075      */
00076     template<typename Value_Type, typename Cmp_Fn, typename _Alloc>
00077     class thin_heap
00078     : public left_child_next_sibling_heap PB_DS_BASE_T_P
00079     {
00080     private:
00081       typedef typename _Alloc::template rebind<Value_Type>::other __rebind_a;
00082       typedef left_child_next_sibling_heap PB_DS_BASE_T_P base_type;
00083 
00084     protected:
00085       typedef typename base_type::node          node;
00086       typedef typename base_type::node_pointer      node_pointer;
00087       typedef typename base_type::node_const_pointer    node_const_pointer;
00088 
00089     public:
00090       typedef Value_Type                value_type;
00091       typedef Cmp_Fn                    cmp_fn;
00092       typedef _Alloc                    allocator_type;
00093       typedef typename _Alloc::size_type        size_type;
00094       typedef typename _Alloc::difference_type      difference_type;
00095 
00096       typedef typename __rebind_a::pointer      pointer;
00097       typedef typename __rebind_a::const_pointer    const_pointer;
00098       typedef typename __rebind_a::reference        reference;
00099       typedef typename __rebind_a::const_reference      const_reference;
00100 
00101       typedef typename base_type::point_iterator    point_iterator;
00102       typedef typename base_type::point_const_iterator  point_const_iterator;
00103       typedef typename base_type::iterator      iterator;
00104       typedef typename base_type::const_iterator    const_iterator;
00105 
00106 
00107       inline point_iterator
00108       push(const_reference);
00109 
00110       void
00111       modify(point_iterator, const_reference);
00112 
00113       inline const_reference
00114       top() const;
00115 
00116       void
00117       pop();
00118 
00119       void
00120       erase(point_iterator);
00121 
00122       inline void
00123       clear();
00124 
00125       template<typename Pred>
00126       size_type
00127       erase_if(Pred);
00128 
00129       template<typename Pred>
00130       void
00131       split(Pred, PB_DS_CLASS_C_DEC&);
00132 
00133       void
00134       join(PB_DS_CLASS_C_DEC&);
00135 
00136     protected:
00137       thin_heap();
00138 
00139       thin_heap(const Cmp_Fn&);
00140 
00141       thin_heap(const PB_DS_CLASS_C_DEC&);
00142 
00143       void
00144       swap(PB_DS_CLASS_C_DEC&);
00145 
00146       ~thin_heap();
00147 
00148       template<typename It>
00149       void
00150       copy_from_range(It, It);
00151 
00152 #ifdef _GLIBCXX_DEBUG
00153       void
00154       assert_valid(const char*, int) const;
00155 
00156       void
00157       assert_max(const char*, int) const;
00158 #endif
00159 
00160 #ifdef PB_DS_THIN_HEAP_TRACE_
00161       void
00162       trace() const;
00163 #endif
00164 
00165     private:
00166       enum
00167     {
00168       max_rank = (sizeof(size_type) << 4) + 2
00169     };
00170 
00171       void
00172       initialize();
00173 
00174       inline void
00175       update_max(node_pointer);
00176 
00177       inline void
00178       fix(node_pointer);
00179 
00180       inline void
00181       fix_root(node_pointer);
00182 
00183       inline void
00184       fix_sibling_rank_1_unmarked(node_pointer);
00185 
00186       inline void
00187       fix_sibling_rank_1_marked(node_pointer);
00188 
00189       inline void
00190       fix_sibling_general_unmarked(node_pointer);
00191 
00192       inline void
00193       fix_sibling_general_marked(node_pointer);
00194 
00195       inline void
00196       fix_child(node_pointer);
00197 
00198       inline static void
00199       make_root(node_pointer);
00200 
00201       inline void
00202       make_root_and_link(node_pointer);
00203 
00204       inline void
00205       remove_max_node();
00206 
00207       void
00208       to_aux_except_max();
00209 
00210       inline void
00211       add_to_aux(node_pointer);
00212 
00213       inline void
00214       make_from_aux();
00215 
00216       inline size_type
00217       rank_bound();
00218 
00219       inline void
00220       make_child_of(node_pointer, node_pointer);
00221 
00222       inline void
00223       remove_node(node_pointer);
00224 
00225       inline node_pointer
00226       join(node_pointer, node_pointer) const;
00227 
00228 #ifdef _GLIBCXX_DEBUG
00229       void
00230       assert_node_consistent(node_const_pointer, bool, const char*, int) const;
00231 
00232       void
00233       assert_aux_null(const char*, int) const;
00234 #endif
00235 
00236       node_pointer  m_p_max;
00237       node_pointer  m_a_aux[max_rank];
00238     };
00239 
00240     enum
00241       {
00242     num_distinct_rank_bounds = 48
00243       };
00244 
00245     // Taken from the SGI implementation; acknowledged in the docs.
00246     static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] =
00247       {
00248     /* Dealing cards... */
00249     /* 0     */ 0ul,
00250     /* 1     */ 1ul,
00251     /* 2     */ 1ul,
00252     /* 3     */ 2ul,
00253     /* 4     */ 4ul,
00254     /* 5     */ 6ul,
00255     /* 6     */ 11ul,
00256     /* 7     */ 17ul,
00257     /* 8     */ 29ul,
00258     /* 9     */ 46ul,
00259     /* 10    */ 76ul,
00260     /* 11    */ 122ul,
00261     /* 12    */ 199ul,
00262     /* 13    */ 321ul,
00263     /* 14    */ 521ul,
00264     /* 15    */ 842ul,
00265     /* 16    */ 1364ul,
00266     /* 17    */ 2206ul,
00267     /* 18    */ 3571ul,
00268     /* 19    */ 5777ul,
00269     /* 20    */ 9349ul,
00270     /* 21    */ 15126ul,
00271     /* 22    */ 24476ul,
00272     /* 23    */ 39602ul,
00273     /* 24    */ 64079ul,
00274     /* 25    */ 103681ul,
00275     /* 26    */ 167761ul,
00276     /* 27    */ 271442ul,
00277     /* 28    */ 439204ul,
00278     /* 29    */ 710646ul,
00279     /* 30    */ 1149851ul,
00280     /* 31    */ 1860497ul,
00281     /* 32    */ 3010349ul,
00282     /* 33    */ 4870846ul,
00283     /* 34    */ 7881196ul,
00284     /* 35    */ 12752042ul,
00285     /* 36    */ 20633239ul,
00286     /* 37    */ 33385282ul,
00287     /* 38    */ 54018521ul,
00288     /* 39    */ 87403803ul,
00289     /* 40    */ 141422324ul,
00290     /* 41    */ 228826127ul,
00291     /* 42    */ 370248451ul,
00292     /* 43    */ 599074578ul,
00293     /* 44    */ 969323029ul,
00294     /* 45    */ 1568397607ul,
00295     /* 46    */ 2537720636ul,
00296     /* 47    */ 4106118243ul
00297     /* Pot's good, let's play */
00298       };
00299 
00300 #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool)          \
00301   _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool,      \
00302                          __FILE__, __LINE__);)
00303 
00304 #define PB_DS_ASSERT_AUX_NULL(X)                    \
00305   _GLIBCXX_DEBUG_ONLY(X.assert_aux_null(__FILE__, __LINE__);)
00306 
00307 #include <ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp>
00308 #include <ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp>
00309 #include <ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp>
00310 #include <ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp>
00311 #include <ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp>
00312 #include <ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp>
00313 #include <ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp>
00314 
00315 #undef PB_DS_ASSERT_AUX_NULL
00316 #undef PB_DS_ASSERT_NODE_CONSISTENT
00317 #undef PB_DS_CLASS_C_DEC
00318 #undef PB_DS_CLASS_T_DEC
00319 #undef PB_DS_BASE_T_P
00320 
00321   } // namespace detail
00322 } // namespace __gnu_pbds
00323 
00324 #endif