diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-23 15:25:03 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-23 15:25:03 +0000 |
commit | 5f12ed9f259a825efc7c2354230932712273fab6 (patch) | |
tree | 5a2d24e651e107ed6bacb4ec363126be44c97b74 | |
parent | Other objects support in removeAll/clear (diff) | |
download | ilt-5f12ed9f259a825efc7c2354230932712273fab6.tar.bz2 ilt-5f12ed9f259a825efc7c2354230932712273fab6.tar.xz ilt-5f12ed9f259a825efc7c2354230932712273fab6.zip |
Use otherObjects where possible for find
-rw-r--r-- | lib/collection.h | 32 | ||||
-rw-r--r-- | test/test-collection.cpp | 29 |
2 files changed, 53 insertions, 8 deletions
diff --git a/lib/collection.h b/lib/collection.h index 98f043b..6ee6c82 100644 --- a/lib/collection.h +++ b/lib/collection.h @@ -54,12 +54,19 @@ public: T * find() { - if (auto i = std::find_if(objects.begin(), objects.end(), - [](auto && o) { - return (dynamic_cast<T *>(o.get())); - }); - i != objects.end()) { - return static_cast<T *>(i->get()); + const auto & srcObjects = containerFor<T>(); + if constexpr (std::is_convertible_v<typename std::remove_reference_t<decltype(srcObjects)>::value_type, T *>) { + if (srcObjects.empty()) { + return nullptr; + } + return srcObjects.front(); + } + else if (auto i = std::find_if(srcObjects.begin(), srcObjects.end(), + [](auto && o) { + return dynamic_cast<T *>(std::to_address(o)) != nullptr; + }); + i != srcObjects.end()) { + return static_cast<T *>(std::to_address(*i)); } return nullptr; } @@ -224,6 +231,19 @@ protected: ...); } + template<typename T> + [[nodiscard]] + const auto & + containerFor() const + { + if constexpr ((std::is_convertible_v<T *, Others *> || ...)) { + return std::get<OtherObjects<T>>(otherObjects); + } + else { + return objects; + } + } + template<typename T = Object, typename... Params> auto apply_internal(const auto begin, const auto end, const auto & m, Params &&... params) const diff --git a/test/test-collection.cpp b/test/test-collection.cpp index 13df95c..7fadcf9 100644 --- a/test/test-collection.cpp +++ b/test/test-collection.cpp @@ -47,6 +47,8 @@ BOOST_AUTO_TEST_CASE(empty) BOOST_REQUIRE(!apply(&Base::add)); const auto i = applyOne(&Base::add); BOOST_CHECK_EQUAL(i, end()); + BOOST_CHECK(!find<Base>()); + BOOST_CHECK(!find<Sub>()); } BOOST_AUTO_TEST_CASE(a_base) @@ -58,16 +60,20 @@ BOOST_AUTO_TEST_CASE(a_base) BOOST_CHECK_EQUAL(b->total, 1); const auto i = applyOne(&Base::add); BOOST_CHECK_EQUAL(i, end()); + BOOST_CHECK_EQUAL(b.get(), find<Base>()); + BOOST_CHECK(!find<Sub>()); } BOOST_AUTO_TEST_CASE(emplace_others) { - emplace(std::make_shared<Base>()); + auto b = emplace(std::make_shared<Base>()); BOOST_CHECK_EQUAL(objects.size(), 1); BOOST_CHECK(std::get<OtherObjects<Sub>>(otherObjects).empty()); - emplace(std::make_shared<Sub>()); + auto s = emplace(std::make_shared<Sub>()); BOOST_CHECK_EQUAL(objects.size(), 2); BOOST_CHECK_EQUAL(std::get<OtherObjects<Sub>>(otherObjects).size(), 1); + BOOST_CHECK_EQUAL(b.get(), find<Base>()); + BOOST_CHECK_EQUAL(s.get(), find<Sub>()); } BOOST_AUTO_TEST_CASE(a_rbase) @@ -107,6 +113,25 @@ BOOST_AUTO_TEST_CASE(rbegin_rend) BOOST_CHECK_EQUAL(2, std::distance(rbegin(), rend())); } +BOOST_AUTO_TEST_CASE(createCreate) +{ + auto b = findOrCreate<Base>(); + BOOST_CHECK(b); + auto b2 = findOrCreate<Base>(); + BOOST_CHECK_EQUAL(b, b2); + auto s = findOrCreate<Sub>(); + BOOST_CHECK_NE(s, b); + auto s2 = findOrCreate<Sub>(); + BOOST_CHECK_EQUAL(s, s2); +} + +BOOST_AUTO_TEST_CASE(createCreateSub) +{ + auto s = findOrCreate<Sub>(); + auto b = findOrCreate<Base>(); + BOOST_CHECK_EQUAL(s, b); +} + BOOST_AUTO_TEST_SUITE_END() using TestUniqueCollection = UniqueCollection<Base, Sub>; |