Home | History | Annotate | Download | only in binary_heap_
      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 binary_heap_/binary_heap_.hpp
     38  * Contains an implementation class for a binary heap.
     39  */
     40 
     41 #ifndef PB_DS_BINARY_HEAP_HPP
     42 #define PB_DS_BINARY_HEAP_HPP
     43 
     44 #include <queue>
     45 #include <algorithm>
     46 #include <ext/pb_ds/detail/cond_dealtor.hpp>
     47 #include <ext/pb_ds/detail/cond_dealtor.hpp>
     48 #include <ext/pb_ds/detail/type_utils.hpp>
     49 #include <ext/pb_ds/detail/binary_heap_/entry_cmp.hpp>
     50 #include <ext/pb_ds/detail/binary_heap_/entry_pred.hpp>
     51 #include <ext/pb_ds/detail/binary_heap_/resize_policy.hpp>
     52 #include <ext/pb_ds/detail/binary_heap_/point_const_iterator.hpp>
     53 #include <ext/pb_ds/detail/binary_heap_/const_iterator.hpp>
     54 #ifdef PB_DS_BINARY_HEAP_TRACE_
     55 #include <iostream>
     56 #endif
     57 #include <ext/pb_ds/detail/type_utils.hpp>
     58 #include <debug/debug.h>
     59 
     60 namespace __gnu_pbds
     61 {
     62   namespace detail
     63   {
     64 #define PB_DS_CLASS_T_DEC \
     65     template<typename Value_Type, typename Cmp_Fn, typename _Alloc>
     66 
     67 #define PB_DS_CLASS_C_DEC \
     68     binary_heap<Value_Type, Cmp_Fn, _Alloc>
     69 
     70 #define PB_DS_ENTRY_CMP_DEC \
     71     entry_cmp<Value_Type, Cmp_Fn, _Alloc, is_simple<Value_Type>::value>::type
     72 
     73 #define PB_DS_RESIZE_POLICY_DEC	\
     74     __gnu_pbds::detail::resize_policy<typename _Alloc::size_type>
     75 
     76     /**
     77      *  Binary heaps composed of resize and compare policies.
     78      *
     79      *  @ingroup heap-detail
     80      *
     81      *  Based on CLRS.
     82      */
     83     template<typename Value_Type, typename Cmp_Fn, typename _Alloc>
     84     class binary_heap
     85     : public PB_DS_ENTRY_CMP_DEC, public PB_DS_RESIZE_POLICY_DEC
     86     {
     87     public:
     88       typedef Value_Type 				value_type;
     89       typedef Cmp_Fn 					cmp_fn;
     90       typedef _Alloc 					allocator_type;
     91       typedef typename _Alloc::size_type 		size_type;
     92       typedef typename _Alloc::difference_type 		difference_type;
     93       typedef typename PB_DS_ENTRY_CMP_DEC 		entry_cmp;
     94       typedef PB_DS_RESIZE_POLICY_DEC 			resize_policy;
     95       typedef cond_dealtor<value_type, _Alloc> 		cond_dealtor_t;
     96 
     97     private:
     98       enum
     99 	{
    100 	  simple_value = is_simple<value_type>::value
    101 	};
    102 
    103       typedef integral_constant<int, simple_value> 	no_throw_copies_t;
    104 
    105       typedef typename _Alloc::template rebind<value_type>	__rebind_v;
    106       typedef typename __rebind_v::other 		value_allocator;
    107 
    108     public:
    109       typedef typename value_allocator::pointer		pointer;
    110       typedef typename value_allocator::const_pointer	const_pointer;
    111       typedef typename value_allocator::reference	reference;
    112       typedef typename value_allocator::const_reference	const_reference;
    113 
    114       typedef typename __conditional_type<simple_value,
    115 					  value_type, pointer>::__type
    116       							entry;
    117 
    118       typedef typename _Alloc::template rebind<entry>::other
    119       							entry_allocator;
    120 
    121       typedef typename entry_allocator::pointer 	entry_pointer;
    122 
    123       typedef binary_heap_point_const_iterator_<value_type, entry,
    124 						simple_value, _Alloc>
    125       							point_const_iterator;
    126 
    127       typedef point_const_iterator 			point_iterator;
    128 
    129       typedef binary_heap_const_iterator_<value_type, entry,
    130 					  simple_value, _Alloc>
    131       							const_iterator;
    132 
    133       typedef const_iterator 				iterator;
    134 
    135 
    136       binary_heap();
    137 
    138       binary_heap(const cmp_fn&);
    139 
    140       binary_heap(const binary_heap&);
    141 
    142       void
    143       swap(binary_heap&);
    144 
    145       ~binary_heap();
    146 
    147       inline bool
    148       empty() const;
    149 
    150       inline size_type
    151       size() const;
    152 
    153       inline size_type
    154       max_size() const;
    155 
    156       Cmp_Fn&
    157       get_cmp_fn();
    158 
    159       const Cmp_Fn&
    160       get_cmp_fn() const;
    161 
    162       inline point_iterator
    163       push(const_reference);
    164 
    165       void
    166       modify(point_iterator, const_reference);
    167 
    168       inline const_reference
    169       top() const;
    170 
    171       inline void
    172       pop();
    173 
    174       inline void
    175       erase(point_iterator);
    176 
    177       template<typename Pred>
    178 	size_type
    179 	erase_if(Pred);
    180 
    181       inline void
    182       erase_at(entry_pointer, size_type, false_type);
    183 
    184       inline void
    185       erase_at(entry_pointer, size_type, true_type);
    186 
    187       inline iterator
    188       begin();
    189 
    190       inline const_iterator
    191       begin() const;
    192 
    193       inline iterator
    194       end();
    195 
    196       inline const_iterator
    197       end() const;
    198 
    199       void
    200       clear();
    201 
    202       template<typename Pred>
    203 	void
    204 	split(Pred, binary_heap&);
    205 
    206       void
    207       join(binary_heap&);
    208 
    209 #ifdef PB_DS_BINARY_HEAP_TRACE_
    210       void
    211       trace() const;
    212 #endif
    213 
    214     protected:
    215       template<typename It>
    216 	void
    217 	copy_from_range(It, It);
    218 
    219     private:
    220       void
    221       value_swap(binary_heap&);
    222 
    223       inline void
    224       insert_value(const_reference, false_type);
    225 
    226       inline void
    227       insert_value(value_type, true_type);
    228 
    229       inline void
    230       resize_for_insert_if_needed();
    231 
    232       inline void
    233       swap_value_imp(entry_pointer, value_type, true_type);
    234 
    235       inline void
    236       swap_value_imp(entry_pointer, const_reference, false_type);
    237 
    238       void
    239       fix(entry_pointer);
    240 
    241       inline const_reference
    242       top_imp(true_type) const;
    243 
    244       inline const_reference
    245       top_imp(false_type) const;
    246 
    247       inline static size_type
    248       left_child(size_type);
    249 
    250       inline static size_type
    251       right_child(size_type);
    252 
    253       inline static size_type
    254       parent(size_type);
    255 
    256       inline void
    257       resize_for_erase_if_needed();
    258 
    259       template<typename Pred>
    260       size_type
    261       partition(Pred);
    262 
    263       void
    264       make_heap()
    265       {
    266 	const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
    267 	entry_pointer end = m_a_entries + m_size;
    268 	std::make_heap(m_a_entries, end, m_cmp);
    269 	_GLIBCXX_DEBUG_ASSERT(is_heap());
    270       }
    271 
    272       void
    273       push_heap()
    274       {
    275 	if (!is_heap())
    276 	  make_heap();
    277 	else
    278 	  {
    279 	    const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
    280 	    entry_pointer end = m_a_entries + m_size;
    281 	    std::push_heap(m_a_entries, end, m_cmp);
    282 	  }
    283       }
    284 
    285       void
    286       pop_heap()
    287       {
    288 	const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
    289 	entry_pointer end = m_a_entries + m_size;
    290 	std::pop_heap(m_a_entries, end, m_cmp);
    291       }
    292 
    293       bool
    294       is_heap()
    295       {
    296 	const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
    297 	entry_pointer end = m_a_entries + m_size;
    298 	bool p = std::__is_heap(m_a_entries, end, m_cmp);
    299 	return p;
    300       }
    301 
    302 #ifdef _GLIBCXX_DEBUG
    303       void
    304       assert_valid(const char*, int) const;
    305 #endif
    306 
    307 #ifdef PB_DS_BINARY_HEAP_TRACE_
    308       void
    309       trace_entry(const entry&, false_type) const;
    310 
    311       void
    312       trace_entry(const entry&, true_type) const;
    313 #endif
    314 
    315       static entry_allocator 	s_entry_allocator;
    316       static value_allocator 	s_value_allocator;
    317       static no_throw_copies_t 	s_no_throw_copies_ind;
    318 
    319       size_type 		m_size;
    320       size_type 		m_actual_size;
    321       entry_pointer 		m_a_entries;
    322     };
    323 
    324 #define PB_DS_ASSERT_VALID(X) \
    325   _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);)
    326 
    327 #define PB_DS_DEBUG_VERIFY(_Cond)					\
    328   _GLIBCXX_DEBUG_VERIFY_AT(_Cond,					\
    329 			   _M_message(#_Cond" assertion from %1;:%2;")	\
    330 			   ._M_string(__FILE__)._M_integer(__LINE__)	\
    331 			   ,__file,__line)
    332 
    333 #include <ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp>
    334 #include <ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp>
    335 #include <ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp>
    336 #include <ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp>
    337 #include <ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp>
    338 #include <ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp>
    339 #include <ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp>
    340 #include <ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp>
    341 #include <ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp>
    342 #include <ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp>
    343 
    344 #undef PB_DS_CLASS_C_DEC
    345 #undef PB_DS_CLASS_T_DEC
    346 #undef PB_DS_ENTRY_CMP_DEC
    347 #undef PB_DS_RESIZE_POLICY_DEC
    348 
    349   } // namespace detail
    350 } // namespace __gnu_pbds
    351 
    352 #endif
    353