diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-23 18:09:16 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-23 18:09:16 +0000 |
commit | 8734626b2c6fc36acc59e0d7bf7e51d4cff719de (patch) | |
tree | aafec70ddb21a08a8ec6617bbb21e9de162f45b1 | |
parent | Use otherObjects where possible for find (diff) | |
download | ilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.tar.bz2 ilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.tar.xz ilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.zip |
Use typed collections for apply/applyOne
-rw-r--r-- | lib/collection.h | 53 | ||||
-rw-r--r-- | test/test-collection.cpp | 28 |
2 files changed, 64 insertions, 17 deletions
diff --git a/lib/collection.h b/lib/collection.h index 6ee6c82..d32cff1 100644 --- a/lib/collection.h +++ b/lib/collection.h @@ -86,28 +86,32 @@ public: auto apply(const auto & m, Params &&... params) const { - return apply_internal<T>(objects.begin(), objects.end(), m, std::forward<Params>(params)...); + const auto & srcObjects = containerFor<T>(); + return apply_internal<T>(srcObjects.begin(), srcObjects.end(), m, std::forward<Params>(params)...); } template<typename T = Object, typename... Params> auto rapply(const auto & m, Params &&... params) const { - return apply_internal<T>(objects.rbegin(), objects.rend(), m, std::forward<Params>(params)...); + const auto & srcObjects = containerFor<T>(); + return apply_internal<T>(srcObjects.rbegin(), srcObjects.rend(), m, std::forward<Params>(params)...); } template<typename T = Object, typename... Params> auto applyOne(const auto & m, Params &&... params) const { - return applyOne_internal<T>(objects.begin(), objects.end(), m, std::forward<Params>(params)...); + const auto & srcObjects = containerFor<T>(); + return applyOne_internal<T>(srcObjects.begin(), srcObjects.end(), m, std::forward<Params>(params)...); } template<typename T = Object, typename... Params> auto rapplyOne(const auto & m, Params &&... params) const { - return applyOne_internal<T>(objects.rbegin(), objects.rend(), m, std::forward<Params>(params)...); + const auto & srcObjects = containerFor<T>(); + return applyOne_internal<T>(srcObjects.rbegin(), srcObjects.rend(), m, std::forward<Params>(params)...); } template<typename T> @@ -248,25 +252,40 @@ protected: auto apply_internal(const auto begin, const auto end, const auto & m, Params &&... params) const { - return std::count_if(begin, end, [&m, ¶ms...](auto && op) { - if (auto o = dynamic_cast<T *>(op.get())) { - std::invoke(m, o, std::forward<Params>(params)...); - return true; - } - return false; - }); + if constexpr (std::is_convertible_v<decltype(std::to_address(*begin)), T *>) { + std::for_each(begin, end, [&m, ¶ms...](auto && op) { + std::invoke(m, op, std::forward<Params>(params)...); + }); + return std::distance(begin, end); + } + else { + return std::count_if(begin, end, [&m, ¶ms...](auto && op) { + if (auto o = dynamic_cast<T *>(op.get())) { + std::invoke(m, o, std::forward<Params>(params)...); + return true; + } + return false; + }); + } } template<typename T = Object, typename... Params> auto applyOne_internal(const auto begin, const auto end, const auto & m, Params &&... params) const { - return std::find_if(begin, end, [&m, ¶ms...](auto && op) { - if (auto o = dynamic_cast<T *>(op.get())) { - return std::invoke(m, o, std::forward<Params>(params)...); - } - return false; - }); + if constexpr (std::is_convertible_v<decltype(std::to_address(*begin)), T *>) { + return std::find_if(begin, end, [&m, ¶ms...](auto && op) { + return std::invoke(m, op, std::forward<Params>(params)...); + }); + } + else { + return std::find_if(begin, end, [&m, ¶ms...](auto && op) { + if (auto o = dynamic_cast<T *>(op.get())) { + return std::invoke(m, o, std::forward<Params>(params)...); + } + return false; + }); + } } }; diff --git a/test/test-collection.cpp b/test/test-collection.cpp index 7fadcf9..5aae9f0 100644 --- a/test/test-collection.cpp +++ b/test/test-collection.cpp @@ -21,6 +21,12 @@ public: return false; } + [[nodiscard]] virtual bool + yes() const + { + return true; + } + unsigned int total {0}; }; @@ -137,6 +143,8 @@ BOOST_AUTO_TEST_SUITE_END() using TestUniqueCollection = UniqueCollection<Base, Sub>; BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::const_iterator) BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::const_reverse_iterator) +BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::iterator) +BOOST_TEST_DONT_PRINT_LOG_VALUE(TestUniqueCollection::Objects::reverse_iterator) BOOST_FIXTURE_TEST_SUITE(utc, TestUniqueCollection) @@ -204,6 +212,26 @@ BOOST_AUTO_TEST_CASE(no_others) emplace(std::make_unique<Sub>()); } +BOOST_AUTO_TEST_CASE(applyAll) +{ + create<Base>(); + BOOST_CHECK_EQUAL(0, apply<Sub>(&Base::add)); + BOOST_CHECK_EQUAL(1, apply<Base>(&Base::add)); + create<Sub>(); + BOOST_CHECK_EQUAL(1, apply<Sub>(&Base::add)); + BOOST_CHECK_EQUAL(2, apply<Base>(&Base::add)); +} + +BOOST_AUTO_TEST_CASE(applyOneType) +{ + create<Base>(); + BOOST_CHECK_EQUAL(objects.end(), applyOne<Sub>(&Base::yes)); + BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes)); + create<Sub>(); + BOOST_CHECK_EQUAL(objects.begin() + 1, applyOne<Sub>(&Base::yes)); + BOOST_CHECK_EQUAL(objects.begin(), applyOne<Base>(&Base::yes)); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_CASE(wrapped_ptr_file_cons) |