// SPDX-License-Identifier: MIT // Part of https://algorithm.tamnd.com/merge-sort/. The authors are listed in prov/4MRG7S.jsonl. #pragma once #include #include #include #include namespace algo { namespace detail { template void merge(std::span a, std::size_t mid, std::vector& b) { b.assign(std::make_move_iterator(a.begin()), std::make_move_iterator(a.begin() + mid)); // @line L6 std::size_t i = 0, j = mid, k = 0; // @line L7 while (i < b.size() && j < a.size()) { // @line L8 if (!(a[j] < b[i])) { // @line L9: b[i] <= a[j], with only < a[k] = std::move(b[i++]); } else { a[k] = std::move(a[j++]); // @line L10 } k++; // @line L11 } while (i < b.size()) { // @line L12 a[k++] = std::move(b[i++]); // @line L13 } } template void sort(std::span a, std::vector& b) { if (a.size() <= 1) return; // @line L1 std::size_t mid = a.size() / 2; // @line L2 sort(a.first(mid), b); // @line L3 sort(a.subspan(mid), b); // @line L4 merge(a, mid, b); // @line L5 } } // namespace detail // merge_sort sorts a in place, in non-decreasing order. The sort is stable. template void merge_sort(std::span a) { std::vector b; b.reserve((a.size() + 1) / 2); detail::sort(a, b); } } // namespace algo