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. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@305536 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -250,9 +250,11 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_ALWAYS_INLINE
|
_LIBCPP_ALWAYS_INLINE
|
||||||
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
|
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
|
||||||
|
typedef typename remove_cv<_Promise>::type _RawPromise;
|
||||||
coroutine_handle __tmp;
|
coroutine_handle __tmp;
|
||||||
__tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise),
|
__tmp.__handle_ = __builtin_coro_promise(
|
||||||
__alignof(_Promise), true);
|
_VSTD::addressof(const_cast<_RawPromise&>(__promise)),
|
||||||
|
__alignof(_Promise), true);
|
||||||
return __tmp;
|
return __tmp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,6 +28,39 @@
|
|||||||
|
|
||||||
namespace coro = std::experimental;
|
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>
|
template <class Promise>
|
||||||
void do_test(coro::coroutine_handle<Promise>&& H) {
|
void do_test(coro::coroutine_handle<Promise>&& H) {
|
||||||
|
|
||||||
@@ -46,4 +79,6 @@ void do_test(coro::coroutine_handle<Promise>&& H) {
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
do_test(coro::coroutine_handle<int>{});
|
do_test(coro::coroutine_handle<int>{});
|
||||||
|
do_test(coro::coroutine_handle<const int>{});
|
||||||
|
do_runtime_test();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user