Chris@16
|
1 // boost heap: helper classes for stable priority queues
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright (C) 2010 Tim Blechmann
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_HEAP_DETAIL_STABLE_HEAP_HPP
|
Chris@16
|
10 #define BOOST_HEAP_DETAIL_STABLE_HEAP_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #include <limits>
|
Chris@16
|
13 #include <stdexcept>
|
Chris@16
|
14 #include <utility>
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/cstdint.hpp>
|
Chris@16
|
17 #include <boost/throw_exception.hpp>
|
Chris@16
|
18 #include <boost/iterator/iterator_adaptor.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/heap/policies.hpp>
|
Chris@16
|
21 #include <boost/heap/heap_merge.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost {
|
Chris@16
|
24 namespace heap {
|
Chris@16
|
25 namespace detail {
|
Chris@16
|
26
|
Chris@16
|
27 template<bool ConstantSize, class SizeType>
|
Chris@16
|
28 struct size_holder
|
Chris@16
|
29 {
|
Chris@16
|
30 static const bool constant_time_size = ConstantSize;
|
Chris@16
|
31 typedef SizeType size_type;
|
Chris@16
|
32
|
Chris@16
|
33 size_holder(void):
|
Chris@16
|
34 size_(0)
|
Chris@16
|
35 {}
|
Chris@16
|
36
|
Chris@16
|
37 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
38 size_holder(size_holder && rhs):
|
Chris@16
|
39 size_(rhs.size_)
|
Chris@16
|
40 {
|
Chris@16
|
41 rhs.size_ = 0;
|
Chris@16
|
42 }
|
Chris@16
|
43
|
Chris@16
|
44 size_holder(size_holder const & rhs):
|
Chris@16
|
45 size_(rhs.size_)
|
Chris@16
|
46 {}
|
Chris@16
|
47
|
Chris@16
|
48 size_holder & operator=(size_holder && rhs)
|
Chris@16
|
49 {
|
Chris@16
|
50 size_ = rhs.size_;
|
Chris@16
|
51 rhs.size_ = 0;
|
Chris@16
|
52 return *this;
|
Chris@16
|
53 }
|
Chris@16
|
54
|
Chris@16
|
55 size_holder & operator=(size_holder const & rhs)
|
Chris@16
|
56 {
|
Chris@16
|
57 size_ = rhs.size_;
|
Chris@16
|
58 return *this;
|
Chris@16
|
59 }
|
Chris@16
|
60 #endif
|
Chris@16
|
61
|
Chris@16
|
62 SizeType get_size() const
|
Chris@16
|
63 { return size_; }
|
Chris@16
|
64
|
Chris@16
|
65 void set_size(SizeType size)
|
Chris@16
|
66 { size_ = size; }
|
Chris@16
|
67
|
Chris@16
|
68 void decrement()
|
Chris@16
|
69 { --size_; }
|
Chris@16
|
70
|
Chris@16
|
71 void increment()
|
Chris@16
|
72 { ++size_; }
|
Chris@16
|
73
|
Chris@16
|
74 void add(SizeType value)
|
Chris@16
|
75 { size_ += value; }
|
Chris@16
|
76
|
Chris@16
|
77 void sub(SizeType value)
|
Chris@16
|
78 { size_ -= value; }
|
Chris@16
|
79
|
Chris@16
|
80 void swap(size_holder & rhs)
|
Chris@16
|
81 { std::swap(size_, rhs.size_); }
|
Chris@16
|
82
|
Chris@16
|
83 SizeType size_;
|
Chris@16
|
84 };
|
Chris@16
|
85
|
Chris@16
|
86 template<class SizeType>
|
Chris@16
|
87 struct size_holder<false, SizeType>
|
Chris@16
|
88 {
|
Chris@16
|
89 static const bool constant_time_size = false;
|
Chris@16
|
90 typedef SizeType size_type;
|
Chris@16
|
91
|
Chris@16
|
92 size_holder(void)
|
Chris@16
|
93 {}
|
Chris@16
|
94
|
Chris@16
|
95 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
96 size_holder(size_holder && rhs)
|
Chris@16
|
97 {}
|
Chris@16
|
98
|
Chris@16
|
99 size_holder(size_holder const & rhs)
|
Chris@16
|
100 {}
|
Chris@16
|
101
|
Chris@16
|
102 size_holder & operator=(size_holder && rhs)
|
Chris@16
|
103 {
|
Chris@16
|
104 return *this;
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 size_holder & operator=(size_holder const & rhs)
|
Chris@16
|
108 {
|
Chris@16
|
109 return *this;
|
Chris@16
|
110 }
|
Chris@16
|
111 #endif
|
Chris@16
|
112
|
Chris@16
|
113 size_type get_size() const
|
Chris@16
|
114 { return 0; }
|
Chris@16
|
115
|
Chris@16
|
116 void set_size(size_type)
|
Chris@16
|
117 {}
|
Chris@16
|
118
|
Chris@16
|
119 void decrement()
|
Chris@16
|
120 {}
|
Chris@16
|
121
|
Chris@16
|
122 void increment()
|
Chris@16
|
123 {}
|
Chris@16
|
124
|
Chris@16
|
125 void add(SizeType value)
|
Chris@16
|
126 {}
|
Chris@16
|
127
|
Chris@16
|
128 void sub(SizeType value)
|
Chris@16
|
129 {}
|
Chris@16
|
130
|
Chris@16
|
131 void swap(size_holder & rhs)
|
Chris@16
|
132 {}
|
Chris@16
|
133 };
|
Chris@16
|
134
|
Chris@16
|
135 // note: MSVC does not implement lookup correctly, we therefore have to place the Cmp object as member inside the
|
Chris@16
|
136 // struct. of course, this prevents EBO and significantly reduces the readability of this code
|
Chris@16
|
137 template <typename T,
|
Chris@16
|
138 typename Cmp,
|
Chris@16
|
139 bool constant_time_size,
|
Chris@16
|
140 typename StabilityCounterType = boost::uintmax_t,
|
Chris@16
|
141 bool stable = false
|
Chris@16
|
142 >
|
Chris@16
|
143 struct heap_base:
|
Chris@16
|
144 #ifndef BOOST_MSVC
|
Chris@16
|
145 Cmp,
|
Chris@16
|
146 #endif
|
Chris@16
|
147 size_holder<constant_time_size, size_t>
|
Chris@16
|
148 {
|
Chris@16
|
149 typedef StabilityCounterType stability_counter_type;
|
Chris@16
|
150 typedef T value_type;
|
Chris@16
|
151 typedef T internal_type;
|
Chris@16
|
152 typedef size_holder<constant_time_size, size_t> size_holder_type;
|
Chris@16
|
153 typedef Cmp value_compare;
|
Chris@16
|
154 typedef Cmp internal_compare;
|
Chris@16
|
155 static const bool is_stable = stable;
|
Chris@16
|
156
|
Chris@16
|
157 #ifdef BOOST_MSVC
|
Chris@16
|
158 Cmp cmp_;
|
Chris@16
|
159 #endif
|
Chris@16
|
160
|
Chris@16
|
161 heap_base (Cmp const & cmp = Cmp()):
|
Chris@16
|
162 #ifndef BOOST_MSVC
|
Chris@16
|
163 Cmp(cmp)
|
Chris@16
|
164 #else
|
Chris@16
|
165 cmp_(cmp)
|
Chris@16
|
166 #endif
|
Chris@16
|
167 {}
|
Chris@16
|
168
|
Chris@16
|
169 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
170 heap_base(heap_base && rhs):
|
Chris@16
|
171 #ifndef BOOST_MSVC
|
Chris@16
|
172 Cmp(std::move(static_cast<Cmp&>(rhs))),
|
Chris@16
|
173 #else
|
Chris@16
|
174 cmp_(std::move(rhs.cmp_)),
|
Chris@16
|
175 #endif
|
Chris@16
|
176 size_holder_type(std::move(static_cast<size_holder_type&>(rhs)))
|
Chris@16
|
177 {}
|
Chris@16
|
178
|
Chris@16
|
179 heap_base(heap_base const & rhs):
|
Chris@16
|
180 #ifndef BOOST_MSVC
|
Chris@16
|
181 Cmp(static_cast<Cmp const &>(rhs)),
|
Chris@16
|
182 #else
|
Chris@16
|
183 cmp_(rhs.value_comp()),
|
Chris@16
|
184 #endif
|
Chris@16
|
185 size_holder_type(static_cast<size_holder_type const &>(rhs))
|
Chris@16
|
186 {}
|
Chris@16
|
187
|
Chris@16
|
188 heap_base & operator=(heap_base && rhs)
|
Chris@16
|
189 {
|
Chris@16
|
190 value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
|
Chris@16
|
191 size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
|
Chris@16
|
192 return *this;
|
Chris@16
|
193 }
|
Chris@16
|
194
|
Chris@16
|
195 heap_base & operator=(heap_base const & rhs)
|
Chris@16
|
196 {
|
Chris@16
|
197 value_comp_ref().operator=(rhs.value_comp());
|
Chris@16
|
198 size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
|
Chris@16
|
199 return *this;
|
Chris@16
|
200 }
|
Chris@16
|
201 #endif
|
Chris@16
|
202
|
Chris@16
|
203 bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
Chris@16
|
204 {
|
Chris@16
|
205 return value_comp().operator()(lhs, rhs);
|
Chris@16
|
206 }
|
Chris@16
|
207
|
Chris@16
|
208 internal_type make_node(T const & val)
|
Chris@16
|
209 {
|
Chris@16
|
210 return val;
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
214 T && make_node(T && val)
|
Chris@16
|
215 {
|
Chris@16
|
216 return std::forward<T>(val);
|
Chris@16
|
217 }
|
Chris@16
|
218 #endif
|
Chris@16
|
219
|
Chris@16
|
220 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
221 template <class... Args>
|
Chris@16
|
222 internal_type make_node(Args && ... val)
|
Chris@16
|
223 {
|
Chris@16
|
224 return internal_type(std::forward<Args>(val)...);
|
Chris@16
|
225 }
|
Chris@16
|
226 #endif
|
Chris@16
|
227
|
Chris@16
|
228 static T & get_value(internal_type & val)
|
Chris@16
|
229 {
|
Chris@16
|
230 return val;
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 static T const & get_value(internal_type const & val)
|
Chris@16
|
234 {
|
Chris@16
|
235 return val;
|
Chris@16
|
236 }
|
Chris@16
|
237
|
Chris@16
|
238 Cmp const & value_comp(void) const
|
Chris@16
|
239 {
|
Chris@16
|
240 #ifndef BOOST_MSVC
|
Chris@16
|
241 return *this;
|
Chris@16
|
242 #else
|
Chris@16
|
243 return cmp_;
|
Chris@16
|
244 #endif
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 Cmp const & get_internal_cmp(void) const
|
Chris@16
|
248 {
|
Chris@16
|
249 return value_comp();
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 void swap(heap_base & rhs)
|
Chris@16
|
253 {
|
Chris@16
|
254 std::swap(value_comp_ref(), rhs.value_comp_ref());
|
Chris@16
|
255 size_holder<constant_time_size, size_t>::swap(rhs);
|
Chris@16
|
256 }
|
Chris@16
|
257
|
Chris@16
|
258 stability_counter_type get_stability_count(void) const
|
Chris@16
|
259 {
|
Chris@16
|
260 return 0;
|
Chris@16
|
261 }
|
Chris@16
|
262
|
Chris@16
|
263 void set_stability_count(stability_counter_type)
|
Chris@16
|
264 {}
|
Chris@16
|
265
|
Chris@16
|
266 template <typename Heap1, typename Heap2>
|
Chris@16
|
267 friend struct heap_merge_emulate;
|
Chris@16
|
268
|
Chris@16
|
269 private:
|
Chris@16
|
270 Cmp & value_comp_ref(void)
|
Chris@16
|
271 {
|
Chris@16
|
272 #ifndef BOOST_MSVC
|
Chris@16
|
273 return *this;
|
Chris@16
|
274 #else
|
Chris@16
|
275 return cmp_;
|
Chris@16
|
276 #endif
|
Chris@16
|
277 }
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280
|
Chris@16
|
281 template <typename T,
|
Chris@16
|
282 typename Cmp,
|
Chris@16
|
283 bool constant_time_size,
|
Chris@16
|
284 typename StabilityCounterType
|
Chris@16
|
285 >
|
Chris@16
|
286 struct heap_base<T, Cmp, constant_time_size, StabilityCounterType, true>:
|
Chris@16
|
287 #ifndef BOOST_MSVC
|
Chris@16
|
288 Cmp,
|
Chris@16
|
289 #endif
|
Chris@16
|
290 size_holder<constant_time_size, size_t>
|
Chris@16
|
291 {
|
Chris@16
|
292 typedef StabilityCounterType stability_counter_type;
|
Chris@16
|
293 typedef T value_type;
|
Chris@16
|
294
|
Chris@16
|
295 struct internal_type
|
Chris@16
|
296 {
|
Chris@16
|
297 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
298 template <class ...Args>
|
Chris@16
|
299 internal_type(stability_counter_type cnt, Args && ... args):
|
Chris@16
|
300 first(std::forward<Args>(args)...), second(cnt)
|
Chris@16
|
301 {}
|
Chris@16
|
302 #endif
|
Chris@16
|
303
|
Chris@16
|
304 internal_type(stability_counter_type const & cnt, T const & value):
|
Chris@16
|
305 first(value), second(cnt)
|
Chris@16
|
306 {}
|
Chris@16
|
307
|
Chris@16
|
308 T first;
|
Chris@16
|
309 stability_counter_type second;
|
Chris@16
|
310 };
|
Chris@16
|
311
|
Chris@16
|
312 typedef size_holder<constant_time_size, size_t> size_holder_type;
|
Chris@16
|
313 typedef Cmp value_compare;
|
Chris@16
|
314
|
Chris@16
|
315 #ifdef BOOST_MSVC
|
Chris@16
|
316 Cmp cmp_;
|
Chris@16
|
317 #endif
|
Chris@16
|
318
|
Chris@16
|
319 heap_base (Cmp const & cmp = Cmp()):
|
Chris@16
|
320 #ifndef BOOST_MSVC
|
Chris@16
|
321 Cmp(cmp),
|
Chris@16
|
322 #else
|
Chris@16
|
323 cmp_(cmp),
|
Chris@16
|
324 #endif
|
Chris@16
|
325 counter_(0)
|
Chris@16
|
326 {}
|
Chris@16
|
327
|
Chris@16
|
328 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
329 heap_base(heap_base && rhs):
|
Chris@16
|
330 #ifndef BOOST_MSVC
|
Chris@16
|
331 Cmp(std::move(static_cast<Cmp&>(rhs))),
|
Chris@16
|
332 #else
|
Chris@16
|
333 cmp_(std::move(rhs.cmp_)),
|
Chris@16
|
334 #endif
|
Chris@16
|
335 size_holder_type(std::move(static_cast<size_holder_type&>(rhs))), counter_(rhs.counter_)
|
Chris@16
|
336 {
|
Chris@16
|
337 rhs.counter_ = 0;
|
Chris@16
|
338 }
|
Chris@16
|
339
|
Chris@16
|
340 heap_base(heap_base const & rhs):
|
Chris@16
|
341 #ifndef BOOST_MSVC
|
Chris@16
|
342 Cmp(static_cast<Cmp const&>(rhs)),
|
Chris@16
|
343 #else
|
Chris@16
|
344 cmp_(rhs.value_comp()),
|
Chris@16
|
345 #endif
|
Chris@16
|
346 size_holder_type(static_cast<size_holder_type const &>(rhs)), counter_(rhs.counter_)
|
Chris@16
|
347 {}
|
Chris@16
|
348
|
Chris@16
|
349 heap_base & operator=(heap_base && rhs)
|
Chris@16
|
350 {
|
Chris@16
|
351 value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
|
Chris@16
|
352 size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
|
Chris@16
|
353
|
Chris@16
|
354 counter_ = rhs.counter_;
|
Chris@16
|
355 rhs.counter_ = 0;
|
Chris@16
|
356 return *this;
|
Chris@16
|
357 }
|
Chris@16
|
358
|
Chris@16
|
359 heap_base & operator=(heap_base const & rhs)
|
Chris@16
|
360 {
|
Chris@16
|
361 value_comp_ref().operator=(rhs.value_comp());
|
Chris@16
|
362 size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
|
Chris@16
|
363
|
Chris@16
|
364 counter_ = rhs.counter_;
|
Chris@16
|
365 return *this;
|
Chris@16
|
366 }
|
Chris@16
|
367 #endif
|
Chris@16
|
368
|
Chris@16
|
369 bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
Chris@16
|
370 {
|
Chris@16
|
371 return get_internal_cmp()(lhs, rhs);
|
Chris@16
|
372 }
|
Chris@16
|
373
|
Chris@16
|
374 bool operator()(T const & lhs, T const & rhs) const
|
Chris@16
|
375 {
|
Chris@16
|
376 return value_comp()(lhs, rhs);
|
Chris@16
|
377 }
|
Chris@16
|
378
|
Chris@16
|
379 internal_type make_node(T const & val)
|
Chris@16
|
380 {
|
Chris@16
|
381 stability_counter_type count = ++counter_;
|
Chris@16
|
382 if (counter_ == (std::numeric_limits<stability_counter_type>::max)())
|
Chris@16
|
383 BOOST_THROW_EXCEPTION(std::runtime_error("boost::heap counter overflow"));
|
Chris@16
|
384 return internal_type(count, val);
|
Chris@16
|
385 }
|
Chris@16
|
386
|
Chris@16
|
387 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
388 template <class... Args>
|
Chris@16
|
389 internal_type make_node(Args&&... args)
|
Chris@16
|
390 {
|
Chris@16
|
391 stability_counter_type count = ++counter_;
|
Chris@16
|
392 if (counter_ == (std::numeric_limits<stability_counter_type>::max)())
|
Chris@16
|
393 BOOST_THROW_EXCEPTION(std::runtime_error("boost::heap counter overflow"));
|
Chris@16
|
394 return internal_type (count, std::forward<Args>(args)...);
|
Chris@16
|
395 }
|
Chris@16
|
396 #endif
|
Chris@16
|
397
|
Chris@16
|
398 static T & get_value(internal_type & val)
|
Chris@16
|
399 {
|
Chris@16
|
400 return val.first;
|
Chris@16
|
401 }
|
Chris@16
|
402
|
Chris@16
|
403 static T const & get_value(internal_type const & val)
|
Chris@16
|
404 {
|
Chris@16
|
405 return val.first;
|
Chris@16
|
406 }
|
Chris@16
|
407
|
Chris@16
|
408 Cmp const & value_comp(void) const
|
Chris@16
|
409 {
|
Chris@16
|
410 #ifndef BOOST_MSVC
|
Chris@16
|
411 return *this;
|
Chris@16
|
412 #else
|
Chris@16
|
413 return cmp_;
|
Chris@16
|
414 #endif
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 struct internal_compare:
|
Chris@16
|
418 Cmp
|
Chris@16
|
419 {
|
Chris@16
|
420 internal_compare(Cmp const & cmp = Cmp()):
|
Chris@16
|
421 Cmp(cmp)
|
Chris@16
|
422 {}
|
Chris@16
|
423
|
Chris@16
|
424 bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
Chris@16
|
425 {
|
Chris@16
|
426 if (Cmp::operator()(lhs.first, rhs.first))
|
Chris@16
|
427 return true;
|
Chris@16
|
428
|
Chris@16
|
429 if (Cmp::operator()(rhs.first, lhs.first))
|
Chris@16
|
430 return false;
|
Chris@16
|
431
|
Chris@16
|
432 return lhs.second > rhs.second;
|
Chris@16
|
433 }
|
Chris@16
|
434 };
|
Chris@16
|
435
|
Chris@16
|
436 internal_compare get_internal_cmp(void) const
|
Chris@16
|
437 {
|
Chris@16
|
438 return internal_compare(value_comp());
|
Chris@16
|
439 }
|
Chris@16
|
440
|
Chris@16
|
441 void swap(heap_base & rhs)
|
Chris@16
|
442 {
|
Chris@16
|
443 #ifndef BOOST_MSVC
|
Chris@16
|
444 std::swap(static_cast<Cmp&>(*this), static_cast<Cmp&>(rhs));
|
Chris@16
|
445 #else
|
Chris@16
|
446 std::swap(cmp_, rhs.cmp_);
|
Chris@16
|
447 #endif
|
Chris@16
|
448 std::swap(counter_, rhs.counter_);
|
Chris@16
|
449 size_holder<constant_time_size, size_t>::swap(rhs);
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 stability_counter_type get_stability_count(void) const
|
Chris@16
|
453 {
|
Chris@16
|
454 return counter_;
|
Chris@16
|
455 }
|
Chris@16
|
456
|
Chris@16
|
457 void set_stability_count(stability_counter_type new_count)
|
Chris@16
|
458 {
|
Chris@16
|
459 counter_ = new_count;
|
Chris@16
|
460 }
|
Chris@16
|
461
|
Chris@16
|
462 template <typename Heap1, typename Heap2>
|
Chris@16
|
463 friend struct heap_merge_emulate;
|
Chris@16
|
464
|
Chris@16
|
465 private:
|
Chris@16
|
466 Cmp & value_comp_ref(void)
|
Chris@16
|
467 {
|
Chris@16
|
468 #ifndef BOOST_MSVC
|
Chris@16
|
469 return *this;
|
Chris@16
|
470 #else
|
Chris@16
|
471 return cmp_;
|
Chris@16
|
472 #endif
|
Chris@16
|
473 }
|
Chris@16
|
474
|
Chris@16
|
475 stability_counter_type counter_;
|
Chris@16
|
476 };
|
Chris@16
|
477
|
Chris@16
|
478 template <typename node_pointer,
|
Chris@16
|
479 typename extractor,
|
Chris@16
|
480 typename reference
|
Chris@16
|
481 >
|
Chris@16
|
482 struct node_handle
|
Chris@16
|
483 {
|
Chris@16
|
484 explicit node_handle(node_pointer n = 0):
|
Chris@16
|
485 node_(n)
|
Chris@16
|
486 {}
|
Chris@16
|
487
|
Chris@16
|
488 reference operator*() const
|
Chris@16
|
489 {
|
Chris@16
|
490 return extractor::get_value(node_->value);
|
Chris@16
|
491 }
|
Chris@16
|
492
|
Chris@16
|
493 bool operator==(node_handle const & rhs) const
|
Chris@16
|
494 {
|
Chris@16
|
495 return node_ == rhs.node_;
|
Chris@16
|
496 }
|
Chris@16
|
497
|
Chris@16
|
498 bool operator!=(node_handle const & rhs) const
|
Chris@16
|
499 {
|
Chris@16
|
500 return node_ != rhs.node_;
|
Chris@16
|
501 }
|
Chris@16
|
502
|
Chris@16
|
503 node_pointer node_;
|
Chris@16
|
504 };
|
Chris@16
|
505
|
Chris@16
|
506 template <typename value_type,
|
Chris@16
|
507 typename internal_type,
|
Chris@16
|
508 typename extractor
|
Chris@16
|
509 >
|
Chris@16
|
510 struct value_extractor
|
Chris@16
|
511 {
|
Chris@16
|
512 value_type const & operator()(internal_type const & data) const
|
Chris@16
|
513 {
|
Chris@16
|
514 return extractor::get_value(data);
|
Chris@16
|
515 }
|
Chris@16
|
516 };
|
Chris@16
|
517
|
Chris@16
|
518 template <typename T,
|
Chris@16
|
519 typename ContainerIterator,
|
Chris@16
|
520 typename Extractor>
|
Chris@16
|
521 class stable_heap_iterator:
|
Chris@16
|
522 public boost::iterator_adaptor<stable_heap_iterator<T, ContainerIterator, Extractor>,
|
Chris@16
|
523 ContainerIterator,
|
Chris@16
|
524 T const,
|
Chris@16
|
525 boost::random_access_traversal_tag>
|
Chris@16
|
526 {
|
Chris@16
|
527 typedef boost::iterator_adaptor<stable_heap_iterator,
|
Chris@16
|
528 ContainerIterator,
|
Chris@16
|
529 T const,
|
Chris@16
|
530 boost::random_access_traversal_tag> super_t;
|
Chris@16
|
531
|
Chris@16
|
532 public:
|
Chris@16
|
533 stable_heap_iterator(void):
|
Chris@16
|
534 super_t(0)
|
Chris@16
|
535 {}
|
Chris@16
|
536
|
Chris@16
|
537 explicit stable_heap_iterator(ContainerIterator const & it):
|
Chris@16
|
538 super_t(it)
|
Chris@16
|
539 {}
|
Chris@16
|
540
|
Chris@16
|
541 private:
|
Chris@16
|
542 friend class boost::iterator_core_access;
|
Chris@16
|
543
|
Chris@16
|
544 T const & dereference() const
|
Chris@16
|
545 {
|
Chris@16
|
546 return Extractor::get_value(*super_t::base());
|
Chris@16
|
547 }
|
Chris@16
|
548 };
|
Chris@16
|
549
|
Chris@16
|
550 template <typename T, typename Parspec, bool constant_time_size>
|
Chris@16
|
551 struct make_heap_base
|
Chris@16
|
552 {
|
Chris@16
|
553 typedef typename parameter::binding<Parspec, tag::compare, std::less<T> >::type compare_argument;
|
Chris@16
|
554 typedef typename parameter::binding<Parspec, tag::allocator, std::allocator<T> >::type allocator_argument;
|
Chris@16
|
555 typedef typename parameter::binding<Parspec, tag::stability_counter_type, boost::uintmax_t >::type stability_counter_type;
|
Chris@16
|
556
|
Chris@16
|
557 static const bool is_stable = extract_stable<Parspec>::value;
|
Chris@16
|
558
|
Chris@16
|
559 typedef heap_base<T, compare_argument, constant_time_size, stability_counter_type, is_stable> type;
|
Chris@16
|
560 };
|
Chris@16
|
561
|
Chris@16
|
562
|
Chris@16
|
563 template <typename Alloc>
|
Chris@16
|
564 struct extract_allocator_types
|
Chris@16
|
565 {
|
Chris@16
|
566 typedef typename Alloc::size_type size_type;
|
Chris@16
|
567 typedef typename Alloc::difference_type difference_type;
|
Chris@16
|
568 typedef typename Alloc::reference reference;
|
Chris@16
|
569 typedef typename Alloc::const_reference const_reference;
|
Chris@16
|
570 typedef typename Alloc::pointer pointer;
|
Chris@16
|
571 typedef typename Alloc::const_pointer const_pointer;
|
Chris@16
|
572 };
|
Chris@16
|
573
|
Chris@16
|
574
|
Chris@16
|
575 } /* namespace detail */
|
Chris@16
|
576 } /* namespace heap */
|
Chris@16
|
577 } /* namespace boost */
|
Chris@16
|
578
|
Chris@16
|
579 #endif /* BOOST_HEAP_DETAIL_STABLE_HEAP_HPP */
|