/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019 Danny Robson */ #include "list/sort.hpp" #include "random.hpp" #include "rand/generic.hpp" #include "tap.hpp" #include "iterator/zip.hpp" #include #include #include /////////////////////////////////////////////////////////////////////////////// template static void test_sort ( cruft::TAP::logger &tap, std::vector &&data, char const (&fmt)[N], ArgsT&&...args ) { // Pre-allocate the array so that we don't get caught by pointer // invalidation as we build the nodes. std::vector< cruft::list::node::compound > nodes (data.size ()); // Build the list and fold in the supplied data. for (auto [node, value]: cruft::iterator::zip (nodes, data)) { node.next = &node + 1; node.data = value; } nodes.back ().next = nullptr; // Actually do the sort and test the result. auto head = cruft::list::sort ( &nodes.front (), &nodes.back () ); tap.expect ( cruft::list::is_sorted (head), fmt, std::forward (args)... ); } //----------------------------------------------------------------------------- int main () { cruft::TAP::logger tap; // Try sorting a 'large' array of unique, but shuffled, contiguous integers. { // Don't use a power of two here. It won't exercise any edge cases in // the splitting logic of some sorts (like merge). static constexpr int COUNT = 500'000; // Create a list of randomly distributed integers. Use a constant seed so // we don't get randomised test results. std::vector data (COUNT); std::iota (std::begin (data), std::end (data), 0); std::shuffle ( std::begin (data), std::end (data), cruft::rand::general_generator {COUNT} ); test_sort (tap, std::move (data), "sorting large unique and shuffled array"); } // Try sorting a small array with identical elements { static constexpr int COUNT = 15; std::vector data (COUNT, COUNT); test_sort (tap, std::move (data), "sorting small identical array"); } return tap.status (); }