Intro
This is the very first time I actually expose myself to C++20 (concepts in this case). I decided to rewrite the Batcher's sort.
(This post has a continuation: Batcher's sort in C++20 - Take II.)
Code
batcherssort.h
#ifndef IO_GITHUB_CODERODDE_UTIL_BATCHERSSORT_H
#define IO_GITHUB_CODERODDE_UTIL_BATCHERSSORT_H
#include <cmath>
#include <concepts>
#include <utility>
#ifdef _OPENMP
#include <omp.h>
#endif
template <std::totally_ordered T>
void batchersSort(T* begin, T* end) {
auto n = end - begin;
if (n < 2) {
return;
}
auto t = (size_t) std::ceil(std::log2(n));
auto s = 1 << (t - 1);
for (size_t p = s; p > 0; p /= 2) {
size_t r = 0;
size_t d = p;
for (size_t q = s; q >= p; q /= 2) {
#ifdef _OPENMP
#pragma omp parallel for schedule(static)
#endif
for (std::ptrdiff_t k = 0; k < n - static_cast<std::ptrdiff_t>(d); ++k) {
if ((static_cast<std::size_t>(k) & p) == r) {
if (begin[k] > begin[k + d]) {
std::swap(begin[k], begin[k + d]);
}
}
}
d = q - p;
r = p;
}
}
}
#endif // IO_GITHUB_CODERODDE_UTIL_BATCHERSSORT_H
main.cpp
#include "batcherssort.h"
#include <algorithm>
#include <chrono>
#include <iostream>
#include <limits>
#include <random>
static const size_t N = 100000;
static size_t millis() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
}
static void fill(int* arr1, int* arr2) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(std::numeric_limits<int>::min(),
std::numeric_limits<int>::max());
for (size_t i = 0; i < N; ++i) {
int val = dist(gen);
arr1[i] = val;
arr2[i] = val;
}
}
int main()
{
int* arr1 = new int[N];
int* arr2 = new int[N];
fill(arr1, arr2);
auto ta = millis();
std::sort(arr1, arr1 + N);
auto tb = millis();
std::cout << "std::sort: " << (tb - ta) << " ms.\n";
ta = millis();
batchersSort(arr2, arr2 + N);
tb = millis();
std::cout << "batchersSort: " << (tb - ta) << " ms.\n";
std::cout << "Algorithms agree: "
<< std::boolalpha
<< std::equal(arr1, arr1 + N, arr2)
<< "\n";
}
Typical output
std::sort: 11 ms.
batchersSort: 25 ms.
Algorithms agree: true
Critique request
As always, I am eager to hear some constructive commentary.