--- libgeos/geos/include/geos/index/strtree/TemplateSTRtree.h.orig 2021-11-18 21:07:45.622785813 +0100 +++ libgeos/geos/include/geos/index/strtree/TemplateSTRtree.h 2021-11-18 21:09:00.690195225 +0100 @@ -359,12 +359,12 @@ // begin and end define a range of nodes needing parents auto begin = nodes.begin(); - auto end = nodes.end(); + auto number = static_cast(std::distance(begin, nodes.end())); - while (std::distance(begin, end) > 1) { - createParentNodes(begin, end); - begin = end; // parents just added become children in the next round - end = nodes.end(); + while (number > 1) { + createParentNodes(begin, number); + std::advance(begin, static_cast(number)); // parents just added become children in the next round + number = static_cast(std::distance(begin, nodes.end())); } assert(finalSize == nodes.size()); @@ -421,22 +421,24 @@ return nodesInTree; } - void createParentNodes(const NodeListIterator& begin, const NodeListIterator& end) { + void createParentNodes(const NodeListIterator& begin, size_t number) { // Arrange child nodes in two dimensions. // First, divide them into vertical slices of a given size (left-to-right) // Then create nodes within those slices (bottom-to-top) - auto numChildren = static_cast(std::distance(begin, end)); - auto numSlices = sliceCount(numChildren); - std::size_t nodesPerSlice = sliceCapacity(numChildren, numSlices); + auto numSlices = sliceCount(number); + std::size_t nodesPerSlice = sliceCapacity(number, numSlices); // We could sort all of the nodes here, but we don't actually need them to be // completely sorted. They need to be sorted enough for each node to end up // in the right vertical slice, but their relative position within the slice // doesn't matter. So we do a partial sort for each slice below instead. + auto end = begin + static_cast(number); sortNodesX(begin, end); auto startOfSlice = begin; for (decltype(numSlices) j = 0; j < numSlices; j++) { + // end iterator is being invalidated at each iteration + end = begin + static_cast(number); auto nodesRemaining = static_cast(std::distance(startOfSlice, end)); auto nodesInSlice = std::min(nodesRemaining, nodesPerSlice); auto endOfSlice = std::next(startOfSlice, static_cast(nodesInSlice));