17 #ifndef COM_SAXBOPHONE_TR_SORT_HPP
18 #define COM_SAXBOPHONE_TR_SORT_HPP
23 #include <type_traits>
45 std::size_t Extent = std::dynamic_extent,
46 typename Real =
long double
48 void sort(std::span<T, Extent> data) {
50 if (data.size() < 2) {
54 std::size_t size = data.size();
56 if constexpr (std::is_floating_point<T>::value) {
57 min = +std::numeric_limits<T>::infinity();
58 max = -std::numeric_limits<T>::infinity();
60 min = std::numeric_limits<T>::max();
61 max = std::numeric_limits<T>::lowest();
68 bool already_sorted =
true;
69 for (
auto datum : data) {
83 if (datum < previous) {
84 already_sorted =
false;
93 if (data.size() == 2) {
95 data[data.size() - 1] = max;
98 if constexpr (std::is_floating_point<T>::value) {
99 if (min == -std::numeric_limits<T>::infinity()) {
100 min = std::numeric_limits<T>::lowest();
102 if (max == +std::numeric_limits<T>::infinity()) {
103 max = std::numeric_limits<T>::max();
108 range = (Real)max - (Real)min;
110 std::vector<std::vector<T>> sorts(data.size() + 2);
111 for (
auto n : data) {
112 if constexpr (std::is_floating_point<T>::value) {
113 if (n == -std::numeric_limits<T>::infinity()) {
114 sorts[0].push_back(n);
116 }
else if (n == +std::numeric_limits<T>::infinity()) {
117 sorts[sorts.size() - 1].push_back(n);
122 Real raw_pos = std::ceil((((Real)n - min) / range) * (size - 1));
123 std::size_t pos = std::isnan(raw_pos) ? 1u : (std::size_t)raw_pos;
126 }
else if (raw_pos > (sorts.size() - 1)) {
127 pos = sorts.size() - 1;
130 sorts[pos].push_back(n);
134 for (
auto& bucket : sorts) {
136 if (bucket.size() > 1) {
137 sort<T, std::dynamic_extent, Real>(bucket);
139 for (T datum : bucket) {
Definition: tr-sort.hpp:27
void sort(std::span< T, Extent > data)
Stable sorts the input dating using the Transposition Sort sorting algorithm.
Definition: tr-sort.hpp:48