Skip to content

Commit

Permalink
cpp 20
Browse files Browse the repository at this point in the history
  • Loading branch information
ladnir committed Apr 29, 2024
1 parent cfd155c commit 8d02547
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 18 deletions.
4 changes: 2 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"MACORO_FETCH_AUTO": "ON",
"MACORO_CPP_20": true,
"MACORO_CPP_VER": "20",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
},
"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }
Expand All @@ -51,7 +51,7 @@
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"MACORO_FETCH_AUTO": "ON",
"MACORO_CPP_20": false,
"MACORO_CPP_VER": "20",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
},
"vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } }
Expand Down
8 changes: 6 additions & 2 deletions cmake/macoroFindDeps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ if((MACORO_FETCH_AUTO OR MACORO_FETCH_OPTIONAL) AND MACORO_BUILD)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/../thirdparty/getOptionalLite.cmake")
endif()
FIND_OPTIONAL(REQUIRED)

if(MACORO_OPTIONAL_LITE)
FIND_OPTIONAL(REQUIRED)
endif()

## variant-lite
###########################################################################
Expand All @@ -58,7 +60,9 @@ if((MACORO_FETCH_AUTO OR MACORO_FETCH_OPTIONAL) AND MACORO_BUILD)

include("${CMAKE_CURRENT_LIST_DIR}/../thirdparty/getVariantLite.cmake")
endif()
FIND_VARIANT(REQUIRED)
if(MACORO_VARIANT_LITE)
FIND_VARIANT(REQUIRED)
endif()



Expand Down
1 change: 0 additions & 1 deletion frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ set(SRC


add_executable(macoroFrontend ${SRC})

target_link_libraries(macoroFrontend macoroTests macoro)


Expand Down
2 changes: 1 addition & 1 deletion macoro/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ endif()
if(MACORO_ASAN)
message("Warning: ASAN is enabled for macoro.")
if(MSVC)
target_compile_options(macoro PRIVATE
target_compile_options(macoro PUBLIC
"/fsanitize=address")
else()
target_compile_options(macoro PRIVATE
Expand Down
4 changes: 4 additions & 0 deletions macoro/detail/when_all_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include <cassert>
#include <utility>

#ifdef MACORO_CPP_20
#define MACORO_CPP_20_WHEN_ALL 1
#endif

namespace macoro
{
namespace detail
Expand Down
23 changes: 12 additions & 11 deletions macoro/sync_wait.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
namespace macoro
{

#ifdef MACORO_CPP_20
#define MACORO_MAKE_BLOCKING_20 1
#endif
namespace detail
{
template<typename T>
Expand All @@ -20,14 +23,14 @@ namespace macoro
{
struct final_awaiter
{
bool await_ready() { return false; }
bool await_ready() noexcept { return false; }
#ifdef MACORO_CPP_20
template<typename P>
void await_suspend(std::coroutine_handle<P> h) { h.promise().set(); }
void await_suspend(std::coroutine_handle<P> h) noexcept { h.promise().set(); }
#endif
template<typename P>
void await_suspend(coroutine_handle<P> h) { h.promise().set(); }
void await_resume() {}
void await_suspend(coroutine_handle<P> h) noexcept { h.promise().set(); }
void await_resume() noexcept {}
};

std::exception_ptr exception;
Expand Down Expand Up @@ -142,15 +145,13 @@ namespace macoro
template<
typename Awaitable,
typename ResultType = typename awaitable_traits<Awaitable&&>::await_result>
enable_if_t<!std::is_void<ResultType>::value,
enable_if_t<!std::is_void<ResultType>::value,
blocking_task<ResultType>
>
>
make_blocking_task(Awaitable&& awaitable)
{
#if MACORO_MAKE_BLOCKING_20
auto promise = co_await typename blocking_promise<ResultType>::get_promise{};
auto awaiter = promise->yield_value(co_await std::forward<Awaitable>(awaitable));
co_await awaiter;
co_return co_await static_cast<Awaitable&&>(awaitable);
#else
MC_BEGIN(blocking_task<ResultType>, &awaitable);
MC_RETURN_AWAIT(static_cast<Awaitable&&>(awaitable));
Expand All @@ -162,9 +163,9 @@ namespace macoro
template<
typename Awaitable,
typename ResultType = typename awaitable_traits<Awaitable&&>::await_result>
enable_if_t<std::is_void<ResultType>::value,
enable_if_t<std::is_void<ResultType>::value,
blocking_task<ResultType>
>
>
make_blocking_task(Awaitable&& awaitable)
{
#if MACORO_MAKE_BLOCKING_20
Expand Down
212 changes: 211 additions & 1 deletion tests/when_all_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,214 @@ namespace macoro
}

}
}


#ifdef MACORO_CPP_20
#define MACORO_MAKE_blocking2_20 1
#endif


namespace detail
{
struct blocking2_task;


struct blocking2_promise
{
int* mVal = nullptr;

blocking2_task get_return_object() noexcept;

using reference_type = int&;
void return_value(reference_type v) noexcept
{
mVal = std::addressof(v);
}

reference_type value()
{
if (this->exception)
std::rethrow_exception(this->exception);
return static_cast<reference_type>(*mVal);
}

struct final_awaiter
{
final_awaiter() noexcept{};
final_awaiter(const final_awaiter&) noexcept {};
final_awaiter(final_awaiter&&) noexcept {};

bool await_ready() noexcept { return false; }
#ifdef MACORO_CPP_20
template<typename P>
void await_suspend(std::coroutine_handle<P> h) noexcept { h.promise().set(); }
#endif
template<typename P>
void await_suspend(coroutine_handle<P> h) noexcept { h.promise().set(); }
void await_resume() noexcept {}
};

std::exception_ptr exception;
std::mutex mutex;
std::condition_variable cv;
bool is_set = false;

void wait()
{
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [this] { return is_set; });
}

void set()
{
assert(is_set == false);
std::lock_guard<std::mutex> lock(this->mutex);
this->is_set = true;
this->cv.notify_all();
}


suspend_always initial_suspend() noexcept { return{}; }

final_awaiter final_suspend() noexcept(true) {
return { };
}

void unhandled_exception() noexcept
{
exception = std::current_exception();
}
};

//static_assert(std::is_nothrow_invocable<blocking2_promise::final_suspend, blocking2_promise&>::value, "");
struct blocking2_task
{
using promise_type = blocking2_promise;
coroutine_handle<promise_type> handle;
blocking2_task(coroutine_handle<promise_type> h)
: handle(h)
{}

blocking2_task() = delete;
blocking2_task(blocking2_task&& h) noexcept :handle(std::exchange(h.handle, std::nullptr_t{})) {}
blocking2_task& operator=(blocking2_task&& h) noexcept { handle = std::exchange(h.handle, std::nullptr_t{}); }

~blocking2_task()
{
if (handle)
handle.destroy();
}

void start()
{
handle.resume();
}

decltype(auto) get()
{
handle.promise().wait();
return handle.promise().value();
}
};

blocking2_task blocking2_promise::get_return_object() noexcept
{
return { coroutine_handle<blocking2_promise>::from_promise(*this, coroutine_handle_type::std) };
}


// template<
// typename Awaitable
// >
// blocking2_task
// make_blocking2_task(Awaitable&& awaitable)
// {
//#if MACORO_MAKE_blocking2_20
// //auto promise = co_await typename blocking2_promise<ResultType>::get_promise;
// //auto awaiter = promise->yield_value(co_await std::forward<Awaitable>(awaitable));
// //co_await awaiter;
// co_return co_await static_cast<Awaitable&&>(awaitable);
//#else
// MC_BEGIN(blocking2_task<ResultType>, &awaitable);
// MC_RETURN_AWAIT(static_cast<Awaitable&&>(awaitable));
// MC_END();
//
//#endif
// }

// template<
// typename Awaitable,
// typename ResultType = typename awaitable_traits<Awaitable&&>::await_result>
// enable_if_t<std::is_void<ResultType>::value,
// blocking2_task<ResultType>
// >
// make_blocking2_task(Awaitable&& awaitable)
// {
//#if MACORO_MAKE_blocking2_20
// co_await std::forward<Awaitable>(awaitable);
//#else
// MC_BEGIN(blocking2_task<ResultType>, &awaitable);
// MC_AWAIT(static_cast<Awaitable&&>(awaitable));
// MC_END();
//#endif
// }
}


//template<typename Awaitable>
//typename awaitable_traits<Awaitable&&>::await_result
// sync_wait2(Awaitable&& awaitable)
//{
// auto task = detail::make_blocking2_task<Awaitable&&>(std::forward<Awaitable>(awaitable));
// task.start();
// return task.get();
//}


//struct sync_wait2_t
//{
//};

//inline sync_wait2_t sync_wait2()
//{
// return {};
//}


//template<typename awaitable>
//decltype(auto) operator|(awaitable&& a, sync_wait2_t)
//{
// return sync_wait2(std::forward<awaitable>(a));
//}


void when_all_basic2_tests()
{

auto f = []() -> task<int> {
MC_BEGIN(task<int>);
MC_RETURN(42);
MC_END();
};

auto g = []() -> task<bool> {
MC_BEGIN(task<bool>);
MC_RETURN(true);
MC_END();
};

using F = decltype(f());
using Awaitable = F;
using ResultType = int;

auto task = [&]() -> detail::blocking2_task {
auto i = co_await f();
co_return i;
}();
task.start();
auto i = task.get();

}

}

0 comments on commit 8d02547

Please sign in to comment.