From 238560250063e1d8423a053a0ddae2895f09153c Mon Sep 17 00:00:00 2001 From: Mateusz Loskot Date: Fri, 11 Aug 2017 01:07:29 +0200 Subject: [PATCH] Switch to reliable non-existent handle for QueryHeap items. Default-constructed objects of (boost::heap) handle_type are singular, including the wrapped handle_type::iterator. Apparently, MSVC iterator debug facilities strictly require that one singular instance is compared to another singular instance. It is not possible to get check-comparabe iterators of non-singular and singular instances as owning container will always mismatch. --- include/util/query_heap.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/include/util/query_heap.hpp b/include/util/query_heap.hpp index 8f29ee6bb..5f83502ba 100644 --- a/include/util/query_heap.hpp +++ b/include/util/query_heap.hpp @@ -180,7 +180,16 @@ class QueryHeap { BOOST_ASSERT(WasInserted(node)); const Key index = node_index.peek_index(node); - return inserted_nodes[index].handle == HeapHandle{}; + + // Use end iterator as a reliable "non-existent" handle. + // Default-constructed handles are singular and + // can only be checked-compared to another singular instance. + // Behaviour investigated at https://lists.boost.org/boost-users/2017/08/87787.php, + // eventually confirmation at https://stackoverflow.com/a/45622940/151641. + // Corrected in https://github.com/Project-OSRM/osrm-backend/pull/4396 + auto const end_it = const_cast(heap).end(); // non-const iterator + auto const none_handle = heap.s_handle_from_iterator(end_it); // from non-const iterator + return inserted_nodes[index].handle == none_handle; } bool WasInserted(const NodeID node) const @@ -210,14 +219,15 @@ class QueryHeap BOOST_ASSERT(!heap.empty()); const Key removedIndex = heap.top().second; heap.pop(); - inserted_nodes[removedIndex].handle = HeapHandle{}; + inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end()); return inserted_nodes[removedIndex].node; } void DeleteAll() { - std::for_each(inserted_nodes.begin(), inserted_nodes.end(), [](auto &node) { - node.handle = HeapHandle(); + auto const none_handle = heap.s_handle_from_iterator(heap.end()); + std::for_each(inserted_nodes.begin(), inserted_nodes.end(), [&none_handle](auto &node) { + node.handle = none_handle; }); heap.clear(); }