cpp-sort turns every sorting algorithm into a function object
Sorting algorithms & related tools for C++
At a glance
- What is it?
- cpp-sort is a header-only C++17 library built around one generic sorting interface, where algorithms, adapters, a sorter facade, metrics and measures of disorder are separate pieces you compose. It is a library for people who have to pick a sorting algorithm deliberately.
- Who is it for?
- Use cpp-sort when the choice of sorting algorithm is part of your problem, for instance when you need adaptivity, proxy iterator support or movable-only elements, and when a reviewer will ask why the code does not simply call std::sort. Skip it for ordinary sorting of a vector, where the standard library is already enough.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 12 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One generic interface over many algorithms
cpp-sort is a generic C++17 header-only sorting library that revolves around one main generic sorting interface and provides several small tools to pick or design sorting algorithms.
The library is introduced with a quotation from Donald Knuth's The Art Of Computer Programming, Volume 3, which is the right frame for it. Knuth's point is that it would be nice if one or two sorting methods dominated all others regardless of application or computer, but in fact each method has its own peculiar virtues, and nearly all of the algorithms deserve to be remembered since there are applications in which they turn out to be best.
That is precisely the problem the library addresses. std::sort is a fine default, and if you have never measured anything, it should stay your default. But when the data has a known character, for example a nearly sorted array, a large number of duplicates, or elements that are not copyable, the right algorithm is not obvious and the standard library does not let you change it.
Being header-only is a deliberate choice with a clear trade-off. There is nothing to build, nothing to link, and the implementation is visible in the translation unit that uses it, at the cost of longer compile times and a binary that only contains the algorithms you instantiate.
The basic use is meant to be trivial, and the README shows it as a single include, a single call and a loop to print the result.
The example that shows the whole model in twelve lines
The README gives a first example that sorts a small array with a smooth sort, which is one of the less common algorithms in wide use and a good demonstration that the library takes the algorithm as a parameter of the call rather than a setting.
#include <array>
#include <iostream>
#include <cpp-sort/sorters/smooth_sorter.h>
int main()
{
std::array<int, 5> arr = { 5, 8, 3, 2, 9 };
cppsort::smooth_sort(arr);
// prints 2 3 5 8 9
for (int val: arr) {
std::cout << val << ' ';
}
}Two things are worth noticing. The algorithm is named in the include path, so the reader of the code knows which sorting algorithm is in use without tracing a template parameter. And the call takes the collection and nothing else, because the smooth sort needs no comparator for a plain array of integers.
The second example in the README is the one that explains the design. It defines a wrapper struct with a value member, puts five of them in a forward list and five in a vector, and then builds a sorter that uses a pattern-defeating quicksort for random-access collections and a mergesort otherwise.
cppsort::hybrid_adapter<
cppsort::pdq_sorter,
cppsort::merge_sorter
> sorter;
// Sort li and vec in reverse order using their value member
sorter(li, std::greater{}, &wrapper::value);
sorter(vec, std::greater{}, &wrapper::value);The same sorter object handles both containers, choosing the algorithm per collection, and the projection parameter points at the member to sort by. This is the composition story in miniature: algorithms are types, the choice between them is a type, and the call site stays the same.
Sorters, adapters, a facade, metrics and disorder measures
The README lists the main building blocks of the library, and each one is a separate, replaceable piece.
Every sorting algorithm exists as a function object called a sorter. Sorters can be wrapped in sorter adapters to augment their behaviour. The library provides a sorter facade to easily build sorters. Fixed-size sorters can be used to efficiently sort tiny fixed-size collections. Metrics can be used to gather information about the sorting operation. Measures of disorder can be used to evaluate the disorder in a collection.
The separation of sorters and adapters is the central idea. A sorter is one algorithm with one behaviour. An adapter wraps a sorter and changes how it behaves without changing which algorithm runs, which is what makes the library composable rather than a list of unrelated options.
The benchmark section demonstrates this concretely. The graph in the README shows the time needed for heap_sort to sort one million elements without being adapted, then when it is adapted with either drop_merge_adapter or split_adapter, as the number of inversions in the std::vector<int> increases. Wrapping heap_sort with either of the adapters makes it adaptive to the number of inversions in a non-intrusive manner, and the two algorithms used to adapt it have different pros and cons, so the choice is left to the user.
The measures of disorder are the other half of that story. If you can measure how unsorted a collection is, you can decide whether it is worth switching algorithm at runtime, or simply report the disorder as a diagnostic.
The README is candid that the benchmark exists mostly to show what the library can do, with more commented benchmarks in a dedicated wiki page.
The guarantees that make it usable with awkward types
Even when the extra features are not used, the README states that the sorting functions still provide a set of guarantees, with the ideas often taken from the Ranges TS.
They provide both an iterator and a range interface. When possible they accept a custom comparator parameter, and most of them accept a projection parameter.
The interesting ones are about awkward types and containers. They correctly handle proxy iterators with iter_swap and iter_move, and they also work when iterators provide neither post-increment nor post-decrement. The value types of the collections to be sorted need not be default-constructible, and they need not be copyable, only movable.
Those last four are the ones that separate a real library from a wrapper around std::sort. A vector of a move-only type will not compile with std::sort in most standard configurations, because sorting may need to create a temporary. A container with proxy iterators, such as a vector of bool or a custom transform iterator, breaks algorithms that assume a real reference type. A forward-only iterator without post-increment support trips implementations that write `*first++ = value`.
Two smaller but real conveniences round out the list. Stateless sorters can be converted to a function pointer for each overloaded operator(), and sorters are function objects, so they can be passed directly as overload sets to other functions.
The repository carries a .clang-tidy configuration, an examples/ directory with files such as bubble_sorter.cpp, list_selection_sorter.cpp, randomizing_adapter.cpp and readme_example.cpp, plus a tests/ directory, so the behaviour above is exercised rather than merely claimed.
Compiler support is a matrix, and Visual Studio needs a flag
cpp-sort requires C++17 support, and the README lists the compilers it should work with.
g++-9 or more recent, and clang++-11 or more recent with both libstdc++ and libc++. The versions of MinGW-w64 and AppleClang equivalent to those compilers. Visual Studio 2022 version 17.14.36414.22 or more recent, only with /permissive-, and a few features are unavailable in that case. And clang-cl corresponding to the Visual Studio version above.
The CI pipeline runs on four platforms, with build status badges for Ubuntu, MSVC, MinGW-w64 and macOS, and the library is also tested with the most recent versions of those compilers on a regular basis. The compilers listed are the ones used by the pipeline, and all the other versions in between are untested but should also work, with an invitation to open an issue if that is not the case.
The Visual Studio line deserves a second look. The requirement for /permissive- and the note that a few features are unavailable is the kind of caveat that gets missed until a build fails, so a team on MSVC should check the wiki changelog for the differences tied to the C++ version and the enabled compiler extensions.
The default branch is 2.x.y-develop, and older versions of the library targeting C++14 are still available in the 1.x.y-develop and 1.x.y-stable branches, but they are not actively developed anymore, with an offer to open an issue if something needs to be backported.
CMake and Conan support, and a MIT licence
The main repository contains additional support for standard tooling such as CMake or Conan, with details in the wiki.
Conan is the more visible of the two here, because the README carries a Conan package badge tied to version 2.2.0, and the top level has a conanfile.py. CMake is present as well, with a CMakeLists.txt at the root and a cmake/ directory, and the examples directory has its own CMakeLists.txt so the sample programs can be built as part of the project.
The repository layout also shows the discipline of the project. There is a .clang-tidy configuration, a test_package/ directory, which is the conventional location for a Conan recipe's test, a benchmarks/ directory, tools/, docs/ and a LICENSE.txt alongside a NOTICE.txt.
The licence is MIT, with the LICENSE.txt and NOTICE.txt files at the root of the repository.
The release record shows two lines in active use at once. The 2.x line is the current one, with v2.2.0 published on 2026-08-24 and v2.1.0 on 2026-01-18, and the tag names carry names, v2.2.0 Carrig Bru and v2.1.0 Brewing. The 1.x line still receives point releases for the C++14 target, with 1.17.3 Manifique published on 2026-08-25. The last push was on 2026-10-11 and the repository is not archived.
Two lines being maintained at once is a deliberate compatibility choice rather than a sign of confusion, but it does mean an upgrade decision has two axes: the 2.x line for new work, and the frozen 1.x line for projects that cannot move to C++17 yet.
Editorial conclusion
Use cpp-sort when the choice of sorting algorithm is part of your problem, for instance when you need adaptivity, proxy iterator support or movable-only elements, and when a reviewer will ask why the code does not simply call std::sort. Skip it for ordinary sorting of a vector, where the standard library is already enough. Before adopting, confirm your compiler is in the supported matrix, and remember that the Visual Studio support requires /permissive- with a few features unavailable, and that the C++14 line is frozen on the 1.x.y branches.
Frequently asked questions
What is cpp-sort and how do I use it?
It is a generic C++17 header-only sorting library. Every sorting algorithm exists as a function object called a sorter, and you call it directly, for example cppsort::smooth_sort(arr) after including <cpp-sort/sorters/smooth_sorter.h>.
What is a sorter adapter in cpp-sort?
Sorters can be wrapped in sorter adapters to augment their behaviour without changing which algorithm runs. The README's benchmark shows heap_sort wrapped in either drop_merge_adapter or split_adapter becoming adaptive to the number of inversions in the collection.
Does cpp-sort work with proxy iterators and move-only element types?
Yes. The README states that the sorters correctly handle proxy iterators with iter_swap and iter_move, work when iterators provide neither post-increment nor post-decrement, and do not require the value types to be default-constructible or copyable, only movable.
Which compilers does cpp-sort support?
It requires C++17 and should work with g++-9 or newer, clang++-11 or newer with libstdc++ or libc++, the equivalent MinGW-w64 and AppleClang versions, and Visual Studio 2022 version 17.14.36414.22 or newer only with /permissive-, where a few features are unavailable.
Can I still use cpp-sort with C++14?
Older versions targeting C++14 are still available in the 1.x.y-develop and 1.x.y-stable branches, but they are not actively developed anymore. The README asks you to open an issue if something needs to be backported.
What licence is cpp-sort released under?
It is released under the MIT licence, with the terms in the LICENSE.txt file and the NOTICE.txt file at the root of the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/morwenn-cpp-sort)Was this useful?