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...);