MyraMath
sortperm.h
Go to the documentation of this file.
1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
6 #ifndef MYRAMATH_UTILITY_SORTPERM_H
7 #define MYRAMATH_UTILITY_SORTPERM_H
8 
14 #include <vector>
15 #include <iterator>
16 #include <algorithm>
17 
18 #include <myramath/utility/detail/ssize.h>
19 
20 namespace myra {
21 namespace detail {
22 
23 // Implementation detail of sortperm(), holds an Iterator along with index data.
24 template<class Iterator> class sortperm_Pair
25  {
26  public:
27  sortperm_Pair(Iterator in_i, int in_index)
28  : i(in_i), index(in_index) { }
29  Iterator i;
30  int index;
31  };
32 
33 // Comparator for sortperm_Pair's. Compares through the iterator, but carries the index data along.
34 template<class Iterator, class Comparator> class sortperm_Comparator
35  {
36  public:
38  sortperm_Comparator(const Comparator& in_cmp)
39  : cmp(in_cmp) { }
40  bool operator() (const Pair& a, const Pair& b)
41  { return cmp(*(a.i),*(b.i)); }
42  private:
43  const Comparator& cmp;
44  };
45 
46 } // namespace detail
47 
49 template<class Iterator, class Comparator>
50 std::vector<int> sortperm(Iterator begin, Iterator end, const Comparator& cmp)
51  {
52  // Form pairs of iterators+indices ("schwartzian transform")
54  typedef std::vector<Pair> Pairs;
55  Pairs pairs; pairs.reserve(std::distance(begin,end));
56  for (Iterator i = begin; i != end; ++i)
57  pairs.push_back( Pair(i,ssize(pairs)) );
58  // Delegate to std::sort with a special comparator.
59  std::sort(pairs.begin(), pairs.end(), detail::sortperm_Comparator<Iterator,Comparator>(cmp));
60  // Extract permutation vector.
61  std::vector<int> perm; perm.reserve(pairs.size());
62  for (typename Pairs::const_iterator i = pairs.begin(); i != pairs.end(); ++i)
63  perm.push_back(i->index);
64  return perm;
65  }
66 
68 template<class Iterator>
69 std::vector<int> sortperm(Iterator begin, Iterator end)
70  {
71  typedef typename std::iterator_traits<Iterator>::value_type T;
72  typedef std::less<T> Comparator;
73  return sortperm(begin,end,Comparator());
74  }
75 
76 } // namespace myra
77 
78 #endif
std::vector< int > sortperm(Iterator begin, Iterator end, const Comparator &cmp)
Given a range, returns the permutation that will place it in sorted order according to cmp()...
Definition: sortperm.h:50
Definition: sortperm.h:34
Definition: syntax.dox:1
Definition: random.cpp:45
Definition: sortperm.h:24