commit e8129215852034a143fdd6a5bed5e50353afbf64
parent 319adf93a20711ce74b1b868952c5919e8f60f4a
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Sat, 6 Jul 2024 20:55:07 +0000
filter-bubble: Add coroutine generator example which filters expired weak_ptr and keeps them sorted
Diffstat:
1 file changed, 64 insertions(+), 0 deletions(-)
diff --git a/src/filter-bubble.cpp b/src/filter-bubble.cpp
@@ -0,0 +1,64 @@
+#include <algorithm>
+#include <generator>
+#include <memory>
+#include <print>
+#include <random>
+#include <string>
+#include <vector>
+
+template <typename T>
+std::generator<T&> filter_bubble(std::vector<std::weak_ptr<T>>& vec)
+{
+ auto removed = vec.end();
+ auto it = vec.begin();
+
+ while (removed != it && it->expired())
+ std::iter_swap(it, --removed);
+
+ if (it != removed)
+ {
+ auto next = std::next(it);
+
+ while (next != removed)
+ {
+ if (next->expired())
+ {
+ std::iter_swap(next, --removed);
+ continue;
+ }
+ if (next->owner_before(*it))
+ std::iter_swap(it, next);
+ co_yield *it->lock();
+ it = next++;
+ }
+
+ co_yield *it->lock();
+ }
+
+ vec.erase(removed, vec.end());
+ co_return;
+}
+
+int main(int argv, char* argc[])
+{
+ std::vector<std::shared_ptr<std::string>> strings;
+ for (int i = 0; i < argv; ++i)
+ strings.push_back(std::make_shared<std::string>(argc[i]));
+
+ std::vector<std::weak_ptr<std::string>> string_refs;
+ std::ranges::copy(strings, std::back_inserter(string_refs));
+
+ std::default_random_engine gen;
+ std::shuffle(string_refs.begin(), string_refs.end(), gen);
+
+ for(unsigned i = 1;;++i)
+ {
+ std::print("round {} (", i);
+ for (auto& x : filter_bubble(string_refs))
+ std::print(" {}", x);
+ std::println(" ) {}", std::ranges::is_sorted(string_refs, std::owner_less<decltype(string_refs)::value_type>{}));
+ if (strings.empty())
+ break;
+ strings.erase(strings.begin() + std::rand() % strings.size());
+ }
+}