#ifndef MAGYAR_SORT_H #define MAGYAR_SORT_H /** * single header lib: In-place, fast heavily modified and optimized radix sort. * * Only unsigned ints for now, but should be able to modify for int and float... * This is the counting variant with smart changes (not per-bit). * * LICENCE: CC3 - look it up, you need to mention me but that is all */ #include #include namespace MagyarSort { // Only change these if you know what you are doing // I use these because I want to see if nibbles are // better or something... // // Bytes of nibbles only: // - DIGIT_RANGE and BITS_PER_DIGIT should correspond // - DIGITS should also correspond with the uint32_t // - and DIGIT_RANGE should be 2^n value (16 or 256) static constexpr int DIGITS = 4; // "helyiérték" static constexpr int BITS_PER_DIGIT = 8; // "bit / helyiérték" static constexpr int DIGIT_RANGE = 256; // "helyiérték állapottér" template static inline uint32_t getDigit(uint32_t num) noexcept { static constexpr int SHIFT = digitChoice * BITS_PER_DIGIT; uint32_t shifted = num >> SHIFT; return shifted & DIGIT_RANGE; } /** Sort the given array (in-place sorting) with the given size */ inline void sort(uint32_t arr[], size_t size) noexcept { // Holds "digit" occurences, prefix sums, whatevers // First "DIGIT_RANGE" elem is for MSB "DIGITS", last is for LSB static thread_local size_t radics[DIGITS * DIGIT_RANGE]; for(int i = 0; i < (DIGITS * DIGIT_RANGE); ++i) { radics[i] = 0; } // Calculate occurences of digits for(size_t i = 0; i < size; ++i) { auto d0 = getDigit<0>(arr[i]); auto d1 = getDigit<1>(arr[i]); auto d2 = getDigit<2>(arr[i]); auto d3 = getDigit<3>(arr[i]); ++radics[d0]; ++radics[d1 + DIGIT_RANGE * 1]; ++radics[d2 + DIGIT_RANGE * 2]; ++radics[d3 + DIGIT_RANGE * 3]; } // TODO: remove debug stuffz for(size_t j = 0; j < DIGITS; ++j) { printf("d%d: ", j); for(size_t i = 0; i < DIGIT_RANGE; ++i) { printf("%d,"); } printf("\n"); } } }; #endif