{"id":13757207,"url":"https://github.com/timsort/cpp-TimSort","last_synced_at":"2025-05-10T05:31:48.407Z","repository":{"id":1694916,"uuid":"2423322","full_name":"timsort/cpp-TimSort","owner":"timsort","description":"A C++ implementation of timsort","archived":false,"fork":false,"pushed_at":"2024-12-03T19:58:18.000Z","size":231,"stargazers_count":306,"open_issues_count":2,"forks_count":45,"subscribers_count":17,"default_branch":"3.x.y","last_synced_at":"2025-05-07T23:43:11.660Z","etag":null,"topics":["algorithm","c-plus-plus","sort","sorting"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timsort.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-09-20T15:31:09.000Z","updated_at":"2025-04-15T22:50:56.000Z","dependencies_parsed_at":"2024-01-25T05:23:56.722Z","dependency_job_id":"d8086f9d-90db-4457-9b3c-da682ab2bc50","html_url":"https://github.com/timsort/cpp-TimSort","commit_stats":{"total_commits":188,"total_committers":9,"mean_commits":20.88888888888889,"dds":0.6276595744680851,"last_synced_commit":"99b612d9826e8387a30008f2b21be206181ad890"},"previous_names":["gfx/cpp-timsort"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timsort%2Fcpp-TimSort","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timsort%2Fcpp-TimSort/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timsort%2Fcpp-TimSort/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timsort%2Fcpp-TimSort/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timsort","download_url":"https://codeload.github.com/timsort/cpp-TimSort/tar.gz/refs/heads/3.x.y","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253371072,"owners_count":21897998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithm","c-plus-plus","sort","sorting"],"created_at":"2024-08-03T12:00:29.299Z","updated_at":"2025-05-10T05:31:48.397Z","avatar_url":"https://github.com/timsort.png","language":"C++","readme":"[![Latest Release](https://img.shields.io/badge/release-3.0.1-blue.svg)](https://github.com/timsort/cpp-TimSort/releases/tag/v3.0.1)\n[![Conan Package](https://img.shields.io/badge/conan-cpp--TimSort%2F3.0.1-blue.svg)](https://conan.io/center/recipes/timsort?version=3.0.1)\n[![Pitchfork Layout](https://img.shields.io/badge/standard-PFL-orange.svg)](https://github.com/vector-of-bool/pitchfork)\n\n## TimSort\n\nA C++ implementation of TimSort, an O(n log n) stable sorting algorithm, ported from Python's and OpenJDK's.\n\nSee also the following links for a detailed description of TimSort:\n* http://svn.python.org/projects/python/trunk/Objects/listsort.txt\n* http://en.wikipedia.org/wiki/Timsort\n\nThis version of the library requires at least C++20. Older versions of the library, available in different branches,\noffer support for older standards though implement fewer features:\n* Branch `2.x.y` is compatible with C++11, and is slightly more permissive in some reagard due to the lack of\n  concepts to constrain its interface (it notaby supports iterators without postfix operator++/--).\n* Branch `1.x.y` is compatible with C++03.\nOlder versions are not actively maintained anymore. If you need extended support for those, please open specific\nissues for the problems you want solved.\n\nAccording to the benchmarks, `gfx::timsort` is slower than [`std::ranges::sort`][std-sort] on randomized sequences,\nbut faster on partially-sorted ones. It can be used as a drop-in replacement for [`std::ranges::stable_sort`][std-stable-sort],\nwith the difference that it can't fall back to a O(n log² n) algorithm when there isn't enough extra heap memory\navailable.\n\nMerging sorted ranges efficiently is an important part of the TimSort algorithm. This library exposes `gfx::timmerge`\nin the public API, a drop-in replacement for [`std::ranges::inplace_merge`][std-inplace-merge] with the difference\nthat it can't fall back to a O(n log n) algorithm when there isn't enough extra heap memory available. According to\nthe benchmarks, `gfx::timmerge` is slower than `std::ranges::inplace_merge` on heavily/randomly overlapping subranges\nof simple elements, but it is faster for complex elements such as `std::string`, and on sparsely overlapping subranges.\n\nThe ibrary exposes the following functions in namespace `gfx`:\n\n```cpp\n// timsort\n\ntemplate \u003c\n    std::random_access_iterator Iterator,\n    std::sentinel_for\u003cIterator\u003e Sentinel,\n    typename Compare = std::ranges::less,\n    typename Projection = std::identity\n\u003e\n    requires std::sortable\u003cIterator, Compare, Projection\u003e\nauto timsort(Iterator first, Sentinel last,\n             Compare compare={}, Projection projection={})\n    -\u003e Iterator;\n\ntemplate \u003c\n    std::ranges::random_access_range Range,\n    typename Compare = std::ranges::less,\n    typename Projection = std::identity\n\u003e\n    requires std::sortable\u003cstd::ranges::iterator_t\u003cRange\u003e, Compare, Projection\u003e\nauto timsort(Range \u0026range, Compare compare={}, Projection projection={})\n    -\u003e std::ranges::borrowed_iterator_t\u003cRange\u003e;\n\n// timmerge\n\ntemplate \u003c\n    std::random_access_iterator Iterator,\n    std::sentinel_for\u003cIterator\u003e Sentinel,\n    typename Compare = std::ranges::less,\n    typename Projection = std::identity\n\u003e\n    requires std::sortable\u003cIterator, Compare, Projection\u003e\nauto timmerge(Iterator first, Iterator middle, Sentinel last,\n              Compare compare={}, Projection projection={})\n    -\u003e Iterator;\n\ntemplate \u003c\n    std::ranges::random_access_range Range,\n    typename Compare = std::ranges::less,\n    typename Projection = std::identity\n\u003e\n    requires std::sortable\u003cstd::ranges::iterator_t\u003cRange\u003e, Compare, Projection\u003e\nauto timmerge(Range \u0026\u0026range, std::ranges::iterator_t\u003cRange\u003e middle,\n              Compare compare={}, Projection projection={})\n    -\u003e std::ranges::borrowed_iterator_t\u003cRange\u003e;\n```\n\n## EXAMPLE\n\nExample of using timsort with a defaulted comparison function and a projection function to sort a vector of strings\nby length:\n\n```cpp\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n#include \u003cgfx/timsort.hpp\u003e\n\nsize_t len(const std::string\u0026 str) {\n    return str.size();\n}\n\n// Sort a vector of strings by length\nstd::vector\u003cstd::string\u003e collection = { /* ... */ };\ngfx::timsort(collection, {}, \u0026len);\n```\n\n## INSTALLATION \u0026 COMPATIBILITY\n\n[![Ubuntu Builds](https://github.com/timsort/cpp-TimSort/actions/workflows/build-ubuntu.yml/badge.svg?branch=3.x.y)](https://github.com/timsort/cpp-TimSort/actions/workflows/build-ubuntu.yml)\n[![MSVC Builds](https://github.com/timsort/cpp-TimSort/actions/workflows/build-msvc.yml/badge.svg?branch=3.x.y)](https://github.com/timsort/cpp-TimSort/actions/workflows/build-msvc.yml)\n[![MinGW-w64 Builds](https://github.com/timsort/cpp-TimSort/actions/workflows/build-mingw.yml/badge.svg?branch=3.x.y)](https://github.com/timsort/cpp-TimSort/actions/workflows/build-mingw.yml)\n[![MacOS Builds](https://github.com/timsort/cpp-TimSort/actions/workflows/build-macos.yml/badge.svg?branch=3.x.y)](https://github.com/timsort/cpp-TimSort/actions/workflows/build-macos.yml)\n\nThe library is tested with the following compilers:\n* Ubuntu: GCC 10, Clang 11\n* Windows: MSVC 19.37.32826.1, MinGW-w64 GCC 12\n* MacOS: GCC 10, Clang 17\n\nThe library can be installed on the system via [CMake][cmake] (at least 3.14) with the following commands:\n\n```sh\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Release\ncmake --install build\n```\n\nAlternatively the library is also available [Conan Center][conan-center] and can be directly installed in your local\n[Conan][conan] cache with the following command:\n\n```sh\nconan install --requires=timsort/3.0.1\n```\n\n## DIAGNOSTICS \u0026 INFORMATION\n\nThe following configuration macros allow `gfx::timsort` and `gfx::timmerge` to emit diagnostics, which can be helpful\nto diagnose issues:\n* Defining `GFX_TIMSORT_ENABLE_ASSERT` light inserts assertions in key locations in the algorithm to avoid logic errors.\n* Defining `GFX_TIMSORT_ENABLE_AUDIT` inserts assertions that verify pre- and postconditions. These verifications can\n  slow the algorithm down significantly. Enable the audits only while testing or debugging. Enabling audits automatically\n  enables lighter assertions too.\n* Defining `GFX_TIMSORT_ENABLE_LOG` inserts logs in key locations, which allow to follow more closely the flow of the\n  algorithm.\n\n**cpp-TimSort** follows semantic versioning and provides the following macros to retrieve the current major, minor\nand patch versions:\n\n```cpp\nGFX_TIMSORT_VERSION_MAJOR\nGFX_TIMSORT_VERSION_MINOR\nGFX_TIMSORT_VERSION_PATCH\n```\n\n## TESTS\n\nThe tests are written with Catch2 and can be compiled with CMake and run through CTest.\n\nWhen using the project's main `CMakeLists.txt`, the CMake option `BUILD_TESTING` is `ON` by default unless the\nproject is included as a subdirectory. The following CMake options are available to change the way the tests are\nbuilt with CMake:\n* `GFX_TIMSORT_USE_VALGRIND`: if `ON`, the tests will be run through Valgrind (`OFF` by default)\n* `GFX_TIMSORT_SANITIZE`: this variable takes a comma-separated list of sanitizers options to run the tests (empty by default)\n\n## BENCHMARKS\n\nBenchmarks are available in the `benchmarks` subdirectory, and can be constructed directly by passing the option\n`-DBUILD_BENCHMARKS=ON` to CMake during the configuration step.\n\nExample bench_sort output (timing scale: sec.):\n\n    c++ -v\n    Apple LLVM version 7.0.0 (clang-700.0.72)\n    Target: x86_64-apple-darwin14.5.0\n    Thread model: posix\n    c++ -I. -Wall -Wextra -g  -DNDEBUG -O2 -std=c++11 example/bench.cpp -o .bin/bench\n    ./.bin/bench\n    RANDOMIZED SEQUENCE\n    [int]\n    size\t100000\n    std::sort        0.695253\n    std::stable_sort 0.868916\n    timsort          1.255825\n    [std::string]\n    size\t100000\n    std::sort        3.438217\n    std::stable_sort 4.122629\n    timsort          5.791845\n    REVERSED SEQUENCE\n    [int]\n    size\t100000\n    std::sort        0.045461\n    std::stable_sort 0.575431\n    timsort          0.019139\n    [std::string]\n    size\t100000\n    std::sort        0.586707\n    std::stable_sort 2.715778\n    timsort          0.345099\n    SORTED SEQUENCE\n    [int]\n    size\t100000\n    std::sort        0.021876\n    std::stable_sort 0.087993\n    timsort          0.008042\n    [std::string]\n    size\t100000\n    std::sort        0.402458\n    std::stable_sort 2.436326\n    timsort          0.298639\n\nExample bench_merge output (timing scale: milliseconds; omitted detailed results for different\nmiddle iterator positions, reformatted to improve readability):\n\n    c++ -v\n    Using built-in specs.\n    ...\n    Target: x86_64-pc-linux-gnu\n    ...\n    gcc version 10.2.0 (GCC)\n    c++ -I ../include -Wall -Wextra -g -DNDEBUG -O2 -std=c++11 bench_merge.cpp -o bench_merge\n    ./bench_merge\n    size\t100000\n    element type\\algorithm:      \tstd::inplace_merge\ttimmerge\n    RANDOMIZED SEQUENCE\n    [int] approx. average        \t 33.404430        \t 37.047990\n    [std::string] approx. average\t324.964249        \t210.297207\n    REVERSED SEQUENCE\n    [int] approx. average        \t 11.441404        \t  4.017482\n    [std::string] approx. average\t305.649503        \t114.773898\n    SORTED SEQUENCE\n    [int] approx. average        \t  4.291098        \t  0.105571\n    [std::string] approx. average\t158.238114        \t  0.273858\n\nDetailed bench_merge results for different middle iterator positions can be found at\nhttps://github.com/timsort/cpp-TimSort/wiki/Benchmark-results\n\n\n  [cmake]: https://cmake.org/\n  [conan]: https://conan.io/\n  [conan-center]: https://conan.io/center\n  [std-inplace-merge]: https://en.cppreference.com/w/cpp/algorithm/ranges/inplace_merge\n  [std-sort]: https://en.cppreference.com/w/cpp/algorithm/ranges/sort\n  [std-stable-sort]: https://en.cppreference.com/w/cpp/algorithm/ranges/stable_sort\n","funding_links":[],"categories":["Coding"],"sub_categories":["C++ Data Structures and Algorithms"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimsort%2Fcpp-TimSort","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimsort%2Fcpp-TimSort","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimsort%2Fcpp-TimSort/lists"}