Skip to content

Commit 57b5294

Browse files
committed
change __connect_awaitable to await the awaitable with no dynamic allocations
1 parent d8ef5fe commit 57b5294

5 files changed

Lines changed: 274 additions & 117 deletions

File tree

examples/hello_coro.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,25 @@
1919
#include <stdexec/execution.hpp>
2020

2121
#if !STDEXEC_NO_STDCPP_COROUTINES() && !STDEXEC_NVHPC()
22-
# include <exec/task.hpp>
2322

2423
using namespace stdexec;
2524

2625
template <sender S1, sender S2>
27-
auto async_answer(S1 s1, S2 s2) -> exec::task<int>
26+
auto async_answer(S1 s1, S2 s2) -> stdexec::task<int>
2827
{
2928
// Senders are implicitly awaitable (in this coroutine type):
3029
co_await static_cast<S2&&>(s2);
3130
co_return co_await static_cast<S1&&>(s1);
3231
}
3332

3433
template <sender S1, sender S2>
35-
auto async_answer2(S1 s1, S2 s2) -> exec::task<std::optional<int>>
34+
auto async_answer2(S1 s1, S2 s2) -> stdexec::task<std::optional<int>>
3635
{
3736
co_return co_await stopped_as_optional(async_answer(s1, s2));
3837
}
3938

4039
// tasks have an associated stop token
41-
auto async_stop_token() -> exec::task<std::optional<stdexec::inplace_stop_token>>
40+
auto async_stop_token() -> stdexec::task<std::optional<stdexec::inplace_stop_token>>
4241
{
4342
co_return co_await stopped_as_optional(get_stop_token());
4443
}

include/stdexec/__detail/__awaitable.hpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
#pragma once
1717

18+
#include "../functional.hpp"
1819
#include "__concepts.hpp"
1920
#include "__config.hpp"
2021
#include "__meta.hpp"
@@ -39,20 +40,20 @@ namespace STDEXEC
3940
__promise.await_transform(static_cast<_Awaitable &&>(__awaitable));
4041
};
4142

42-
template <class _Awaitable>
43-
constexpr auto __get_awaitable(_Awaitable &&__awaitable, __ignore = {}) -> decltype(auto)
44-
{
45-
return static_cast<_Awaitable &&>(__awaitable);
46-
}
43+
inline constexpr auto __get_awaitable = __first_callable{
44+
[]<class _Promise, __has_await_transform<_Promise> _Awaitable>(_Awaitable &&__awaitable,
45+
_Promise &__promise)
46+
-> decltype(auto)
47+
{ return __promise.await_transform(static_cast<_Awaitable &&>(__awaitable)); },
48+
[]<class _Awaitable>(_Awaitable &&__awaitable, __ignore = {}) -> decltype(auto)
49+
{ return static_cast<_Awaitable &&>(__awaitable); }};
4750

48-
template <class _Promise, __has_await_transform<_Promise> _Awaitable>
49-
constexpr auto __get_awaitable(_Awaitable &&__awaitable, _Promise &__promise) -> decltype(auto)
50-
{
51-
return __promise.await_transform(static_cast<_Awaitable &&>(__awaitable));
52-
}
51+
template <class _Awaitable, class _Promise>
52+
using __awaitable_of_t = decltype(STDEXEC::__get_awaitable(__declval<_Awaitable>(),
53+
__declval<_Promise &>()));
5354

54-
template <class _Awaitable>
55-
constexpr auto __get_awaiter(_Awaitable &&__awaitable) -> decltype(auto)
55+
inline constexpr auto __get_awaiter =
56+
[]<class _Awaitable>(_Awaitable &&__awaitable) -> decltype(auto)
5657
{
5758
if constexpr (requires { __declval<_Awaitable>().operator co_await(); })
5859
{
@@ -66,7 +67,10 @@ namespace STDEXEC
6667
{
6768
return static_cast<_Awaitable &&>(__awaitable);
6869
}
69-
}
70+
};
71+
72+
template <class _Awaitable>
73+
using __awaiter_of_t = decltype(STDEXEC::__get_awaiter(__declval<_Awaitable>()));
7074

7175
template <class _Awaitable, class... _Promise>
7276
concept __awaitable = requires(_Awaitable &&__awaitable, _Promise &...__promise) {

include/stdexec/__detail/__config.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,15 @@ namespace STDEXEC::__std
401401
# define STDEXEC_PRAGMA_IGNORE_MSVC(...)
402402
#endif
403403

404+
#if STDEXEC_MSVC()
405+
# define STDEXEC_PRAGMA_OPTIMIZE_BEGIN() STDEXEC_PRAGMA(optimize("", on))
406+
# define STDEXEC_PRAGMA_OPTIMIZE_END() STDEXEC_PRAGMA(optimize("", off))
407+
#else
408+
# define STDEXEC_PRAGMA_OPTIMIZE_BEGIN() STDEXEC_PRAGMA(GCC push_options) \
409+
STDEXEC_PRAGMA(GCC optimize("O3"))
410+
# define STDEXEC_PRAGMA_OPTIMIZE_END() STDEXEC_PRAGMA(GCC pop_options)
411+
#endif
412+
404413
#if !STDEXEC_MSVC() && defined(__has_builtin)
405414
# define STDEXEC_HAS_BUILTIN __has_builtin
406415
#else

0 commit comments

Comments
 (0)