examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

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:
Asrc/filter-bubble.cpp | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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()); + } +}