#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; } if (old_to_new[index] == index) { was_replaced[index] = true; 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]); } } template std::vector orderingToPermutation(const std::vector &ordering) { std::vector permutation(ordering.size()); for (auto index : util::irange(0, ordering.size())) permutation[ordering[index]] = index; return permutation; } } } #endif