Skip to content

Commit

Permalink
Support both <coroutine> and <experimental/coroutine>
Browse files Browse the repository at this point in the history
Starting with GCC 10.1, GCC/libstdc++ supports coroutines, but includes
them in their final location in <coroutine>.

This commit generalizes the location of the header, and the name of the
types (either in the std or std::experimental namespace), so that both
the current Clang/MSVC and the GCC approach can be supported.

This should also guarantee that both current and later Clang/MSVC
releases will be supported by the library.
  • Loading branch information
dutow committed Jul 19, 2020
1 parent 16ae7f1 commit 0b201f8
Show file tree
Hide file tree
Showing 43 changed files with 213 additions and 181 deletions.
6 changes: 3 additions & 3 deletions include/cppcoro/async_auto_reset_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef CPPCORO_ASYNC_AUTO_RESET_EVENT_HPP_INCLUDED
#define CPPCORO_ASYNC_AUTO_RESET_EVENT_HPP_INCLUDED

#include <experimental/coroutine>
#include <cppcoro/coroutine.hpp>
#include <atomic>
#include <cstdint>

Expand Down Expand Up @@ -80,7 +80,7 @@ namespace cppcoro
async_auto_reset_event_operation(const async_auto_reset_event_operation& other) noexcept;

bool await_ready() const noexcept { return m_event == nullptr; }
bool await_suspend(std::experimental::coroutine_handle<> awaiter) noexcept;
bool await_suspend(cppcoro::coroutine_handle<> awaiter) noexcept;
void await_resume() const noexcept {}

private:
Expand All @@ -89,7 +89,7 @@ namespace cppcoro

const async_auto_reset_event* m_event;
async_auto_reset_event_operation* m_next;
std::experimental::coroutine_handle<> m_awaiter;
cppcoro::coroutine_handle<> m_awaiter;
std::atomic<std::uint32_t> m_refCount;

};
Expand Down
52 changes: 26 additions & 26 deletions include/cppcoro/async_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <atomic>
#include <iterator>
#include <type_traits>
#include <experimental/coroutine>
#include <cppcoro/coroutine.hpp>
#include <functional>
#include <cassert>

Expand Down Expand Up @@ -45,7 +45,7 @@ namespace cppcoro
async_generator_promise_base(const async_generator_promise_base& other) = delete;
async_generator_promise_base& operator=(const async_generator_promise_base& other) = delete;

std::experimental::suspend_always initial_suspend() const noexcept
cppcoro::suspend_always initial_suspend() const noexcept
{
return {};
}
Expand Down Expand Up @@ -89,7 +89,7 @@ namespace cppcoro

std::exception_ptr m_exception;

std::experimental::coroutine_handle<> m_consumerCoroutine;
cppcoro::coroutine_handle<> m_consumerCoroutine;

protected:

Expand All @@ -100,7 +100,7 @@ namespace cppcoro
{
public:

async_generator_yield_operation(std::experimental::coroutine_handle<> consumer) noexcept
async_generator_yield_operation(cppcoro::coroutine_handle<> consumer) noexcept
: m_consumer(consumer)
{}

Expand All @@ -109,8 +109,8 @@ namespace cppcoro
return false;
}

std::experimental::coroutine_handle<>
await_suspend([[maybe_unused]] std::experimental::coroutine_handle<> producer) noexcept
cppcoro::coroutine_handle<>
await_suspend([[maybe_unused]] cppcoro::coroutine_handle<> producer) noexcept
{
return m_consumer;
}
Expand All @@ -119,7 +119,7 @@ namespace cppcoro

private:

std::experimental::coroutine_handle<> m_consumer;
cppcoro::coroutine_handle<> m_consumer;

};

Expand All @@ -145,7 +145,7 @@ namespace cppcoro

async_generator_advance_operation(
async_generator_promise_base& promise,
std::experimental::coroutine_handle<> producerCoroutine) noexcept
cppcoro::coroutine_handle<> producerCoroutine) noexcept
: m_promise(std::addressof(promise))
, m_producerCoroutine(producerCoroutine)
{
Expand All @@ -155,8 +155,8 @@ namespace cppcoro

bool await_ready() const noexcept { return false; }

std::experimental::coroutine_handle<>
await_suspend(std::experimental::coroutine_handle<> consumerCoroutine) noexcept
cppcoro::coroutine_handle<>
await_suspend(cppcoro::coroutine_handle<> consumerCoroutine) noexcept
{
m_promise->m_consumerCoroutine = consumerCoroutine;
return m_producerCoroutine;
Expand All @@ -165,7 +165,7 @@ namespace cppcoro
protected:

async_generator_promise_base* m_promise;
std::experimental::coroutine_handle<> m_producerCoroutine;
cppcoro::coroutine_handle<> m_producerCoroutine;

};

Expand Down Expand Up @@ -242,7 +242,7 @@ namespace cppcoro
class async_generator_iterator final
{
using promise_type = async_generator_promise<T>;
using handle_type = std::experimental::coroutine_handle<promise_type>;
using handle_type = cppcoro::coroutine_handle<promise_type>;

public:

Expand Down Expand Up @@ -307,7 +307,7 @@ namespace cppcoro
class async_generator_begin_operation final : public async_generator_advance_operation
{
using promise_type = async_generator_promise<T>;
using handle_type = std::experimental::coroutine_handle<promise_type>;
using handle_type = cppcoro::coroutine_handle<promise_type>;

public:

Expand Down Expand Up @@ -358,7 +358,7 @@ namespace cppcoro
{}

explicit async_generator(promise_type& promise) noexcept
: m_coroutine(std::experimental::coroutine_handle<promise_type>::from_promise(promise))
: m_coroutine(cppcoro::coroutine_handle<promise_type>::from_promise(promise))
{}

async_generator(async_generator&& other) noexcept
Expand Down Expand Up @@ -408,7 +408,7 @@ namespace cppcoro

private:

std::experimental::coroutine_handle<promise_type> m_coroutine;
cppcoro::coroutine_handle<promise_type> m_coroutine;

};

Expand Down Expand Up @@ -451,7 +451,7 @@ namespace cppcoro
async_generator_promise_base(const async_generator_promise_base& other) = delete;
async_generator_promise_base& operator=(const async_generator_promise_base& other) = delete;

std::experimental::suspend_always initial_suspend() const noexcept
cppcoro::suspend_always initial_suspend() const noexcept
{
return {};
}
Expand Down Expand Up @@ -556,7 +556,7 @@ namespace cppcoro

std::exception_ptr m_exception;

std::experimental::coroutine_handle<> m_consumerCoroutine;
cppcoro::coroutine_handle<> m_consumerCoroutine;

protected:

Expand All @@ -579,7 +579,7 @@ namespace cppcoro
return m_initialState == state::value_not_ready_consumer_suspended;
}

bool await_suspend(std::experimental::coroutine_handle<> producer) noexcept;
bool await_suspend(cppcoro::coroutine_handle<> producer) noexcept;

void await_resume() noexcept {}

Expand Down Expand Up @@ -625,7 +625,7 @@ namespace cppcoro
}

inline bool async_generator_yield_operation::await_suspend(
std::experimental::coroutine_handle<> producer) noexcept
cppcoro::coroutine_handle<> producer) noexcept
{
state currentState = m_initialState;
if (currentState == state::value_not_ready_consumer_active)
Expand Down Expand Up @@ -711,7 +711,7 @@ namespace cppcoro

async_generator_advance_operation(
async_generator_promise_base& promise,
std::experimental::coroutine_handle<> producerCoroutine) noexcept
cppcoro::coroutine_handle<> producerCoroutine) noexcept
: m_promise(std::addressof(promise))
, m_producerCoroutine(producerCoroutine)
{
Expand Down Expand Up @@ -740,7 +740,7 @@ namespace cppcoro
return m_initialState == state::value_ready_producer_suspended;
}

bool await_suspend(std::experimental::coroutine_handle<> consumerCoroutine) noexcept
bool await_suspend(cppcoro::coroutine_handle<> consumerCoroutine) noexcept
{
m_promise->m_consumerCoroutine = consumerCoroutine;

Expand Down Expand Up @@ -791,7 +791,7 @@ namespace cppcoro
protected:

async_generator_promise_base* m_promise;
std::experimental::coroutine_handle<> m_producerCoroutine;
cppcoro::coroutine_handle<> m_producerCoroutine;

private:

Expand Down Expand Up @@ -872,7 +872,7 @@ namespace cppcoro
class async_generator_iterator final
{
using promise_type = async_generator_promise<T>;
using handle_type = std::experimental::coroutine_handle<promise_type>;
using handle_type = cppcoro::coroutine_handle<promise_type>;

public:

Expand Down Expand Up @@ -937,7 +937,7 @@ namespace cppcoro
class async_generator_begin_operation final : public async_generator_advance_operation
{
using promise_type = async_generator_promise<T>;
using handle_type = std::experimental::coroutine_handle<promise_type>;
using handle_type = cppcoro::coroutine_handle<promise_type>;

public:

Expand Down Expand Up @@ -988,7 +988,7 @@ namespace cppcoro
{}

explicit async_generator(promise_type& promise) noexcept
: m_coroutine(std::experimental::coroutine_handle<promise_type>::from_promise(promise))
: m_coroutine(cppcoro::coroutine_handle<promise_type>::from_promise(promise))
{}

async_generator(async_generator&& other) noexcept
Expand Down Expand Up @@ -1041,7 +1041,7 @@ namespace cppcoro

private:

std::experimental::coroutine_handle<promise_type> m_coroutine;
cppcoro::coroutine_handle<promise_type> m_coroutine;

};

Expand Down
6 changes: 3 additions & 3 deletions include/cppcoro/async_manual_reset_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef CPPCORO_ASYNC_MANUAL_RESET_EVENT_HPP_INCLUDED
#define CPPCORO_ASYNC_MANUAL_RESET_EVENT_HPP_INCLUDED

#include <experimental/coroutine>
#include <cppcoro/coroutine.hpp>
#include <atomic>
#include <cstdint>

Expand Down Expand Up @@ -87,7 +87,7 @@ namespace cppcoro
explicit async_manual_reset_event_operation(const async_manual_reset_event& event) noexcept;

bool await_ready() const noexcept;
bool await_suspend(std::experimental::coroutine_handle<> awaiter) noexcept;
bool await_suspend(cppcoro::coroutine_handle<> awaiter) noexcept;
void await_resume() const noexcept {}

private:
Expand All @@ -96,7 +96,7 @@ namespace cppcoro

const async_manual_reset_event& m_event;
async_manual_reset_event_operation* m_next;
std::experimental::coroutine_handle<> m_awaiter;
cppcoro::coroutine_handle<> m_awaiter;

};
}
Expand Down
6 changes: 3 additions & 3 deletions include/cppcoro/async_mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef CPPCORO_ASYNC_MUTEX_HPP_INCLUDED
#define CPPCORO_ASYNC_MUTEX_HPP_INCLUDED

#include <experimental/coroutine>
#include <cppcoro/coroutine.hpp>
#include <atomic>
#include <cstdint>
#include <mutex> // for std::adopt_lock_t
Expand Down Expand Up @@ -166,7 +166,7 @@ namespace cppcoro
{}

bool await_ready() const noexcept { return false; }
bool await_suspend(std::experimental::coroutine_handle<> awaiter) noexcept;
bool await_suspend(cppcoro::coroutine_handle<> awaiter) noexcept;
void await_resume() const noexcept {}

protected:
Expand All @@ -178,7 +178,7 @@ namespace cppcoro
private:

async_mutex_lock_operation* m_next;
std::experimental::coroutine_handle<> m_awaiter;
cppcoro::coroutine_handle<> m_awaiter;

};

Expand Down
10 changes: 5 additions & 5 deletions include/cppcoro/async_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <cppcoro/on_scope_exit.hpp>

#include <atomic>
#include <experimental/coroutine>
#include <cppcoro/coroutine.hpp>
#include <type_traits>
#include <cassert>

Expand Down Expand Up @@ -52,7 +52,7 @@ namespace cppcoro
return m_scope->m_count.load(std::memory_order_acquire) == 0;
}

bool await_suspend(std::experimental::coroutine_handle<> continuation) noexcept
bool await_suspend(cppcoro::coroutine_handle<> continuation) noexcept
{
m_scope->m_continuation = continuation;
return m_scope->m_count.fetch_sub(1u, std::memory_order_acq_rel) > 1u;
Expand Down Expand Up @@ -85,16 +85,16 @@ namespace cppcoro
{
struct promise_type
{
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() { return {}; }
cppcoro::suspend_never initial_suspend() { return {}; }
cppcoro::suspend_never final_suspend() { return {}; }
void unhandled_exception() { std::terminate(); }
oneway_task get_return_object() { return {}; }
void return_void() {}
};
};

std::atomic<size_t> m_count;
std::experimental::coroutine_handle<> m_continuation;
cppcoro::coroutine_handle<> m_continuation;

};
}
Expand Down
32 changes: 32 additions & 0 deletions include/cppcoro/coroutine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef CPPCORO_COROUTINE_HPP_INCLUDED
#define CPPCORO_COROUTINE_HPP_INCLUDED

#if __has_include(<coroutine>)

#include <coroutine>

namespace cppcoro {
template<typename Promise=void>
using coroutine_handle = std::coroutine_handle<Promise>;

using suspend_always = std::suspend_always;
using suspend_never = std::suspend_never;
}

#elif __has_include(<experimental/coroutine>)

#include <experimental/coroutine>

namespace cppcoro {
template<typename Promise=void>
using coroutine_handle = std::experimental::coroutine_handle<Promise>;

using suspend_always = std::experimental::suspend_always;
using suspend_never = std::experimental::suspend_never;
}

#else
#error Cppcoro requires a C++20 compiler with coroutine support
#endif

#endif

0 comments on commit 0b201f8

Please sign in to comment.