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