12#include "idol/general/utils/Pair.h"
15 template<
class T>
struct get_id;
17 template<
class Key1,
class Key2>
18 struct get_id<std::pair<Key1, Key2>> {
19 auto operator()(
const std::pair<Key1, Key2>& t)
const {
return std::make_pair(get_id<Key1>()(t.first), get_id<Key2>()(t.second)); }
24 unsigned int operator()(
const T& t)
const {
return t.id(); }
27 template<
class Key1,
class Key2>
34 const T& operator()(
const T& t)
const {
return t; }
38 void apply_permutation(
const std::vector<unsigned int>& t_permutation, std::vector<T>& t_arg) {
40 std::vector<bool> visited(t_arg.size(),
false);
42 for (
size_t i = 0; i < t_arg.size(); ++i) {
50 T temp = std::move(t_arg[i]);
53 size_t next = t_permutation[current];
58 t_arg[current] = std::move(t_arg[next]);
59 visited[current] =
true;
63 t_arg[current] = std::move(temp);
64 visited[current] =
true;
68 template<
class FirstT,
class ...T>
69 void apply_permutation(
const std::vector<unsigned int>& t_permutation, std::vector<FirstT>& t_first, std::vector<T>& ...t_args) {
70 apply_permutation(t_permutation, t_first);
71 apply_permutation(t_permutation, t_args...);
74 template<
class IndexT,
class IndexExtractor =
identity<IndexT>,
class ...T>
75 void sort(std::vector<IndexT>& t_index,
76 std::vector<T>& ... t_args) {
78 std::vector<unsigned int> permutation(t_index.size());
79 std::iota(permutation.begin(), permutation.end(), 0);
83 [&t_index, extractor = IndexExtractor()](
unsigned int i,
unsigned int j) {
84 return extractor(t_index[i]) < extractor(t_index[j]);
88 apply_permutation(permutation, t_index, t_args...);