EnTT  3.10.0
algorithm.hpp
1 #ifndef ENTT_CORE_ALGORITHM_HPP
2 #define ENTT_CORE_ALGORITHM_HPP
3 
4 #include <algorithm>
5 #include <functional>
6 #include <iterator>
7 #include <utility>
8 #include <vector>
9 #include "utility.hpp"
10 
11 namespace entt {
12 
21 struct std_sort {
35  template<typename It, typename Compare = std::less<>, typename... Args>
36  void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const {
37  std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
38  }
39 };
40 
54  template<typename It, typename Compare = std::less<>>
55  void operator()(It first, It last, Compare compare = Compare{}) const {
56  if(first < last) {
57  for(auto it = first + 1; it < last; ++it) {
58  auto value = std::move(*it);
59  auto pre = it;
60 
61  for(; pre > first && compare(value, *(pre - 1)); --pre) {
62  *pre = std::move(*(pre - 1));
63  }
64 
65  *pre = std::move(value);
66  }
67  }
68  }
69 };
70 
76 template<std::size_t Bit, std::size_t N>
77 struct radix_sort {
78  static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass");
79 
95  template<typename It, typename Getter = identity>
96  void operator()(It first, It last, Getter getter = Getter{}) const {
97  if(first < last) {
98  static constexpr auto mask = (1 << Bit) - 1;
99  static constexpr auto buckets = 1 << Bit;
100  static constexpr auto passes = N / Bit;
101 
102  using value_type = typename std::iterator_traits<It>::value_type;
103  std::vector<value_type> aux(std::distance(first, last));
104 
105  auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
106  std::size_t index[buckets]{};
107  std::size_t count[buckets]{};
108 
109  for(auto it = from; it != to; ++it) {
110  ++count[(getter(*it) >> start) & mask];
111  }
112 
113  for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) {
114  index[pos + 1u] = index[pos] + count[pos];
115  }
116 
117  for(auto it = from; it != to; ++it) {
118  out[index[(getter(*it) >> start) & mask]++] = std::move(*it);
119  }
120  };
121 
122  for(std::size_t pass = 0; pass < (passes & ~1); pass += 2) {
123  part(first, last, aux.begin(), pass * Bit);
124  part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
125  }
126 
127  if constexpr(passes & 1) {
128  part(first, last, aux.begin(), (passes - 1) * Bit);
129  std::move(aux.begin(), aux.end(), first);
130  }
131  }
132  }
133 };
134 
135 } // namespace entt
136 
137 #endif
EnTT default namespace.
Definition: dense_map.hpp:22
Function object for performing insertion sort.
Definition: algorithm.hpp:42
void operator()(It first, It last, Compare compare=Compare{}) const
Sorts the elements in a range.
Definition: algorithm.hpp:55
Function object for performing LSD radix sort.
Definition: algorithm.hpp:77
void operator()(It first, It last, Getter getter=Getter{}) const
Sorts the elements in a range.
Definition: algorithm.hpp:96
Function object to wrap std::sort in a class type.
Definition: algorithm.hpp:21
void operator()(It first, It last, Compare compare=Compare{}, Args &&...args) const
Sorts the elements in a range.
Definition: algorithm.hpp:36