#ifndef _ASYNCO_ #define _ASYNCO_ #include "engine.hpp" #include using namespace std; #if __cplusplus >= 202002L #include #include #include #endif namespace marcelb { namespace asynco { /** * Run the function asynchronously */ template auto async_(F&& f, Args&&... args) -> future::type> { using return_type = typename result_of::type; future res = _asynco_engine.io_context.post(boost::asio::use_future(bind(forward(f), forward(args)...))); return res; } #if __cplusplus >= 202002L /** * Run the coroutine */ template std::future async_(boost::asio::awaitable _coroutine) { std::promise promise; auto future = promise.get_future(); co_spawn(_asynco_engine.io_context, [_coroutine = std::move(_coroutine), promise = std::move(promise)]() mutable -> boost::asio::awaitable { try { if constexpr (!std::is_void_v) { T result = co_await std::move(_coroutine); promise.set_value(std::move(result)); } else { co_await std::move(_coroutine); promise.set_value(); // Za void ne postavljamo rezultat } } catch (...) { promise.set_exception(std::current_exception()); // Postavljamo izuzetak } }, boost::asio::detached); return future; } #endif /** * Block until the asynchronous call completes */ template T await_(future& r) { return r.get(); } /** * Block until the asynchronous call completes */ template T await_(future&& r) { return move(r).get(); } /** * Run the function asynchronously an block until completes */ template auto await_(F&& f, Args&&... args) -> typename result_of::type { return await_( async_(f, args...) ); } #if __cplusplus >= 202002L /** * Run the coruotine and wait */ template T await_(boost::asio::awaitable _coroutine) { return await_( async_( move(_coroutine) )); } #endif /** * Block until the asynchronous call completes or time expired */ // template // T await_(future& r, uint64_t time) { // if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) { // throw runtime_error("Asynchronous execution timed out"); // } // return r.get(); // } /** * Block until the asynchronous call completes or time expired */ // template // T await_(future&& r, uint64_t time) { // if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) { // throw runtime_error("Asynchronous execution timed out"); // } // return move(r).get(); // } } } #endif