constexpr explicit operator bool() const noexcept { return __handle_; }
_LIBCPP_ALWAYS_INLINE
- void operator()() const { resume(); }
+ void operator()() { resume(); }
_LIBCPP_ALWAYS_INLINE
- void resume() const {
+ void resume() {
_LIBCPP_ASSERT(__is_suspended(),
"resume() can only be called on suspended coroutines");
_LIBCPP_ASSERT(!done(),
}
_LIBCPP_ALWAYS_INLINE
- void destroy() const {
+ void destroy() {
_LIBCPP_ASSERT(__is_suspended(),
"destroy() can only be called on suspended coroutines");
__builtin_coro_destroy(__handle_);
// template <class Promise = void>
// struct coroutine_handle;
-// void destroy() const
+// void destroy()
#include <experimental/coroutine>
#include <type_traits>
namespace coro = std::experimental;
+template <class H>
+auto has_destroy_imp(H&& h, int) -> decltype(h.destroy(), std::true_type{});
+template <class H>
+auto has_destroy_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_destroy() {
+ return decltype(has_destroy_imp(std::declval<H>(), 0))::value;
+}
+
template <class Promise>
-void do_test(coro::coroutine_handle<Promise> const& H) {
+void do_test(coro::coroutine_handle<Promise>&& H) {
+ using HType = coro::coroutine_handle<Promise>;
// FIXME Add a runtime test
{
ASSERT_SAME_TYPE(decltype(H.destroy()), void);
- ASSERT_NOT_NOEXCEPT(H.destroy());
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H.destroy());
+ static_assert(has_destroy<HType&>(), "");
+ static_assert(has_destroy<HType&&>(), "");
+ }
+ {
+ static_assert(!has_destroy<HType const&>(), "");
+ static_assert(!has_destroy<HType const&&>(), "");
}
}
// template <class Promise = void>
// struct coroutine_handle;
-// void operator()() const
-// void resume() const
+// void operator()()
+// void resume()
#include <experimental/coroutine>
#include <type_traits>
namespace coro = std::experimental;
+
+template <class H>
+auto has_resume_imp(H&& h, int) -> decltype(h.resume(), std::true_type{});
+template <class H>
+auto has_resume_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_resume() {
+ return decltype(has_resume_imp(std::declval<H>(), 0))::value;
+}
+
+
+template <class H>
+auto has_call_operator_imp(H&& h, int) -> decltype(h(), std::true_type{});
+template <class H>
+auto has_call_operator_imp(H&&, long) -> std::false_type;
+
+template <class H>
+constexpr bool has_call_operator() {
+ return decltype(has_call_operator_imp(std::declval<H>(), 0))::value;
+}
+
template <class Promise>
-void do_test(coro::coroutine_handle<Promise> const& H) {
+void do_test(coro::coroutine_handle<Promise>&& H) {
+ using HType = coro::coroutine_handle<Promise>;
// FIXME Add a runtime test
{
ASSERT_SAME_TYPE(decltype(H.resume()), void);
ASSERT_SAME_TYPE(decltype(H()), void);
- ASSERT_NOT_NOEXCEPT(H.resume());
- ASSERT_NOT_NOEXCEPT(H());
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H.resume());
+ LIBCPP_ASSERT_NOT_NOEXCEPT(H());
+ static_assert(has_resume<HType&>(), "");
+ static_assert(has_resume<HType&&>(), "");
+ static_assert(has_call_operator<HType&>(), "");
+ static_assert(has_call_operator<HType&&>(), "");
+ }
+ {
+ static_assert(!has_resume<HType const&>(), "");
+ static_assert(!has_resume<HType const&&>(), "");
+ static_assert(!has_call_operator<HType const&>(), "");
+ static_assert(!has_call_operator<HType const&&>(), "");
}
}