queue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #ifndef __GBLIBCPP_QUEUE__
  2. #define __GBLIBCPP_QUEUE__
  3. #include <vector>
  4. #include <functional>
  5. #include <memory>
  6. #include <algorithm>
  7. #include <initializer_list>
  8. #include <cstddef>
  9. namespace std {
  10. template <typename T,
  11. typename Container = std::vector<T>,
  12. typename Compare = std::less<typename Container::value_type>>
  13. class priority_queue {
  14. public:
  15. using container_type = Container;
  16. using value_compare = Compare;
  17. using value_type = typename Container::value_type;
  18. using size_type = typename Container::size_type;
  19. using reference = typename Container::reference;
  20. using const_reference = typename Container::const_reference;
  21. using allocator_type = typename Container::allocator_type;
  22. protected:
  23. container_type c;
  24. value_compare comp;
  25. public:
  26. __GBLIBCPP_CONSTEXPR
  27. priority_queue(const Compare& comp, const Container& c)
  28. : c(c), comp(comp)
  29. {
  30. std::make_heap(c.begin(), c.end(), comp);
  31. }
  32. __GBLIBCPP_CONSTEXPR
  33. explicit priority_queue(const Compare& comp, Container&& c)
  34. : c(std::move(c)), comp(comp)
  35. {
  36. std::make_heap(c.begin(), c.end(), comp);
  37. }
  38. __GBLIBCPP_CONSTEXPR
  39. priority_queue() : priority_queue(Compare(), Container()) {}
  40. __GBLIBCPP_CONSTEXPR
  41. explicit priority_queue(const Compare& comp)
  42. : priority_queue(comp, Container()) {}
  43. template <typename InputIter>
  44. __GBLIBCPP_CONSTEXPR
  45. priority_queue(InputIter first, InputIter last,
  46. const Compare& comp = Compare())
  47. : c(first, last), comp(comp)
  48. {
  49. std::make_heap(c.begin(), c.end(), comp);
  50. }
  51. template <typename InputIter>
  52. __GBLIBCPP_CONSTEXPR
  53. priority_queue(InputIter first, InputIter last,
  54. const Compare& comp, const Container& c)
  55. : c(c), comp(comp)
  56. {
  57. c.insert(c.end(), first, last);
  58. std::make_heap(c.begin(), c.end(), comp);
  59. }
  60. template <typename InputIter>
  61. __GBLIBCPP_CONSTEXPR
  62. priority_queue(InputIter first, InputIter last,
  63. const Compare& comp, Container&& c)
  64. : c(std::move(c)), comp(comp)
  65. {
  66. c.insert(c.end(), first, last);
  67. std::make_heap(c.begin(), c.end(), comp);
  68. }
  69. __GBLIBCPP_CONSTEXPR
  70. priority_queue(const priority_queue&) = default;
  71. __GBLIBCPP_CONSTEXPR
  72. priority_queue(priority_queue&&) = default;
  73. __GBLIBCPP_CONSTEXPR
  74. priority_queue& operator=(const priority_queue&) = default;
  75. __GBLIBCPP_CONSTEXPR
  76. priority_queue& operator=(priority_queue&&) = default;
  77. [[nodiscard]]
  78. __GBLIBCPP_CONSTEXPR
  79. bool empty(void) const noexcept { return c.empty(); }
  80. __GBLIBCPP_CONSTEXPR
  81. size_type size(void) const noexcept { return c.size(); }
  82. __GBLIBCPP_CONSTEXPR
  83. const_reference top(void) const { return c.front(); }
  84. __GBLIBCPP_CONSTEXPR
  85. void push(const value_type& val)
  86. {
  87. c.push_back(val);
  88. std::push_heap(c.begin(), c.end(), comp);
  89. }
  90. __GBLIBCPP_CONSTEXPR
  91. void push(value_type&& val)
  92. {
  93. c.push_back(std::move(val));
  94. std::push_heap(c.begin(), c.end(), comp);
  95. }
  96. template <typename... Args>
  97. __GBLIBCPP_CONSTEXPR
  98. void emplace(Args&&... args)
  99. {
  100. c.emplace_back(std::forward<Args>(args)...);
  101. std::push_heap(c.begin(), c.end(), comp);
  102. }
  103. __GBLIBCPP_CONSTEXPR
  104. void pop(void)
  105. {
  106. std::pop_heap(c.begin(), c.end(), comp);
  107. c.pop_back();
  108. }
  109. __GBLIBCPP_CONSTEXPR
  110. void swap(priority_queue& other) noexcept(
  111. noexcept(std::swap(c, other.c)) &&
  112. noexcept(std::swap(comp, other.comp)))
  113. {
  114. std::swap(c, other.c);
  115. std::swap(comp, other.comp);
  116. }
  117. };
  118. template <typename Compare, typename Container>
  119. priority_queue(Compare, Container)
  120. -> priority_queue<typename Container::value_type,
  121. Container, Compare>;
  122. template <typename T, typename Container, typename Compare>
  123. void swap(priority_queue<T, Container, Compare>& lhs,
  124. priority_queue<T, Container, Compare>& rhs)
  125. noexcept(noexcept(lhs.swap(rhs)))
  126. { lhs.swap(rhs); }
  127. } // namespace std
  128. #endif