From ad5108bd5d8c91bc8d3cab0ab6240c4c6dc71ebc Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 27 Mar 2025 23:39:11 +0000 Subject: Fix up removeAll and test with more complex hierarchy --- lib/collection.h | 20 +++++++++--- test/test-collection.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/lib/collection.h b/lib/collection.h index 853b982..5f39e71 100644 --- a/lib/collection.h +++ b/lib/collection.h @@ -115,14 +115,24 @@ public: } template - requires(std::is_convertible_v || ...) + requires std::is_base_of_v auto removeAll() { - std::get>(otherObjects).clear(); - return std::erase_if(objects, [](auto && op) { - return dynamic_cast(op.get()); - }); + auto removeAllFrom = [](auto & container) { + if constexpr (std::is_base_of_v) { + const auto size = container.size(); + container.clear(); + return size; + } + else { + return std::erase_if(container, [](auto && objPtr) -> bool { + return dynamic_cast(std::to_address(objPtr)); + }); + } + }; + (removeAllFrom(std::get>(otherObjects)), ...); + return removeAllFrom(objects); } void diff --git a/test/test-collection.cpp b/test/test-collection.cpp index 90a3bd1..b0f2c43 100644 --- a/test/test-collection.cpp +++ b/test/test-collection.cpp @@ -42,6 +42,15 @@ public: class Sub1 : public Sub { }; +class Sub2 : public Sub { }; + +class Base2 { +public: + virtual ~Base2() = default; +}; + +class Multi : public Sub1, public Base2 { }; + using TestCollection = SharedCollection; BOOST_TEST_DONT_PRINT_LOG_VALUE(TestCollection::Objects::iterator) @@ -238,8 +247,9 @@ BOOST_AUTO_TEST_CASE(removeAllOfSub) create(); emplace(std::make_unique()); emplace(std::make_unique()); + emplace(std::make_unique()); - removeAll(); + BOOST_CHECK_EQUAL(removeAll(), 3); BOOST_CHECK_EQUAL(objects.size(), 2); BOOST_CHECK(std::get>(otherObjects).empty()); } @@ -280,6 +290,75 @@ BOOST_AUTO_TEST_CASE(applyOneType) BOOST_AUTO_TEST_SUITE_END() +using MultiCollection = Collection, Multi, Sub, Base2>; + +BOOST_FIXTURE_TEST_SUITE(multi, MultiCollection) + +BOOST_AUTO_TEST_CASE(addMulti) +{ + static_assert(MultiCollection::idx() == 0); + static_assert(MultiCollection::idx() == 1); + static_assert(MultiCollection::idx() == 2); + create(); + BOOST_CHECK_EQUAL(objects.size(), 1); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + create(); + BOOST_CHECK_EQUAL(objects.size(), 2); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 1); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + create(); + BOOST_CHECK_EQUAL(objects.size(), 3); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 2); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + create(); + BOOST_CHECK_EQUAL(objects.size(), 4); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 3); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + create(); + BOOST_CHECK_EQUAL(objects.size(), 5); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 1); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 4); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 1); +} + +BOOST_AUTO_TEST_CASE(removeMulti) +{ + create(); + create(); + create(); + create(); + create(); + BOOST_CHECK_EQUAL(objects.size(), 5); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 1); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 4); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 1); + + BOOST_CHECK_EQUAL(removeAll(), 1); + BOOST_CHECK_EQUAL(objects.size(), 4); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 3); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + + BOOST_CHECK_EQUAL(removeAll(), 3); + BOOST_CHECK_EQUAL(objects.size(), 1); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); + + BOOST_CHECK_EQUAL(removeAll(), 1); + BOOST_CHECK_EQUAL(objects.size(), 0); + BOOST_CHECK_EQUAL(std::get<0>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<1>(otherObjects).size(), 0); + BOOST_CHECK_EQUAL(std::get<2>(otherObjects).size(), 0); +} + +BOOST_AUTO_TEST_SUITE_END() + BOOST_AUTO_TEST_CASE(wrapped_ptr_file_cons) { using FilePtr = wrapped_ptr; -- cgit v1.2.3