diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-02-28 15:42:39 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-02-28 15:42:39 +0000 |
commit | d63f5ce1cb86e69da28bd74b21e9452dbd88a38f (patch) | |
tree | 0c9495f8cb5af05e6068b69d5d57551cc2331a97 /lib/collection.hpp | |
parent | Just use addLinksBetween (diff) | |
download | ilt-d63f5ce1cb86e69da28bd74b21e9452dbd88a38f.tar.bz2 ilt-d63f5ce1cb86e69da28bd74b21e9452dbd88a38f.tar.xz ilt-d63f5ce1cb86e69da28bd74b21e9452dbd88a38f.zip |
Move utility to lib
Diffstat (limited to 'lib/collection.hpp')
-rw-r--r-- | lib/collection.hpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/collection.hpp b/lib/collection.hpp new file mode 100644 index 0000000..79c331a --- /dev/null +++ b/lib/collection.hpp @@ -0,0 +1,71 @@ +#ifndef COLLECTION_H +#define COLLECTION_H + +#include <algorithm> +#include <memory> +#include <type_traits> + +template<typename Object, bool shared = true> class Collection { +public: + using Ptr = std::conditional_t<shared, std::shared_ptr<Object>, std::unique_ptr<Object>>; + using Objects = std::vector<Ptr>; + Objects objects; + + template<typename T = Object, typename... Params> + auto + create(Params &&... params) + { + if constexpr (shared) { + auto obj = std::make_shared<T>(std::forward<Params>(params)...); + objects.emplace_back(obj); + return obj; + } + else { + return static_cast<T *>(objects.emplace_back(std::make_unique<T>(std::forward<Params>(params)...)).get()); + } + } + + template<typename T = Object, typename M = void, typename... Params> + auto + apply(const M & m, Params &&... params) const + { + return std::count_if(objects.begin(), objects.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 M = void, typename... Params> + auto + applyOne(const M & m, Params &&... params) const + { + return std::find_if(objects.begin(), objects.end(), [&m, ¶ms...](auto && op) { + if (auto o = dynamic_cast<T *>(op.get())) { + return std::invoke(m, o, std::forward<Params>(params)...); + } + return false; + }); + } + + template<typename T = Object> + void + removeAll() + { + objects.erase(std::remove_if(objects.begin(), objects.end(), + [](auto && op) { + return dynamic_cast<T *>(op.get()); + }), + objects.end()); + } + + auto + end() const + { + return objects.end(); + } +}; + +#endif |