Some useful generic classes taking advantage of C++20 and coroutines.
Currently includes:
    template <typename T>
    class task
    {
    public:
        class promise_type
        {
        public:
            class awaiter
            {
            public:
                awaiter() = default;
                constexpr bool await_ready() const noexcept;
                constexpr void await_suspend(std::coroutine_handle<> h) noexcept;
                constexpr void await_resume() noexcept;
            };
            promise_type();
            awaiter initial_suspend() noexcept;
            std::suspend_always final_suspend() noexcept;
            void return_value(const T &value) noexcept;
            void return_value(T &&value) noexcept;
            task<T> get_return_object() noexcept;
            void unhandled_exception() noexcept;
            void rethrow_if_unhandled_exception() const;
            T &&result();
        };
        task() = default;
        task(std::coroutine_handle<promise_type> h) noexcept;
        T &&result();
        T &&await_resume();
        constexpr bool await_suspend(std::coroutine_handle<> h) noexcept;
        bool await_ready() const noexcept;
        bool done() const noexcept;
        template <typename Func, typename... Args>
        static task<T> run(const Func &func, const Args&... args);
        ~task() noexcept;
    };    template <typename T>
    class generator
    {
    public:
        class promise_type
        {
        public:
            promise_type() = default;
            generator<T> get_return_object() noexcept;
            std::suspend_always initial_suspend() const noexcept;
            std::suspend_always final_suspend() const noexcept;
            void unhandled_exception() noexcept;
            void rethrow_if_unhandled_exception() const;
            void return_void();
            std::suspend_always yield_value(const T &value) noexcept;
            std::suspend_always yield_value(T &&value) noexcept;
            T &get_value() noexcept;
        };
        class iterator
        {
        public:
            iterator() = default;
            iterator(std::coroutine_handle<promise_type> handle) noexcept;
            iterator(const iterator &) = default;
            iterator(iterator &&) = default;
            iterator &operator=(const iterator &) = default;
            iterator &operator=(iterator &&) = default;
            bool operator==(const std::default_sentinel_t &) const noexcept;
            bool operator!=(const std::default_sentinel_t &) const noexcept;
            iterator &operator++() noexcept;
            T &operator*() const noexcept;
            T *operator->() const noexcept;
        };
        generator() = default;
        generator(std::coroutine_handle<promise_type> h) noexcept;
        template <std::ranges::range Range>
        generator(const Range &range) noexcept;
        template <std::ranges::range Range>
        generator(Range &&range) noexcept;
        generator(generator &&other) noexcept;
        iterator begin() const noexcept;
        std::default_sentinel_t end() const noexcept;
        template <class Predicate>
        bool all(const Predicate &pred) const;
        template <class Predicate>
        bool any(const Predicate &pred) const;
        generator<T> append(const T &value);
        generator<T> append(T &&value);
        generator<std::vector<T>> chunk(std::size_t size);
        bool contains(const T &value) const;
        template <std::integral Integral = std::size_t>
        Integral count() const;
        generator<T> distinct();
        T element_at(std::size_t index) const;
        T first() const;
        T last() const;
        generator<T> prepend(const T &value);
        generator<T> prepend(T &&value);
        generator<T> prepend(generator<T> &&other);
        static generator<T> range(T from, T to);
        static generator<T> repeat(const T &value, std::size_t count);
        generator<T> reverse();
        template <class Selector>
        generator<std::invoke_result_t<Selector, const T &>> select(const Selector &selector);
        template <class Predicate>
        generator<T> where(const Predicate &pred);
        ~generator() noexcept;
    };    template <typename T, std::size_t NodeCapacity = 1024>
    class queue
    {
    public:
        queue();
        
        void push(const T &item);
        
        void push(T &&item);
        T pop();
        std::size_t size() const;
        bool empty() const;
    };
    template <typename T, std::size_t NodeCapacity>
    class bounded_queue
    {
    public:
        bounded_queue(std::size_t capacity);
        void push(const T &item);
        void push(T &&item);
        T pop();
        std::size_t size() const;
    };