https://mooseframework.inl.gov
Loading...
Searching...
No Matches
IndirectSort.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include <functional>
13#include <vector>
14#include <algorithm>
15#include <iterator> // std::iterator_traits
16
17namespace Moose
18{
19
20// The indirect (or index) comparison functor is templated on a random
21// access iterator type, and a user comparison function. This class
22// is to be constructed with a random access iterator which points to
23// the beginning of the container whose values are to be indirectly
24// sorted. This class is not to be used directly by the user.
25template <class RandomAccessIterator, class UserComparisonFunctor>
27{
28 // ctor
29 indirect_comparator(RandomAccessIterator r, UserComparisonFunctor c)
31 {
32 }
33
34 // comparison operator - calls the user's comparison function on
35 // v[lhs] and v[rhs]
36 bool operator()(size_t lhs, size_t rhs)
37 {
38 // Note: operator[] is defined for random access iterators!
40 }
41
42private:
43 // data
44 RandomAccessIterator _random_access_iterator;
45 UserComparisonFunctor _user_comp;
46};
47
48// This is a common initialization function called by the indirect_sort's.
49// Should not be called directly by users...
50template <class RandomAccessIterator>
51void
52initialize_indirect_sort(RandomAccessIterator beg,
53 RandomAccessIterator end,
54 std::vector<size_t> & b)
55{
56 // enough storage for all the indices
57 b.resize(std::distance(beg, end));
58
59 // iota
60 for (size_t i = 0; i < b.size(); ++i)
61 b[i] = i;
62}
63
64// A generic indirect sort function templated on the iterator type. Uses
65// std::less<T> for the comparisons.
66template <class RandomAccessIterator>
67void
68indirectSort(RandomAccessIterator beg, RandomAccessIterator end, std::vector<size_t> & b)
69{
70 // Space in b
71 initialize_indirect_sort(beg, end, b);
72
73 // Typedef for less typing. Note: use of std::iterator_traits means this should work with
74 // naked pointers too...
75 typedef std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>
76 LessThanComparator;
77
78 // Construct comparator object
80
81 // Sort the indices, based on the data
82 //
83 // Many use cases pass in a partial order, not a total order; use
84 // stable_sort to make the results of that as reproduceable as
85 // possible.
86 std::stable_sort(b.begin(), b.end(), ic);
87}
88
89// A generic indirect sort function templated on the iterator type *and* the comparison functor
90// to be used for the ordering.
91template <class RandomAccessIterator, class UserComparisonFunctor>
92void
93indirectSort(RandomAccessIterator beg,
94 RandomAccessIterator end,
95 std::vector<size_t> & b,
96 UserComparisonFunctor user_comp)
97{
98 // Space in b
99 initialize_indirect_sort(beg, end, b);
100
101 // Construct comparator object
103
104 // Sort the indices, based on the data
105 //
106 // Many use cases pass in a partial order, not a total order; use
107 // stable_sort to make the results of that as reproduceable as
108 // possible.
109 std::stable_sort(b.begin(), b.end(), ic);
110}
111
114template <typename T>
115void
116applyIndices(T & container, const std::vector<size_t> & indices)
117{
118 T tmp;
119 tmp.resize(container.size());
120 for (size_t i = 0; i < indices.size(); i++)
121 tmp[i] = container[indices[i]];
122 std::swap(tmp, container);
123}
124
125} // namespace Moose
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
void applyIndices(T &container, const std::vector< size_t > &indices)
Uses indices created by the indirectSort function to sort the given container (which must support ran...
void indirectSort(RandomAccessIterator beg, RandomAccessIterator end, std::vector< size_t > &b)
void initialize_indirect_sort(RandomAccessIterator beg, RandomAccessIterator end, std::vector< size_t > &b)
UserComparisonFunctor _user_comp
indirect_comparator(RandomAccessIterator r, UserComparisonFunctor c)
RandomAccessIterator _random_access_iterator
bool operator()(size_t lhs, size_t rhs)