libstdc++
binary_heap_.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2005, 2006, 2009, 2011 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>
54 #ifdef PB_DS_BINARY_HEAP_TRACE_
55 #include <iostream>
56 #endif
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>
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;
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>
126 
128 
129  typedef binary_heap_const_iterator_<value_type, entry,
130  simple_value, _Alloc>
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 
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