Skip to content

Commit ff7ab25

Browse files
authored
C++20 coroutine support (#748)
1 parent fa6bb7a commit ff7ab25

File tree

8 files changed

+65
-154
lines changed

8 files changed

+65
-154
lines changed

scratch/scratch.vcxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129
<IntrinsicFunctions>true</IntrinsicFunctions>
130130
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
131131
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
132-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
132+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
133133
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
134134
</ClCompile>
135135
<Link>
@@ -151,7 +151,7 @@
151151
<Optimization>Disabled</Optimization>
152152
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
153153
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
154-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
154+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
155155
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
156156
</ClCompile>
157157
<Link>
@@ -171,7 +171,7 @@
171171
<Optimization>Disabled</Optimization>
172172
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
173173
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
174-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
174+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
175175
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
176176
</ClCompile>
177177
<Link>
@@ -191,7 +191,7 @@
191191
<Optimization>Disabled</Optimization>
192192
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
193193
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
194-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
194+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
195195
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
196196
</ClCompile>
197197
<Link>
@@ -211,7 +211,7 @@
211211
<Optimization>Disabled</Optimization>
212212
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
213213
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
214-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
214+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
215215
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
216216
</ClCompile>
217217
<Link>
@@ -233,7 +233,7 @@
233233
<IntrinsicFunctions>true</IntrinsicFunctions>
234234
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
235235
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
236-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
236+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
237237
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
238238
</ClCompile>
239239
<Link>
@@ -257,7 +257,7 @@
257257
<IntrinsicFunctions>true</IntrinsicFunctions>
258258
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
259259
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
260-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
260+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
261261
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
262262
</ClCompile>
263263
<Link>
@@ -281,7 +281,7 @@
281281
<IntrinsicFunctions>true</IntrinsicFunctions>
282282
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..\..\..\library</AdditionalIncludeDirectories>
283283
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
284-
<AdditionalOptions>/await %(AdditionalOptions)</AdditionalOptions>
284+
<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
285285
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
286286
</ClCompile>
287287
<Link>

strings/base_coroutine_foundation.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ namespace winrt::impl
100100

101101
struct disconnect_aware_handler
102102
{
103-
disconnect_aware_handler(std::experimental::coroutine_handle<> handle) noexcept
103+
disconnect_aware_handler(coroutine_handle<> handle) noexcept
104104
: m_handle(handle) { }
105105

106106
disconnect_aware_handler(disconnect_aware_handler&& other) noexcept
@@ -119,7 +119,7 @@ namespace winrt::impl
119119

120120
private:
121121
resume_apartment_context m_context;
122-
std::experimental::coroutine_handle<> m_handle;
122+
coroutine_handle<> m_handle;
123123

124124
void Complete()
125125
{
@@ -148,7 +148,7 @@ namespace winrt::impl
148148
return false;
149149
}
150150

151-
void await_suspend(std::experimental::coroutine_handle<> handle)
151+
void await_suspend(coroutine_handle<> handle)
152152
{
153153
auto extend_lifetime = async;
154154
async.Completed([this, handler = disconnect_aware_handler{ handle }](auto&&, auto operation_status) mutable
@@ -282,7 +282,7 @@ namespace winrt::impl
282282
return true;
283283
}
284284

285-
void await_suspend(std::experimental::coroutine_handle<>) const noexcept
285+
void await_suspend(coroutine_handle<>) const noexcept
286286
{
287287
}
288288

@@ -324,7 +324,7 @@ namespace winrt::impl
324324
return true;
325325
}
326326

327-
void await_suspend(std::experimental::coroutine_handle<>) const noexcept
327+
void await_suspend(coroutine_handle<>) const noexcept
328328
{
329329
}
330330

@@ -355,7 +355,7 @@ namespace winrt::impl
355355
if (remaining == 0)
356356
{
357357
std::atomic_thread_fence(std::memory_order_acquire);
358-
std::experimental::coroutine_handle<Derived>::from_promise(*static_cast<Derived*>(this)).destroy();
358+
coroutine_handle<Derived>::from_promise(*static_cast<Derived*>(this)).destroy();
359359
}
360360

361361
return remaining;
@@ -496,7 +496,7 @@ namespace winrt::impl
496496
}
497497
}
498498

499-
std::experimental::suspend_never initial_suspend() const noexcept
499+
suspend_never initial_suspend() const noexcept
500500
{
501501
return{};
502502
}
@@ -514,7 +514,7 @@ namespace winrt::impl
514514
{
515515
}
516516

517-
bool await_suspend(std::experimental::coroutine_handle<>) const noexcept
517+
bool await_suspend(coroutine_handle<>) const noexcept
518518
{
519519
promise->set_completed();
520520
uint32_t const remaining = promise->subtract_reference();
@@ -629,7 +629,11 @@ namespace winrt::impl
629629
};
630630
}
631631

632-
WINRT_EXPORT namespace std::experimental
632+
#ifdef __cpp_lib_coroutine
633+
namespace std
634+
#else
635+
namespace std::experimental
636+
#endif
633637
{
634638
template <typename... Args>
635639
struct coroutine_traits<winrt::Windows::Foundation::IAsyncAction, Args...>

strings/base_coroutine_system.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ WINRT_EXPORT namespace winrt
2323
return m_queued;
2424
}
2525

26-
bool await_suspend(std::experimental::coroutine_handle<> handle)
26+
bool await_suspend(impl::coroutine_handle<> handle)
2727
{
2828
return m_dispatcher.TryEnqueue(m_priority, [handle, this]
2929
{

strings/base_coroutine_system_winui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ WINRT_EXPORT namespace winrt
2323
return m_queued;
2424
}
2525

26-
bool await_suspend(std::experimental::coroutine_handle<> handle)
26+
bool await_suspend(impl::coroutine_handle<> handle)
2727
{
2828
return m_dispatcher.TryEnqueue(m_priority, [handle, this]
2929
{

strings/base_coroutine_threadpool.h

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ namespace winrt::impl
1111

1212
inline void __stdcall resume_background_callback(void*, void* context) noexcept
1313
{
14-
std::experimental::coroutine_handle<>::from_address(context)();
14+
coroutine_handle<>::from_address(context)();
1515
};
1616

17-
inline auto resume_background(std::experimental::coroutine_handle<> handle)
17+
inline auto resume_background(coroutine_handle<> handle)
1818
{
1919
submit_threadpool_callback(resume_background_callback, handle.address());
2020
}
@@ -56,26 +56,26 @@ namespace winrt::impl
5656

5757
inline int32_t __stdcall resume_apartment_callback(com_callback_args* args) noexcept
5858
{
59-
std::experimental::coroutine_handle<>::from_address(args->data)();
59+
coroutine_handle<>::from_address(args->data)();
6060
return 0;
6161
};
6262

63-
inline void resume_apartment_sync(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle)
63+
inline void resume_apartment_sync(com_ptr<IContextCallback> const& context, coroutine_handle<> handle)
6464
{
6565
com_callback_args args{};
6666
args.data = handle.address();
6767

6868
check_hresult(context->ContextCallback(resume_apartment_callback, &args, guid_of<ICallbackWithNoReentrancyToApplicationSTA>(), 5, nullptr));
6969
}
7070

71-
inline void resume_apartment_on_threadpool(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle)
71+
inline void resume_apartment_on_threadpool(com_ptr<IContextCallback> const& context, coroutine_handle<> handle)
7272
{
7373
struct threadpool_resume
7474
{
75-
threadpool_resume(com_ptr<IContextCallback> const& context, std::experimental::coroutine_handle<> handle) :
75+
threadpool_resume(com_ptr<IContextCallback> const& context, coroutine_handle<> handle) :
7676
m_context(context), m_handle(handle) { }
7777
com_ptr<IContextCallback> m_context;
78-
std::experimental::coroutine_handle<> m_handle;
78+
coroutine_handle<> m_handle;
7979
};
8080
auto state = std::make_unique<threadpool_resume>(context, handle);
8181
submit_threadpool_callback([](void*, void* p)
@@ -86,7 +86,7 @@ namespace winrt::impl
8686
state.release();
8787
}
8888

89-
inline auto resume_apartment(resume_apartment_context const& context, std::experimental::coroutine_handle<> handle)
89+
inline auto resume_apartment(resume_apartment_context const& context, coroutine_handle<> handle)
9090
{
9191
if ((context.m_context == nullptr) || (context.m_context == try_capture<IContextCallback>(WINRT_IMPL_CoGetObjectContext)))
9292
{
@@ -246,7 +246,7 @@ namespace winrt::impl
246246
}
247247

248248
template <typename U>
249-
auto await_suspend(std::experimental::coroutine_handle<U> handle)
249+
auto await_suspend(coroutine_handle<U> handle)
250250
{
251251
return awaitable.await_suspend(handle);
252252
}
@@ -278,7 +278,7 @@ WINRT_EXPORT namespace winrt
278278
{
279279
}
280280

281-
void await_suspend(std::experimental::coroutine_handle<> handle) const
281+
void await_suspend(impl::coroutine_handle<> handle) const
282282
{
283283
impl::resume_background(handle);
284284
}
@@ -305,7 +305,7 @@ WINRT_EXPORT namespace winrt
305305
{
306306
}
307307

308-
void await_suspend(std::experimental::coroutine_handle<> resume)
308+
void await_suspend(impl::coroutine_handle<> resume)
309309
{
310310
m_resume = resume;
311311

@@ -325,7 +325,7 @@ WINRT_EXPORT namespace winrt
325325
}
326326

327327
T const& m_context;
328-
std::experimental::coroutine_handle<> m_resume{ nullptr };
328+
impl::coroutine_handle<> m_resume{ nullptr };
329329
};
330330

331331
return awaitable{ context };
@@ -342,7 +342,7 @@ WINRT_EXPORT namespace winrt
342342
{
343343
}
344344

345-
void await_suspend(std::experimental::coroutine_handle<> handle) const
345+
void await_suspend(impl::coroutine_handle<> handle) const
346346
{
347347
auto copy = context; // resuming may destruct *this, so use a copy
348348
impl::resume_apartment(copy, handle);
@@ -377,7 +377,7 @@ WINRT_EXPORT namespace winrt
377377
return m_duration.count() <= 0;
378378
}
379379

380-
void await_suspend(std::experimental::coroutine_handle<> handle)
380+
void await_suspend(impl::coroutine_handle<> handle)
381381
{
382382
m_handle = handle;
383383
m_timer.attach(check_pointer(WINRT_IMPL_CreateThreadpoolTimer(callback, this, nullptr)));
@@ -435,7 +435,7 @@ WINRT_EXPORT namespace winrt
435435

436436
handle_type<timer_traits> m_timer;
437437
Windows::Foundation::TimeSpan m_duration;
438-
std::experimental::coroutine_handle<> m_handle;
438+
impl::coroutine_handle<> m_handle;
439439
std::atomic<state> m_state{ state::idle };
440440
};
441441

@@ -475,7 +475,7 @@ WINRT_EXPORT namespace winrt
475475
return WINRT_IMPL_WaitForSingleObject(m_handle, 0) == 0;
476476
}
477477

478-
void await_suspend(std::experimental::coroutine_handle<> resume)
478+
void await_suspend(impl::coroutine_handle<> resume)
479479
{
480480
m_resume = resume;
481481
m_wait.attach(check_pointer(WINRT_IMPL_CreateThreadpoolWait(callback, this, nullptr)));
@@ -538,7 +538,7 @@ WINRT_EXPORT namespace winrt
538538
Windows::Foundation::TimeSpan m_timeout;
539539
void* m_handle;
540540
uint32_t m_result{};
541-
std::experimental::coroutine_handle<> m_resume{ nullptr };
541+
impl::coroutine_handle<> m_resume{ nullptr };
542542
std::atomic<state> m_state{ state::idle };
543543
};
544544

@@ -568,7 +568,7 @@ WINRT_EXPORT namespace winrt
568568
{
569569
}
570570

571-
void await_suspend(std::experimental::coroutine_handle<> handle)
571+
void await_suspend(impl::coroutine_handle<> handle)
572572
{
573573
if (!WINRT_IMPL_TrySubmitThreadpoolCallback(callback, handle.address(), &m_environment))
574574
{
@@ -580,7 +580,7 @@ WINRT_EXPORT namespace winrt
580580

581581
static void __stdcall callback(void*, void* context) noexcept
582582
{
583-
std::experimental::coroutine_handle<>::from_address(context)();
583+
impl::coroutine_handle<>::from_address(context)();
584584
}
585585

586586
struct pool_traits
@@ -628,7 +628,11 @@ WINRT_EXPORT namespace winrt
628628
struct fire_and_forget {};
629629
}
630630

631+
#ifdef __cpp_lib_coroutine
632+
namespace std
633+
#else
631634
namespace std::experimental
635+
#endif
632636
{
633637
template <typename... Args>
634638
struct coroutine_traits<winrt::fire_and_forget, Args...>

strings/base_coroutine_ui_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ WINRT_EXPORT namespace winrt
2222
{
2323
}
2424

25-
void await_suspend(std::experimental::coroutine_handle<> handle) const
25+
void await_suspend(impl::coroutine_handle<> handle) const
2626
{
2727
m_dispatcher.RunAsync(m_priority, [handle]
2828
{

strings/base_deferral.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ WINRT_EXPORT namespace winrt
2222

2323
[[nodiscard]] Windows::Foundation::IAsyncAction wait_for_deferrals()
2424
{
25-
struct awaitable : std::experimental::suspend_always
25+
struct awaitable : impl::suspend_always
2626
{
2727
bool await_suspend(coroutine_handle handle)
2828
{
@@ -37,7 +37,7 @@ WINRT_EXPORT namespace winrt
3737

3838
private:
3939

40-
using coroutine_handle = std::experimental::coroutine_handle<>;
40+
using coroutine_handle = impl::coroutine_handle<>;
4141

4242
void one_deferral_completed()
4343
{

0 commit comments

Comments
 (0)