EnTT  3.2.2
algorithm.hpp
1 #ifndef ENTT_CORE_ALGORITHM_HPP
2 #define ENTT_CORE_ALGORITHM_HPP
3 
4 
5 #include <utility>
6 #include <iterator>
7 #include <algorithm>
8 #include <functional>
9 #include "utility.hpp"
10 
11 
12 namespace entt {
13 
14 
23 struct std_sort {
37  template<typename It, typename Compare = std::less<>, typename... Args>
38  void operator()(It first, It last, Compare compare = Compare{}, Args &&... args) const {
39  std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
40  }
41 };
42 
43 
57  template<typename It, typename Compare = std::less<>>
58  void operator()(It first, It last, Compare compare = Compare{}) const {
59  if(first < last) {
60  for(auto it = first+1; it < last; ++it) {
61  auto value = std::move(*it);
62  auto pre = it;
63 
64  for(; pre > first && compare(value, *(pre-1)); --pre) {
65  *pre = std::move(*(pre-1));
66  }
67 
68  *pre = std::move(value);
69  }
70  }
71  }
72 };
73 
74 
80 template<std::size_t Bit, std::size_t N>
81 struct radix_sort {
82  static_assert((N % Bit) == 0);
83 
99  template<typename It, typename Getter = identity>
100  void operator()(It first, It last, Getter getter = Getter{}) const {
101  if(first < last) {
102  static constexpr auto mask = (1 << Bit) - 1;
103  static constexpr auto buckets = 1 << Bit;
104  static constexpr auto passes = N / Bit;
105 
106  using value_type = typename std::iterator_traits<It>::value_type;
107  std::vector<value_type> aux(std::distance(first, last));
108 
109  auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
110  std::size_t index[buckets]{};
111  std::size_t count[buckets]{};
112 
113  std::for_each(from, to, [&getter, &count, start](const value_type &item) {
114  ++count[(getter(item) >> start) & mask];
115  });
116 
117  std::for_each(std::next(std::begin(index)), std::end(index), [index = std::begin(index), count = std::begin(count)](auto &item) mutable {
118  item = *(index++) + *(count++);
119  });
120 
121  std::for_each(from, to, [&getter, &out, &index, start](value_type &item) {
122  out[index[(getter(item) >> start) & mask]++] = std::move(item);
123  });
124  };
125 
126  for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
127  part(first, last, aux.begin(), pass * Bit);
128  part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
129  }
130 
131  if constexpr(passes & 1) {
132  part(first, last, aux.begin(), (passes - 1) * Bit);
133  std::move(aux.begin(), aux.end(), first);
134  }
135  }
136  }
137 };
138 
139 
140 }
141 
142 
143 #endif // ENTT_CORE_ALGORITHM_HPP
entt::radix_sort::operator()
void operator()(It first, It last, Getter getter=Getter{}) const
Sorts the elements in a range.
Definition: algorithm.hpp:100
entt::std_sort::operator()
void operator()(It first, It last, Compare compare=Compare{}, Args &&... args) const
Sorts the elements in a range.
Definition: algorithm.hpp:38
entt::insertion_sort
Function object for performing insertion sort.
Definition: algorithm.hpp:45
entt::radix_sort
Function object for performing LSD radix sort.
Definition: algorithm.hpp:81
entt
EnTT default namespace.
Definition: algorithm.hpp:12
entt::insertion_sort::operator()
void operator()(It first, It last, Compare compare=Compare{}) const
Sorts the elements in a range.
Definition: algorithm.hpp:58
entt::std_sort
Function object to wrap std::sort in a class type.
Definition: algorithm.hpp:23