From eba3d9e1f8a7641f0901548e0dddfbce0b481f02 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Fri, 2 Jul 2021 15:19:42 -0400 Subject: [PATCH] Created a general Generator type for coroutines --- Generator.hpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Generator.hpp diff --git a/Generator.hpp b/Generator.hpp new file mode 100644 index 0000000..52d974b --- /dev/null +++ b/Generator.hpp @@ -0,0 +1,96 @@ +//myClasses/Generator.hpp +//Matthew Ellison +// Created: 07-02-21 +//Modified: 07-02-21 +//This file contains a simple generator for coroutines +/* + Copyright (C) 2021 Matthew Ellison + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ +#ifndef MEE_GENERATOR_HPP +#define MEE_GENERATOR_HPP + + +#include +#include + + +namespace mee{ + + +template +class Generator{ +public: + struct promise_type{ + private: + T currentValue; + public: + promise_type() = default; + ~promise_type() = default; + std::suspend_always initial_suspend(){ + return {}; + } + std::suspend_always final_suspend() noexcept{ + return {}; + } + Generator get_return_object(){ + return Generator{std::coroutine_handle::from_promise(*this)}; + } + std::suspend_always yield_value(T value){ + currentValue = value; + return {}; + } + void return_void(){ + } + void unhandled_exception(){ + //If something goes really wrong rethrow the exception + std::rethrow_exception(std::current_exception()); + } + //Don't allow any use of co_await + template + std::suspend_never await_transform(U&& value) = delete; + + T current(){ + return currentValue; + } + }; + Generator(std::coroutine_handle handle) : coroutine(handle){ + } + Generator(const Generator&) = delete; //Don't allow any copy connstructors + Generator(Generator&& other) : coroutine(other.coroutine){ + other.coroutine = nullptr; + } + ~Generator(){ + if(coroutine){ + coroutine.destroy(); + } + } + T next(){ + coroutine.resume(); + return coroutine.promise().current(); + } + T current(){ + return coroutine.promise().current(); + } + Generator& operator=(const Generator&) = delete; //Don't allow any = operations +private: + std::coroutine_handle coroutine; +}; + + +} + + +#endif //MEE_GENERATOR_HPP