Created
October 26, 2023 13:28
-
-
Save CoffeeVampir3/e5ea60505f2d5c39cc7e5ce84c449d90 to your computer and use it in GitHub Desktop.
GeneratorEx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <coroutine> | |
| namespace CoTools | |
| { | |
| template<typename T> class TWeakPromise; | |
| template<typename T> | |
| struct [[nodiscard]] TWeakGenerator | |
| { | |
| using promise_type = TWeakPromise<T>; | |
| friend promise_type; | |
| explicit TWeakGenerator(std::coroutine_handle<promise_type> Handle) noexcept : Handle(Handle) { } | |
| ~TWeakGenerator() | |
| { | |
| if (Handle) | |
| Handle.destroy(); | |
| } | |
| TWeakGenerator(const TWeakGenerator&) = delete; | |
| TWeakGenerator& operator=(const TWeakGenerator&) = delete; | |
| TWeakGenerator& operator=(TWeakGenerator&&) = delete; | |
| explicit operator bool() const noexcept { | |
| Handle(); | |
| return Handle && !Handle.done(); | |
| } | |
| T& operator()() const | |
| { | |
| checkf(Handle && Handle.promise().PromiseValue, | |
| TEXT("Attempted to use a TWeakGenerator but the handle is not valid.")); | |
| return *static_cast<T*>(Handle.promise().PromiseValue); | |
| } | |
| private: | |
| std::coroutine_handle<promise_type> Handle; | |
| }; | |
| class [[nodiscard]] FWeakPromise | |
| { | |
| public: | |
| FWeakPromise() = default; | |
| UE_NONCOPYABLE(FWeakPromise); | |
| std::suspend_never initial_suspend() noexcept { return {}; } | |
| std::suspend_always final_suspend() noexcept { return {}; } | |
| void return_void() noexcept { PromiseValue = nullptr; } | |
| void unhandled_exception(); | |
| protected: | |
| void* PromiseValue = nullptr; | |
| }; | |
| template<typename T> | |
| class [[nodiscard]] TWeakPromise : public FWeakPromise | |
| { | |
| friend TWeakGenerator<T>; | |
| using HandleType = std::coroutine_handle<TWeakPromise>; | |
| public: | |
| TWeakGenerator<T> get_return_object() noexcept | |
| { | |
| return TWeakGenerator<T>(HandleType::from_promise(*this)); | |
| } | |
| std::suspend_always yield_value(std::remove_reference_t<T>& Value) noexcept | |
| { | |
| PromiseValue = std::addressof(Value); | |
| return {}; | |
| } | |
| std::suspend_always yield_value(std::remove_reference_t<T>&& Value) noexcept | |
| { | |
| PromiseValue = std::addressof(Value); | |
| return {}; | |
| } | |
| }; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <coroutine> | |
| namespace CoTools | |
| { | |
| template<typename T> | |
| struct [[nodiscard]] TValueGenerator { | |
| struct promise_type; | |
| using HandleType = std::coroutine_handle<promise_type>; | |
| struct promise_type { | |
| T PromiseValue; | |
| TValueGenerator get_return_object() { | |
| return TValueGenerator(HandleType::from_promise(*this)); | |
| } | |
| std::suspend_never initial_suspend() { return {}; } | |
| std::suspend_always final_suspend() noexcept { return {}; } | |
| void unhandled_exception() {} | |
| template<std::convertible_to<T> From> | |
| std::suspend_always yield_value(From &&from) { | |
| PromiseValue = std::forward<From>(from); | |
| return {}; | |
| } | |
| void return_void() {} | |
| }; | |
| HandleType GeneratorHandle; | |
| TValueGenerator(HandleType Handle) : GeneratorHandle(Handle) {} | |
| TValueGenerator(const TValueGenerator&) = delete; | |
| ~TValueGenerator() {GeneratorHandle.destroy();} | |
| explicit operator bool() const noexcept { | |
| GeneratorHandle(); | |
| return !GeneratorHandle.done(); | |
| } | |
| T operator()() const { | |
| return std::move(GeneratorHandle.promise().PromiseValue); | |
| } | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment