#ifndef OSRM_UTIL_PERMUTATION_HPP #define OSRM_UTIL_PERMUTATION_HPP #include "util/integer_range.hpp" #include namespace osrm { namespace util { template void inplacePermutation(RandomAccesIterator begin, RandomAccesIterator end, const std::vector &old_to_new) { std::size_t size = std::distance(begin, end); BOOST_ASSERT(old_to_new.size() == size); // we need a little bit auxililary space since we need to mark // replaced elements in a non-destructive way std::vector was_replaced(size, false); for (auto index : util::irange(0, size)) { if (was_replaced[index]) continue; // iterate over a cycle in the permutation auto buffer = begin[index]; auto old_index = index; auto new_index = old_to_new[old_index]; for (; new_index != index; old_index = new_index, new_index = old_to_new[new_index]) { was_replaced[old_index] = true; std::swap(buffer, begin[new_index]); } was_replaced[old_index] = true; std::swap(buffer, begin[index]); } } } } #endif