From b4d95c3842577e0fcb71e2d3e4adda7c82a661ba Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 14 Feb 2026 20:13:10 +0000 Subject: Add support for partitioning by 2 unary predicates Second predicate creates a single block of truthy values in the middle, and two falsy blocks at each end. --- test/test-instancing.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'test/test-instancing.cpp') diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index f303a15..4748f93 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -255,4 +255,59 @@ BOOST_AUTO_TEST_CASE(PartitionBy, *boost::unit_test::timeout(1)) checkReverseIndex(); } +BOOST_AUTO_TEST_CASE(PartitionBy2, *boost::unit_test::timeout(1)) +{ + std::mt19937 gen(std::random_device {}()); + std::uniform_int_distribution dist(0, 100000); + static constexpr auto COUNT = 20; + reserve(COUNT); + std::vector instances; + instances.reserve(COUNT); + // At least one of each + instances.push_back(acquire(1)); + instances.push_back(acquire(3)); + while (instances.size() < COUNT) { + instances.push_back(acquire(dist(gen))); + } + const std::vector values(instances.begin(), instances.end()); + BOOST_REQUIRE_EQUAL(size(), COUNT); + + const auto pred3 = [](auto value) { + return (value % 3) == 0; + }; + const auto pred5 = [](auto value) { + return (value % 5) == 0; + }; + auto matchedBoundaries = partition(pred3, pred5); + // As PartitionBy... primary partition is normal layout + // The underlying data is partitioned... + BOOST_REQUIRE(std::is_partitioned(mkcspan().cbegin(), mkcspan().cend(), pred3)); + // The external view of the data is unchanged... + BOOST_CHECK_EQUAL_COLLECTIONS(values.cbegin(), values.cend(), instances.cbegin(), instances.cend()); + // The partition point is right... + BOOST_CHECK(!pred3(at(matchedBoundaries.first))); + BOOST_CHECK(pred3(at(matchedBoundaries.first - 1))); + + // Secondary partition lives contiguous in the middle somewhere, with two falsy blocks at each end + const auto p2bndry = matchedBoundaries.second; + + BOOST_TEST_CONTEXT(mkcspan()) { + BOOST_TEST_CONTEXT(matchedBoundaries.first) { + BOOST_CHECK(std::all_of( + mkcspan().cbegin(), mkcspan().cbegin() + static_cast(matchedBoundaries.first), pred3)); + BOOST_CHECK(std::none_of( + mkcspan().cbegin() + static_cast(matchedBoundaries.first), mkcspan().cend(), pred3)); + } + + BOOST_TEST_CONTEXT(p2bndry) { + BOOST_CHECK(std::all_of(mkcspan().cbegin() + static_cast(p2bndry.first), + mkcspan().begin() + static_cast(p2bndry.second), pred5)); + BOOST_CHECK(std::none_of(mkcspan().cbegin(), mkcspan().cbegin() + static_cast(p2bndry.first), pred5)); + BOOST_CHECK(std::none_of(mkcspan().cbegin() + static_cast(p2bndry.second), mkcspan().cend(), pred5)); + } + } + + checkReverseIndex(); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.3