summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-03-23 18:09:16 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2025-03-23 18:09:16 +0000
commit8734626b2c6fc36acc59e0d7bf7e51d4cff719de (patch)
treeaafec70ddb21a08a8ec6617bbb21e9de162f45b1
parentUse otherObjects where possible for find (diff)
downloadilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.tar.bz2
ilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.tar.xz
ilt-8734626b2c6fc36acc59e0d7bf7e51d4cff719de.zip
Use typed collections for apply/applyOne
-rw-r--r--lib/collection.h53
-rw-r--r--test/test-collection.cpp28
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, &params...](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, &params...](auto && op) {
+ std::invoke(m, op, std::forward<Params>(params)...);
+ });
+ return std::distance(begin, end);
+ }
+ else {
+ return std::count_if(begin, end, [&m, &params...](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, &params...](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, &params...](auto && op) {
+ return std::invoke(m, op, std::forward<Params>(params)...);
+ });
+ }
+ else {
+ return std::find_if(begin, end, [&m, &params...](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)