diff --git a/src/libslic3r/MutablePriorityQueue.hpp b/src/libslic3r/MutablePriorityQueue.hpp index 88fbf48a58..81f3cb7829 100644 --- a/src/libslic3r/MutablePriorityQueue.hpp +++ b/src/libslic3r/MutablePriorityQueue.hpp @@ -41,6 +41,7 @@ public: bool empty() const { return m_heap.empty(); } T& operator[](std::size_t idx) noexcept { return m_heap[idx]; } const T& operator[](std::size_t idx) const noexcept { return m_heap[idx]; } + static constexpr size_t invalid_id() { return std::numeric_limits::max(); } using iterator = typename std::vector::iterator; using const_iterator = typename std::vector::const_iterator; @@ -69,14 +70,10 @@ MutablePriorityQueue make_ template inline void MutablePriorityQueue::clear() { -#ifdef NDEBUG - // Only mark as removed from the queue in release mode, if configured so. - if (ResetIndexWhenRemoved) -#endif /* NDEBUG */ - { + if constexpr (ResetIndexWhenRemoved) { for (size_t idx = 0; idx < m_heap.size(); ++ idx) // Mark as removed from the queue. - m_index_setter(m_heap[idx], std::numeric_limits::max()); + m_index_setter(m_heap[idx], this->invalid_id()); } m_heap.clear(); } @@ -103,13 +100,9 @@ template::pop() { assert(! m_heap.empty()); -#ifdef NDEBUG - // Only mark as removed from the queue in release mode, if configured so. - if (ResetIndexWhenRemoved) -#endif /* NDEBUG */ - { + if constexpr (ResetIndexWhenRemoved) { // Mark as removed from the queue. - m_index_setter(m_heap.front(), std::numeric_limits::max()); + m_index_setter(m_heap.front(), this->invalid_id()); } if (m_heap.size() > 1) { m_heap.front() = m_heap.back(); @@ -124,13 +117,10 @@ template::remove(size_t idx) { assert(idx < m_heap.size()); -#ifdef NDEBUG // Only mark as removed from the queue in release mode, if configured so. - if (ResetIndexWhenRemoved) -#endif /* NDEBUG */ - { + if constexpr (ResetIndexWhenRemoved) { // Mark as removed from the queue. - m_index_setter(m_heap[idx], std::numeric_limits::max()); + m_index_setter(m_heap[idx], this->invalid_id()); } if (idx + 1 == m_heap.size()) { m_heap.pop_back(); @@ -291,6 +281,7 @@ public: bool empty() const { return m_heap.empty(); } T& operator[](std::size_t idx) noexcept { assert(! address::is_padding(idx)); return m_heap[idx]; } const T& operator[](std::size_t idx) const noexcept { assert(! address::is_padding(idx)); return m_heap[idx]; } + static constexpr size_t invalid_id() { return std::numeric_limits::max(); } protected: void update_heap_up(size_t top, size_t bottom); @@ -320,15 +311,11 @@ MutableSkipHeapPriorityQueue inline void MutableSkipHeapPriorityQueue::clear() { -#ifdef NDEBUG - // Only mark as removed from the queue in release mode, if configured so. - if (ResetIndexWhenRemoved) -#endif /* NDEBUG */ - { + if constexpr (ResetIndexWhenRemoved) { for (size_t idx = 0; idx < m_heap.size(); ++ idx) // Mark as removed from the queue. if (! address::is_padding(idx)) - m_index_setter(m_heap[idx], std::numeric_limits::max()); + m_index_setter(m_heap[idx], this->invalid_id()); } m_heap.clear(); } @@ -359,13 +346,9 @@ template::pop() { assert(! m_heap.empty()); -#ifdef NDEBUG - // Only mark as removed from the queue in release mode, if configured so. - if (ResetIndexWhenRemoved) -#endif /* NDEBUG */ - { + if constexpr (ResetIndexWhenRemoved) { // Mark as removed from the queue. - m_index_setter(m_heap[1], std::numeric_limits::max()); + m_index_setter(m_heap[1], this->invalid_id()); } // Zero'th element is padding, thus non-empty queue must have at least two elements. if (m_heap.size() > 2) { @@ -382,13 +365,9 @@ inline void MutableSkipHeapPriorityQueue::max()); + m_index_setter(m_heap[idx], this->invalid_id()); } if (idx + 1 == m_heap.size()) { this->pop_back(); diff --git a/tests/libslic3r/test_mutable_priority_queue.cpp b/tests/libslic3r/test_mutable_priority_queue.cpp index 78c97bc7e1..5ea3db2763 100644 --- a/tests/libslic3r/test_mutable_priority_queue.cpp +++ b/tests/libslic3r/test_mutable_priority_queue.cpp @@ -346,25 +346,22 @@ TEST_CASE("Mutable priority queue - first pop", "[MutableSkipHeapPriorityQueue]" size_t id; float val; }; - size_t count = 50000; - std::vector idxs(count, {0}); - std::vector dels(count, false); + static constexpr const size_t count = 50000; auto q = make_miniheap_mutable_priority_queue( - [&](MyValue &v, size_t idx) { - idxs[v.id] = idx; - }, + [](MyValue &v, size_t idx) { v.id = idx; }, [](MyValue &l, MyValue &r) { return l.val < r.val; }); + using QueueType = decltype(q); q.reserve(count); - for (size_t id = 0; id < count; id++) { - MyValue mv{ id, rand() / 100.f }; - q.push(mv); - } - MyValue it = q.top(); // copy - q.pop(); + for (size_t id = 0; id < count; ++ id) + q.push({ id, rand() / 100.f }); + MyValue v = q.top(); // copy // is valid id (no initial value default value) - CHECK(it.id != 0); + CHECK(QueueType::address::is_padding(0)); + CHECK(!QueueType::address::is_padding(1)); + q.pop(); + CHECK(v.id == 1); // is first item in queue valid value - CHECK(idxs[0] != std::numeric_limits::max()); + CHECK(q.top().id == 1); } TEST_CASE("Mutable priority queue complex", "[MutableSkipHeapPriorityQueue]")