annotate DEPENDENCIES/generic/include/boost/heap/detail/stable_heap.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
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 */