[#design:concepts]
== Concepts

This library has two fundamental concepts:

 - <<awaitable,awaitable>>
 - coroutine

An <<awaitable, awaitable>> is an expression that can be used with `co_await`
from within a coroutine, e.g.:

[source,cpp]
----
co_await delay(50ms);
----

However, a coroutine promise can define an `await_transform`,
i.e. what is actually valid to use with `co_await` expression depends on the coroutine.

Thus, we should redefine what an <<awaitable, awaitable>> is:
An *awaitable* is a type that can be `co_await`-ed from within a coroutine,
which promise does not define `await_transform`.


A `pseudo-keyword` is a type that can be used in a coroutines that is adds special
functionality for it due to its promise `await_transform`.

All the verbs in the <<this_coro, this_coro>> namespace are such pseudo-keywords.

[source,cpp]
----
auto exec = co_await this_coro::executor;
----

NOTE: This library exposes a set of `enable_*` base classes for promises,
to make the creation of custom coroutines easy.
This includes the <<enable_awaitables, enable_awaitables>>, which provides an `await_transform`
that just forward <<awaitable, awaitables>>.

A coroutine in the context of this documentation refers
to an asynchronous coroutine, i.e. synchronous coroutines like
link:https://en.cppreference.com/w/cpp/coroutine/generator[std::generator]
are not considered.

All coroutines except <<main, main>> are also actual <<awaitable, awaitables>>.

