forked from OSchip/llvm-project
Allow coroutine_handle<const T> to support creation from const references to the promise_type
It seems conceivable that a user would need to get a coroutine handle having only a const reference to the promise_type, for example from within a const member function of the promise. This patch allows that use case. A coroutine_handle<const T> can be used in essentially the same way a coroutine_handle<T>, ie to start and destroy the coroutine. The constness of the promise doesn't/shouldn't propagate to the handle. llvm-svn: 305536
This commit is contained in:
parent
f63d41469c
commit
f9bc058935
|
@ -250,9 +250,11 @@ public:
|
|||
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
|
||||
typedef typename remove_cv<_Promise>::type _RawPromise;
|
||||
coroutine_handle __tmp;
|
||||
__tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise),
|
||||
__alignof(_Promise), true);
|
||||
__tmp.__handle_ = __builtin_coro_promise(
|
||||
_VSTD::addressof(const_cast<_RawPromise&>(__promise)),
|
||||
__alignof(_Promise), true);
|
||||
return __tmp;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,6 +28,39 @@
|
|||
|
||||
namespace coro = std::experimental;
|
||||
|
||||
struct MyCoro {
|
||||
struct promise_type {
|
||||
void unhandled_exception() {}
|
||||
void return_void() {}
|
||||
coro::suspend_never initial_suspend() { return {}; }
|
||||
coro::suspend_never final_suspend() { return {}; }
|
||||
MyCoro get_return_object() {
|
||||
do_runtime_test();
|
||||
return {};
|
||||
}
|
||||
void do_runtime_test() {
|
||||
// Test that a coroutine_handle<const T> can be created from a const
|
||||
// promise_type and that it represents the same coroutine as
|
||||
// coroutine_handle<T>
|
||||
using CH = coro::coroutine_handle<promise_type>;
|
||||
using CCH = coro::coroutine_handle<const promise_type>;
|
||||
const auto &cthis = *this;
|
||||
CH h = CH::from_promise(*this);
|
||||
CCH h2 = CCH::from_promise(*this);
|
||||
CCH h3 = CCH::from_promise(cthis);
|
||||
assert(&h.promise() == this);
|
||||
assert(&h2.promise() == this);
|
||||
assert(&h3.promise() == this);
|
||||
assert(h.address() == h2.address());
|
||||
assert(h2.address() == h3.address());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
MyCoro do_runtime_test() {
|
||||
co_await coro::suspend_never{};
|
||||
}
|
||||
|
||||
template <class Promise>
|
||||
void do_test(coro::coroutine_handle<Promise>&& H) {
|
||||
|
||||
|
@ -46,4 +79,6 @@ void do_test(coro::coroutine_handle<Promise>&& H) {
|
|||
int main()
|
||||
{
|
||||
do_test(coro::coroutine_handle<int>{});
|
||||
do_test(coro::coroutine_handle<const int>{});
|
||||
do_runtime_test();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue