Index: libcxx/CMakeLists.txt =================================================================== --- libcxx/CMakeLists.txt +++ libcxx/CMakeLists.txt @@ -569,7 +569,7 @@ endif() if (LIBCXX_CONFIGURE_IDE) - # This simply allows IDE to process + # This simply allows IDE to process target_add_compile_flags_if_supported(${target} PRIVATE -fcoroutines-ts) endif() Index: libcxx/include/CMakeLists.txt =================================================================== --- libcxx/include/CMakeLists.txt +++ libcxx/include/CMakeLists.txt @@ -337,7 +337,6 @@ experimental/__config experimental/__memory experimental/algorithm - experimental/coroutine experimental/deque experimental/filesystem experimental/forward_list Index: libcxx/include/experimental/coroutine =================================================================== --- libcxx/include/experimental/coroutine +++ /dev/null @@ -1,334 +0,0 @@ -// -*- C++ -*- -//===----------------------------- coroutine -----------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_EXPERIMENTAL_COROUTINE -#define _LIBCPP_EXPERIMENTAL_COROUTINE - -/** - experimental/coroutine synopsis - -// C++next - -namespace std { -namespace experimental { -inline namespace coroutines_v1 { - - // 18.11.1 coroutine traits -template -class coroutine_traits; -// 18.11.2 coroutine handle -template -class coroutine_handle; -// 18.11.2.7 comparison operators: -bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; -// 18.11.3 trivial awaitables -struct suspend_never; -struct suspend_always; -// 18.11.2.8 hash support: -template struct hash; -template struct hash>; - -} // namespace coroutines_v1 -} // namespace experimental -} // namespace std - - */ - -#include -#include -#include -#include -#include // for hash -#include -#include <__debug> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -#ifdef _LIBCPP_HAS_NO_COROUTINES -# if defined(_LIBCPP_WARNING) - _LIBCPP_WARNING(" cannot be used with this compiler") -# else -# warning cannot be used with this compiler -# endif -#endif - -#ifndef _LIBCPP_HAS_NO_COROUTINES - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES - -template -struct __coroutine_traits_sfinae {}; - -template -struct __coroutine_traits_sfinae< - _Tp, typename __void_t::type> -{ - using promise_type = typename _Tp::promise_type; -}; - -template -struct coroutine_traits - : public __coroutine_traits_sfinae<_Ret> -{ -}; - -template -class _LIBCPP_TEMPLATE_VIS coroutine_handle; - -template <> -class _LIBCPP_TEMPLATE_VIS coroutine_handle { -public: - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {} - - _LIBCPP_INLINE_VISIBILITY - coroutine_handle& operator=(nullptr_t) _NOEXCEPT { - __handle_ = nullptr; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; } - - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; } - - _LIBCPP_INLINE_VISIBILITY - void operator()() { resume(); } - - _LIBCPP_INLINE_VISIBILITY - void resume() { - _LIBCPP_ASSERT(__is_suspended(), - "resume() can only be called on suspended coroutines"); - _LIBCPP_ASSERT(!done(), - "resume() has undefined behavior when the coroutine is done"); - __builtin_coro_resume(__handle_); - } - - _LIBCPP_INLINE_VISIBILITY - void destroy() { - _LIBCPP_ASSERT(__is_suspended(), - "destroy() can only be called on suspended coroutines"); - __builtin_coro_destroy(__handle_); - } - - _LIBCPP_INLINE_VISIBILITY - bool done() const { - _LIBCPP_ASSERT(__is_suspended(), - "done() can only be called on suspended coroutines"); - return __builtin_coro_done(__handle_); - } - -public: - _LIBCPP_INLINE_VISIBILITY - static coroutine_handle from_address(void* __addr) _NOEXCEPT { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } - - // FIXME: Should from_address(nullptr) be allowed? - _LIBCPP_INLINE_VISIBILITY - static coroutine_handle from_address(nullptr_t) _NOEXCEPT { - return coroutine_handle(nullptr); - } - - template - static coroutine_handle from_address(_Tp*) { - static_assert(_CallIsValid, - "coroutine_handle::from_address cannot be called with " - "non-void pointers"); - } - -private: - bool __is_suspended() const _NOEXCEPT { - // FIXME actually implement a check for if the coro is suspended. - return __handle_; - } - - template friend class coroutine_handle; - void* __handle_; -}; - -// 18.11.2.7 comparison operators: -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return __x.address() == __y.address(); -} -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return !(__x == __y); -} -inline _LIBCPP_INLINE_VISIBILITY -bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return less()(__x.address(), __y.address()); -} -inline _LIBCPP_INLINE_VISIBILITY -bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return __y < __x; -} -inline _LIBCPP_INLINE_VISIBILITY -bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return !(__x > __y); -} -inline _LIBCPP_INLINE_VISIBILITY -bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { - return !(__x < __y); -} - -template -class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> { - using _Base = coroutine_handle<>; -public: -#ifndef _LIBCPP_CXX03_LANG - // 18.11.2.1 construct/reset - using coroutine_handle<>::coroutine_handle; -#else - _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {} - _LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {} -#endif - _LIBCPP_INLINE_VISIBILITY - coroutine_handle& operator=(nullptr_t) _NOEXCEPT { - _Base::operator=(nullptr); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - _Promise& promise() const { - return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); - } - -public: - _LIBCPP_INLINE_VISIBILITY - static coroutine_handle from_address(void* __addr) _NOEXCEPT { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } - - // NOTE: this overload isn't required by the standard but is needed so - // the deleted _Promise* overload doesn't make from_address(nullptr) - // ambiguous. - // FIXME: should from_address work with nullptr? - _LIBCPP_INLINE_VISIBILITY - static coroutine_handle from_address(nullptr_t) _NOEXCEPT { - return coroutine_handle(nullptr); - } - - template - static coroutine_handle from_address(_Tp*) { - static_assert(_CallIsValid, - "coroutine_handle::from_address cannot be called with " - "non-void pointers"); - } - - template - static coroutine_handle from_address(_Promise*) { - static_assert(_CallIsValid, - "coroutine_handle::from_address cannot be used with " - "pointers to the coroutine's promise type; use 'from_promise' instead"); - } - - _LIBCPP_INLINE_VISIBILITY - 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(const_cast<_RawPromise&>(__promise)), - _LIBCPP_ALIGNOF(_Promise), true); - return __tmp; - } -}; - -#if __has_builtin(__builtin_coro_noop) -struct noop_coroutine_promise {}; - -template <> -class _LIBCPP_TEMPLATE_VIS coroutine_handle - : public coroutine_handle<> { - using _Base = coroutine_handle<>; - using _Promise = noop_coroutine_promise; -public: - - _LIBCPP_INLINE_VISIBILITY - _Promise& promise() const { - return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); - } - - _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; } - _LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; } - - _LIBCPP_CONSTEXPR_AFTER_CXX17 void operator()() const _NOEXCEPT {} - _LIBCPP_CONSTEXPR_AFTER_CXX17 void resume() const _NOEXCEPT {} - _LIBCPP_CONSTEXPR_AFTER_CXX17 void destroy() const _NOEXCEPT {} - -private: - _LIBCPP_INLINE_VISIBILITY - friend coroutine_handle noop_coroutine() _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT { - this->__handle_ = __builtin_coro_noop(); - } -}; - -using noop_coroutine_handle = coroutine_handle; - -inline _LIBCPP_INLINE_VISIBILITY -noop_coroutine_handle noop_coroutine() _NOEXCEPT { - return noop_coroutine_handle(); -} -#endif // __has_builtin(__builtin_coro_noop) - -struct suspend_never { - _LIBCPP_INLINE_VISIBILITY - bool await_ready() const _NOEXCEPT { return true; } - _LIBCPP_INLINE_VISIBILITY - void await_suspend(coroutine_handle<>) const _NOEXCEPT {} - _LIBCPP_INLINE_VISIBILITY - void await_resume() const _NOEXCEPT {} -}; - -struct suspend_always { - _LIBCPP_INLINE_VISIBILITY - bool await_ready() const _NOEXCEPT { return false; } - _LIBCPP_INLINE_VISIBILITY - void await_suspend(coroutine_handle<>) const _NOEXCEPT {} - _LIBCPP_INLINE_VISIBILITY - void await_resume() const _NOEXCEPT {} -}; - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -struct hash<_VSTD_CORO::coroutine_handle<_Tp> > { - using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>; - _LIBCPP_INLINE_VISIBILITY - size_t operator()(__arg_type const& __v) const _NOEXCEPT - {return hash()(__v.address());} -}; - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_COROUTINES) - -#endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */ Index: libcxx/test/libcxx/double_include.sh.cpp =================================================================== --- libcxx/test/libcxx/double_include.sh.cpp +++ libcxx/test/libcxx/double_include.sh.cpp @@ -199,7 +199,7 @@ #if __cplusplus >= 201103L # include # if defined(__cpp_coroutines) -# include +# include # endif # include # ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY Index: libcxx/test/libcxx/min_max_macros.compile.pass.cpp =================================================================== --- libcxx/test/libcxx/min_max_macros.compile.pass.cpp +++ libcxx/test/libcxx/min_max_macros.compile.pass.cpp @@ -85,6 +85,10 @@ TEST_MACROS(); #include TEST_MACROS(); +# if defined(__cpp_coroutines) +# include +TEST_MACROS(); +# endif #include TEST_MACROS(); #include @@ -314,10 +318,6 @@ #if __cplusplus >= 201103L # include TEST_MACROS(); -# if defined(__cpp_coroutines) -# include -TEST_MACROS(); -# endif # include TEST_MACROS(); # ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY Index: libcxx/test/libcxx/no_assert_include.compile.pass.cpp =================================================================== --- libcxx/test/libcxx/no_assert_include.compile.pass.cpp +++ libcxx/test/libcxx/no_assert_include.compile.pass.cpp @@ -58,6 +58,9 @@ #include #include #include +# if defined(__cpp_coroutines) +# include +# endif #include #include #include @@ -193,9 +196,6 @@ // experimental headers #if __cplusplus >= 201103L # include -# if defined(__cpp_coroutines) -# include -# endif # include # ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY # include Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.hash/hash.pass.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// namespace std { -// template struct hash>; -// } - -#include -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test(uintptr_t LHSVal, uintptr_t RHSVal) { - const size_t ExpectLHS = std::hash{}(reinterpret_cast(LHSVal)); - const size_t ExpectRHS = std::hash{}(reinterpret_cast(RHSVal)); - const C LHS = C::from_address(reinterpret_cast(LHSVal)); - const C RHS = C::from_address(reinterpret_cast(RHSVal)); - const std::hash h; - // FIXME: libc++'s implementation hash's the result of LHS.address(), so we - // expect that value. However this is not required. - assert(h(LHS) == ExpectLHS); - assert(h(RHS) == ExpectRHS); - assert((h(LHS) == h(RHS)) == (LHSVal == RHSVal)); - { - ASSERT_SAME_TYPE(decltype(h(LHS)), size_t); - ASSERT_NOEXCEPT(std::hash{}(LHS)); - } -} - -int main(int, char**) -{ - std::pair const TestCases[] = { - {0, 0}, - {0, 8}, - {8, 8}, - {8, 16} - }; - for (auto& TC : TestCases) { - do_test>(TC.first, TC.second); - do_test>(TC.first, TC.second); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.pass.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// constexpr explicit operator bool() const noexcept - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test() { - static_assert(std::is_nothrow_constructible::value, ""); - static_assert(!std::is_convertible::value, ""); - { - constexpr C c; ((void)c); - static_assert(bool(c) == false, ""); - } - { // null case - const C c = {}; ((void)c); - ASSERT_NOEXCEPT(bool(c)); - if (c) - assert(false); - else - assert(true); - assert(c.address() == nullptr); - assert(bool(c) == false); - } - { // non-null case - char dummy = 42; - C c = C::from_address((void*)&dummy); - assert(c.address() == &dummy); - assert(bool(c) == true); - } -} - -int main(int, char**) -{ - do_test>(); - do_test>(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.pass.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// bool operator==(coroutine_handle<>, coroutine_handle<>) noexcept -// bool operator!=(coroutine_handle<>, coroutine_handle<>) noexcept - -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test(uintptr_t LHSVal, uintptr_t RHSVal) { - const C LHS = C::from_address(reinterpret_cast(LHSVal)); - const C RHS = C::from_address(reinterpret_cast(RHSVal)); - const bool ExpectIsEqual = (LHSVal == RHSVal); - assert((LHS == RHS) == ExpectIsEqual); - assert((RHS == LHS) == ExpectIsEqual); - assert((LHS != RHS) == !ExpectIsEqual); - assert((RHS != LHS) == !ExpectIsEqual); - { - static_assert(noexcept(LHS == RHS), ""); - static_assert(noexcept(LHS != RHS), ""); - ASSERT_SAME_TYPE(decltype(LHS == RHS), bool); - ASSERT_SAME_TYPE(decltype(LHS != RHS), bool); - } -} - -int main(int, char**) -{ - std::pair const TestCases[] = { - {0, 0}, - {16, 16}, - {0, 16}, - {16, 0} - }; - for (auto& TC : TestCases) { - do_test>(TC.first, TC.second); - do_test>(TC.first, TC.second); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.pass.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// bool operator<(coroutine_handle<>, coroutine_handle<>) noexcept -// bool operator>(coroutine_handle<>, coroutine_handle<>) noexcept -// bool operator>=(coroutine_handle<>, coroutine_handle<>) noexcept -// bool operator<=(coroutine_handle<>, coroutine_handle<>) noexcept - -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test(uintptr_t LHSVal, uintptr_t RHSVal) { - const C LHS = C::from_address(reinterpret_cast(LHSVal)); - const C RHS = C::from_address(reinterpret_cast(RHSVal)); - assert((LHS < RHS) == (LHSVal < RHSVal)); - assert((RHS < LHS) == (RHSVal < LHSVal)); - assert((LHS > RHS) == (LHSVal > RHSVal)); - assert((RHS > LHS) == (RHSVal > LHSVal)); - assert((LHS <= RHS) == (LHSVal <= RHSVal)); - assert((RHS <= LHS) == (RHSVal <= LHSVal)); - assert((LHS >= RHS) == (LHSVal >= RHSVal)); - assert((RHS >= LHS) == (RHSVal >= LHSVal)); - { - static_assert(noexcept(LHS < RHS), ""); - static_assert(noexcept(LHS > RHS), ""); - static_assert(noexcept(LHS <= RHS), ""); - static_assert(noexcept(LHS >= RHS), ""); - ASSERT_SAME_TYPE(decltype(LHS < RHS), bool); - ASSERT_SAME_TYPE(decltype(LHS > RHS), bool); - ASSERT_SAME_TYPE(decltype(LHS <= RHS), bool); - ASSERT_SAME_TYPE(decltype(LHS >= RHS), bool); - } -} - -int main(int, char**) -{ - std::pair const TestCases[] = { - {0, 0}, - {16, 16}, - {0, 16}, - {16, 0} - }; - for (auto& TC : TestCases) { - do_test>(TC.first, TC.second); - do_test>(TC.first, TC.second); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.completion/done.pass.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// bool done() const - -#include -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test(coro::coroutine_handle const& H) { - // FIXME Add a runtime test - { - ASSERT_SAME_TYPE(decltype(H.done()), bool); - LIBCPP_ASSERT_NOT_NOEXCEPT(H.done()); - } -} - -int main(int, char**) -{ - do_test(coro::coroutine_handle<>{}); - do_test(coro::coroutine_handle{}); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/assign.pass.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// coroutine_handle& operator=(nullptr_t) noexcept - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test() { - int dummy = 42; - void* dummy_h = &dummy; - { - C c; ((void)c); - static_assert(std::is_nothrow_assignable::value, ""); - static_assert(!std::is_assignable::value, ""); - } - { - C c = C::from_address(dummy_h); - assert(c.address() == &dummy); - c = nullptr; - assert(c.address() == nullptr); - c = nullptr; - assert(c.address() == nullptr); - } - { - C c; - C& cr = (c = nullptr); - assert(&c == &cr); - } -} - -int main(int, char**) -{ - do_test>(); - do_test>(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.con/construct.pass.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// constexpr coroutine_handle() noexcept -// constexpr coroutine_handle(nullptr_t) noexcept - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test() { - { - constexpr C c; - static_assert(std::is_nothrow_default_constructible::value, ""); - static_assert(c.address() == nullptr, ""); - } - { - constexpr C c(nullptr); - static_assert(std::is_nothrow_constructible::value, ""); - static_assert(c.address() == nullptr, ""); - } - { - C c; - assert(c.address() == nullptr); - } - { - C c(nullptr); - assert(c.address() == nullptr); - } -} - -int main(int, char**) -{ - do_test>(); - do_test>(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/address.pass.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// constexpr void* address() const noexcept - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test() { - { - constexpr C c; ((void)c); - static_assert(c.address() == nullptr, ""); - } - { - const C c = {}; ((void)c); - ASSERT_NOEXCEPT(c.address()); - ASSERT_SAME_TYPE(decltype(c.address()), void*); - assert(c.address() == nullptr); - } - { - char dummy = 42; - C c = C::from_address((void*)&dummy); - assert(c.address() == &dummy); - } -} - -int main(int, char**) -{ - do_test>(); - do_test>(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.fail.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 -// - -// template -// struct coroutine_handle; - -// static coroutine_handle from_address(void*) noexcept - -// Test that `from_address` is explicitly ill-formed when called with a typed -// pointer. The user cannot possibly have a typed pointer to the coroutine. -// FIXME: This behavior is an extension, and should upstreamed into the TS or -// the test removed if the TS changes are rejected. - -#include -#include -#include - -namespace coro = std::experimental; - -int main(int, char**) -{ - { - using H = coro::coroutine_handle<>; - // expected-error@experimental/coroutine:* 3 {{coroutine_handle::from_address cannot be called with non-void pointers}} - H::from_address((int*)nullptr); // expected-note {{requested here}} - H::from_address((const void*)nullptr); // expected-note {{requested here}} - H::from_address((const char*)nullptr); // expected-note {{requested here}} - } - { - using H = coro::coroutine_handle; - // expected-error@experimental/coroutine:* 1 {{static_assert failed "coroutine_handle::from_address cannot be used with pointers to the coroutine's promise type; use 'from_promise' instead"}} - H::from_address((const char*)nullptr); // expected-note {{requested here}} - // expected-error@experimental/coroutine:* 1 {{coroutine_handle::from_address cannot be called with non-void pointers}} - H::from_address((int*)nullptr); // expected-note {{requested here}} - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.export/from_address.pass.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// static coroutine_handle from_address(void*) noexcept - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -void do_test() { - { - C c = C::from_address(nullptr); - static_assert(noexcept(C::from_address(nullptr)), ""); - // FIXME: Should the return type not be 'C'? - static_assert(std::is_same::value, ""); - assert(c.address() == nullptr); - } - { - char dummy = 42; - C c = C::from_address((void*)&dummy); - assert(c.address() == &dummy); - } -} - -int main(int, char**) -{ - do_test>(); - do_test>(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.noop/noop_coroutine.pass.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 -// UNSUPPORTED: ubsan - -// -// struct noop_coroutine_promise; -// using noop_coroutine_handle = coroutine_handle; -// noop_coroutine_handle noop_coroutine() noexcept; - -#include -#include -#include - -#include "test_macros.h" - -#if __has_builtin(__builtin_coro_noop) - -namespace coro = std::experimental::coroutines_v1; - - -static_assert(std::is_same, coro::noop_coroutine_handle>::value, ""); -static_assert(std::is_same::value, ""); - -// template <> struct coroutine_handle : coroutine_handle<> -// { -// // 18.11.2.7 noop observers -// constexpr explicit operator bool() const noexcept; -// constexpr bool done() const noexcept; - -// // 18.11.2.8 noop resumption -// constexpr void operator()() const noexcept; -// constexpr void resume() const noexcept; -// constexpr void destroy() const noexcept; - -// // 18.11.2.9 noop promise access -// noop_coroutine_promise& promise() const noexcept; - -// // 18.11.2.10 noop address -// constexpr void* address() const noexcept; - -int main(int, char**) -{ - auto h = coro::noop_coroutine(); - coro::coroutine_handle<> base = h; - - assert(h); - assert(base); - - assert(!h.done()); - assert(!base.done()); - - h.resume(); - h.destroy(); - h(); - static_assert(h.done() == false, ""); - static_assert(h, ""); - - h.promise(); - assert(h.address() == base.address()); - assert(h.address() != nullptr); - assert(coro::coroutine_handle<>::from_address(h.address()) == base); - - return 0; -} - -#else - -int main(int, char**) { return 0; } - -#endif // __has_builtin(__builtin_coro_noop) Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.prom/promise.pass.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// Promise& promise() const - -#include -#include -#include -#include -#include -#include - -#include "test_macros.h" - -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() noexcept { return {}; } - MyCoro get_return_object() { - do_runtime_test(); - return {}; - } - void do_runtime_test() { - // Test that a coroutine_handle can be created from a const - // promise_type and that it represents the same coroutine as - // coroutine_handle - using CH = coro::coroutine_handle; - using CCH = coro::coroutine_handle; - 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 -void do_test(coro::coroutine_handle&& H) { - - // FIXME Add a runtime test - { - ASSERT_SAME_TYPE(decltype(H.promise()), Promise&); - LIBCPP_ASSERT_NOT_NOEXCEPT(H.promise()); - } - { - auto const& CH = H; - ASSERT_SAME_TYPE(decltype(CH.promise()), Promise&); - LIBCPP_ASSERT_NOT_NOEXCEPT(CH.promise()); - } -} - -int main(int, char**) -{ - do_test(coro::coroutine_handle{}); - do_test(coro::coroutine_handle{}); - do_runtime_test(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.pass.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// void destroy() - -#include -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -auto has_destroy_imp(H&& h, int) -> decltype(h.destroy(), std::true_type{}); -template -auto has_destroy_imp(H&&, long) -> std::false_type; - -template -constexpr bool has_destroy() { - return decltype(has_destroy_imp(std::declval(), 0))::value; -} - -template -void do_test(coro::coroutine_handle&& H) { - using HType = coro::coroutine_handle; - // FIXME Add a runtime test - { - ASSERT_SAME_TYPE(decltype(H.destroy()), void); - LIBCPP_ASSERT_NOT_NOEXCEPT(H.destroy()); - static_assert(has_destroy(), ""); - static_assert(has_destroy(), ""); - } - { - static_assert(!has_destroy(), ""); - static_assert(!has_destroy(), ""); - } -} - -int main(int, char**) -{ - do_test(coro::coroutine_handle<>{}); - do_test(coro::coroutine_handle{}); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.pass.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// template -// struct coroutine_handle; - -// void operator()() -// void resume() - -#include -#include -#include -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - - -template -auto has_resume_imp(H&& h, int) -> decltype(h.resume(), std::true_type{}); -template -auto has_resume_imp(H&&, long) -> std::false_type; - -template -constexpr bool has_resume() { - return decltype(has_resume_imp(std::declval(), 0))::value; -} - - -template -auto has_call_operator_imp(H&& h, int) -> decltype(h(), std::true_type{}); -template -auto has_call_operator_imp(H&&, long) -> std::false_type; - -template -constexpr bool has_call_operator() { - return decltype(has_call_operator_imp(std::declval(), 0))::value; -} - -template -void do_test(coro::coroutine_handle&& H) { - using HType = coro::coroutine_handle; - // FIXME Add a runtime test - { - ASSERT_SAME_TYPE(decltype(H.resume()), void); - ASSERT_SAME_TYPE(decltype(H()), void); - LIBCPP_ASSERT_NOT_NOEXCEPT(H.resume()); - LIBCPP_ASSERT_NOT_NOEXCEPT(H()); - static_assert(has_resume(), ""); - static_assert(has_resume(), ""); - static_assert(has_call_operator(), ""); - static_assert(has_call_operator(), ""); - } - { - static_assert(!has_resume(), ""); - static_assert(!has_resume(), ""); - static_assert(!has_call_operator(), ""); - static_assert(!has_call_operator(), ""); - } -} - -int main(int, char**) -{ - do_test(coro::coroutine_handle<>{}); - do_test(coro::coroutine_handle{}); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.handle/void_handle.pass.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -struct A { - using promise_type = A*; -}; - -struct B {}; -struct C {}; - -namespace std { namespace experimental { - template <> - struct coroutine_traits<::A, int> { - using promise_type = int*; - }; - template - struct coroutine_traits<::B, Args...> { - using promise_type = B*; - }; - template <> - struct coroutine_traits<::C> { - using promise_type = void; - }; -}} - -template -void check_type() { - using P = typename coro::coroutine_traits::promise_type ; - static_assert(std::is_same::value, ""); -}; - -int main(int, char**) -{ - check_type(); - check_type(); - check_type(); - check_type(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.traits/promise_type.pass.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -template -constexpr bool has_promise_type(int) { return true; } -template -constexpr bool has_promise_type(long) { return false; } -template -constexpr bool has_promise_type() { return has_promise_type(0); } - -struct A { - using promise_type = A*; -}; - -struct B {}; -struct C {}; -struct D { -private: - using promise_type = void; -}; -struct E {}; - -namespace std { namespace experimental { - template <> - struct coroutine_traits<::A, int> { - using promise_type = int*; - }; - template - struct coroutine_traits<::B, Args...> { - using promise_type = B*; - }; - template <> - struct coroutine_traits<::C> { - using promise_type = void; - }; -}} - -template -void check_type() { - using Traits = coro::coroutine_traits; - static_assert(has_promise_type(), ""); - static_assert(std::is_same::value, ""); -} - -template -void check_no_type() { - using Traits = coro::coroutine_traits; - static_assert(!has_promise_type(), ""); -} - -int main(int, char**) -{ - { - check_type(); - check_type(); - check_type(); - check_type(); - } - { - check_no_type(); - check_no_type(); - check_no_type(); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_always.pass.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -using SuspendT = std::experimental::coroutines_v1::suspend_always; - -TEST_SAFE_STATIC SuspendT safe_sa; -constexpr SuspendT constexpr_sa; - -constexpr bool check_suspend_constexpr() { - SuspendT s{}; - const SuspendT scopy(s); ((void)scopy); - SuspendT smove(std::move(s)); ((void)smove); - s = scopy; - s = std::move(smove); - return true; -} - -int main(int, char**) -{ - using H = coro::coroutine_handle<>; - using S = SuspendT; - H h{}; - S s{}; - S const& cs = s; - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_ready()), ""); - static_assert(std::is_same::value, ""); - assert(s.await_ready() == false); - assert(cs.await_ready() == false); - } - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), ""); - static_assert(std::is_same::value, ""); - s.await_suspend(h); - cs.await_suspend(h); - } - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), ""); - static_assert(std::is_same::value, ""); - s.await_resume(); - cs.await_resume(); - } - { - static_assert(std::is_nothrow_default_constructible::value, ""); - static_assert(std::is_nothrow_copy_constructible::value, ""); - static_assert(std::is_nothrow_move_constructible::value, ""); - static_assert(std::is_nothrow_copy_assignable::value, ""); - static_assert(std::is_nothrow_move_assignable::value, ""); - static_assert(std::is_trivially_copyable::value, ""); - static_assert(check_suspend_constexpr(), ""); - } - { - // suppress unused warnings for the global constexpr test variable - ((void)constexpr_sa); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/coroutine.trivial.awaitables/suspend_never.pass.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include -#include - -#include "test_macros.h" - -namespace coro = std::experimental; - -// Test that the type is in the correct namespace -using SuspendT = std::experimental::coroutines_v1::suspend_never; - -TEST_SAFE_STATIC SuspendT safe_sn; -constexpr SuspendT constexpr_sn; - -constexpr bool check_suspend_constexpr() { - SuspendT s{}; - const SuspendT scopy(s); ((void)scopy); - SuspendT smove(std::move(s)); ((void)smove); - s = scopy; - s = std::move(smove); - return true; -} - - -int main(int, char**) -{ - using H = coro::coroutine_handle<>; - using S = SuspendT; - H h{}; - S s{}; - S const& cs = s; - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_ready()), ""); - static_assert(std::is_same::value, ""); - assert(s.await_ready() == true); - assert(cs.await_ready() == true); - } - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), ""); - static_assert(std::is_same::value, ""); - s.await_suspend(h); - cs.await_suspend(h); - } - { - LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), ""); - static_assert(std::is_same::value, ""); - s.await_resume(); - cs.await_resume(); - } - { - static_assert(std::is_nothrow_default_constructible::value, ""); - static_assert(std::is_nothrow_copy_constructible::value, ""); - static_assert(std::is_nothrow_move_constructible::value, ""); - static_assert(std::is_nothrow_copy_assignable::value, ""); - static_assert(std::is_nothrow_move_assignable::value, ""); - static_assert(std::is_trivially_copyable::value, ""); - static_assert(check_suspend_constexpr(), ""); - } - { - // suppress unused warnings for the global constexpr test variable - ((void)constexpr_sn); - } - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/await_result.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/await_result.pass.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -struct coro_t { - struct promise_type { - coro_t get_return_object() { - coroutine_handle{}; - return {}; - } - suspend_never initial_suspend() { return {}; } - suspend_never final_suspend() noexcept { return {}; } - void return_void() {} - static void unhandled_exception() {} - }; -}; - -struct B { - ~B() {} - bool await_ready() { return true; } - B await_resume() { return {}; } - template void await_suspend(F) {} -}; - - -struct A { - ~A() {} - bool await_ready() { return true; } - int await_resume() { return 42; } - template void await_suspend(F) {} -}; - -int last_value = -1; -void set_value(int x) { - last_value = x; -} - -coro_t f(int n) { - if (n == 0) { - set_value(0); - co_return; - } - int val = co_await A{}; - ((void)val); - set_value(42); -} - -coro_t g() { B val = co_await B{}; } - -int main(int, char**) { - last_value = -1; - f(0); - assert(last_value == 0); - f(1); - assert(last_value == 42); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/bool_await_suspend.pass.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// See https://llvm.org/PR33271 -// UNSUPPORTED: ubsan - -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -struct coro_t { - struct promise_type { - coro_t get_return_object() { - return coroutine_handle::from_promise(*this); - } - suspend_never initial_suspend() { return {}; } - suspend_never final_suspend() noexcept { return {}; } - void return_void() {} - void unhandled_exception() {} - }; - coro_t(coroutine_handle hh) : h(hh) {} - coroutine_handle h; -}; - -struct NoSuspend { - bool await_ready() { return false; } - void await_resume() {} - template bool await_suspend(F) { return false; } -}; - -struct DoSuspend { - bool await_ready() { return false; } - void await_resume() {} - template bool await_suspend(F) { return true; } -}; - -bool f_started, f_resumed = false; -coro_t f() { - f_started = true; - co_await DoSuspend{}; - f_resumed = true; -} - -bool g_started, g_resumed = false; -coro_t g() { - g_started = true; - co_await NoSuspend{}; - g_resumed = true; -} - -int main(int, char**) { - assert(!f_started && !f_resumed && !g_started && !g_resumed); - auto fret = f(); - assert(f_started && !f_resumed); - fret.h.destroy(); - assert(f_started && !f_resumed); - g(); - assert(g_started && g_resumed); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/expected.pass.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include -#include - -#include "test_macros.h" -using namespace std::experimental; - -struct error_tag { }; - -template -struct expected { - - struct Data { - Data() : val(), error() { } - Data(T v, Error e) : val(v), error(e) { } - T val; - Error error; - }; - std::shared_ptr data; - - expected(T val) : data(std::make_shared(val, Error())) {} - expected(error_tag, Error error) : data(std::make_shared(T(), error)) {} - expected(std::shared_ptr p) : data(p) {} - - struct promise_type { - std::shared_ptr data; - expected get_return_object() { data = std::make_shared(); return {data}; } - suspend_never initial_suspend() { return {}; } - suspend_never final_suspend() noexcept { return {}; } - void return_value(T v) { data->val = v; data->error = {}; } - void unhandled_exception() {} - }; - - bool await_ready() { return !data->error; } - T await_resume() { return data->val; } - void await_suspend(coroutine_handle h) { - h.promise().data->error = data->error; - h.destroy(); - } - - T const& value() { return data->val; } - Error const& error() { return data->error; } -}; - -expected g() { return {0}; } -expected h() { return {error_tag{}, 42}; } - -extern "C" void print(int); - -bool f1_started, f1_resumed = false; -expected f1() { - f1_started = true; - (void)(co_await g()); - f1_resumed = true; - co_return 100; -} - -bool f2_started, f2_resumed = false; -expected f2() { - f2_started = true; - (void)(co_await h()); - f2_resumed = true; - co_return 200; -} - -int main(int, char**) { - auto c1 = f1(); - assert(f1_started && f1_resumed); - assert(c1.value() == 100); - assert(c1.error() == 0); - - auto c2 = f2(); - assert(f2_started && !f2_resumed); - assert(c2.value() == 0); - assert(c2.error() == 42); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/fullexpr-dtor.pass.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -int alive = 0; -int ctor_called = 0; -int dtor_called = 0; -void reset() { - assert(alive == 0); - alive = 0; - ctor_called = 0; - dtor_called = 0; -} -struct Noisy { - Noisy() { ++alive; ++ctor_called; } - ~Noisy() { --alive; ++dtor_called; } -#if TEST_STD_VER > 14 - Noisy(Noisy const&) = delete; -#else - // FIXME: This test depends on copy elision taking place in C++14 - // (pre-C++17 guaranteed copy elision) - Noisy(Noisy const&); -#endif -}; - -struct Bug { - bool await_ready() { return true; } - void await_suspend(std::experimental::coroutine_handle<>) {} - Noisy await_resume() { return {}; } -}; -struct coro2 { - struct promise_type { - suspend_never initial_suspend() { return{}; } - suspend_never final_suspend() noexcept { return {}; } - coro2 get_return_object() { return{}; } - void return_void() {} - Bug yield_value(int) { return {}; } - void unhandled_exception() {} - }; -}; - -// Checks that destructors are correctly invoked for the object returned by -// coawait. -coro2 a() { - reset(); - { - auto x = co_await Bug{}; - assert(alive == 1); - assert(ctor_called == 1); - assert(dtor_called == 0); - ((void)x); - } - assert(alive == 0); - assert(dtor_called == 1); -} - -coro2 b() { - reset(); - { - (void)(co_await Bug{}); - assert(ctor_called == 1); - assert(dtor_called == 1); - assert(alive == 0); - } - assert(ctor_called == 1); - assert(dtor_called == 1); - assert(alive == 0); - -} - -coro2 c() { - reset(); - { - auto x = co_yield 42; - assert(alive == 1); - assert(ctor_called == 1); - assert(dtor_called == 0); - } - assert(alive == 0); - assert(ctor_called == 1); - assert(dtor_called == 1); -} - -coro2 d() { - reset(); - { - (void)(co_yield 42); - assert(ctor_called == 1); - assert(dtor_called == 1); - assert(alive == 0); - } - assert(alive == 0); - assert(ctor_called == 1); - assert(dtor_called == 1); -} - -int main(int, char**) { - a(); - b(); - c(); - d(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/generator.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/generator.pass.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// See https://llvm.org/PR33271 -// UNSUPPORTED: ubsan - -#include -#include -#include - -#include "test_macros.h" -#include "coroutine_experimental_types.h" - -using namespace std::experimental; - -struct minig { - struct promise_type { - int current_value; - suspend_always yield_value(int value) { - this->current_value = value; - return {}; - } - suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() noexcept { return {}; } - minig get_return_object() { return minig{this}; }; - void return_void() {} - void unhandled_exception() {} - }; - - bool move_next() { - p.resume(); - return !p.done(); - } - int current_value() { return p.promise().current_value; } - - minig(minig &&rhs) : p(rhs.p) { rhs.p = nullptr; } - - ~minig() { - if (p) - p.destroy(); - } - -private: - explicit minig(promise_type *p) - : p(coroutine_handle::from_promise(*p)) {} - - coroutine_handle p; -}; - - -minig mini_count(int n) { - for (int i = 0; i < n; i++) { - co_yield i; - } -} - -generator count(int n) { - for (int i = 0; i < n; ++i) - co_yield i; -} - -generator range(int from, int n) { - for (int i = from; i < n; ++i) - co_yield i; -} - -void test_count() { - const std::vector expect = {0, 1, 2, 3, 4}; - std::vector got; - for (auto x : count(5)) - got.push_back(x); - assert(expect == got); -} - -void test_range() { - int sum = 0; - for (auto v: range(1, 20)) - sum += v; - assert(sum == 190); -} - -void test_mini_generator() { - int sum = 0; - auto g = mini_count(5); - while (g.move_next()) { - sum += g.current_value(); - } - assert(sum == 10); -} - -int main(int, char**) { - test_count(); - test_range(); - test_mini_generator(); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/go.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/go.pass.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -bool cancel = false; - -struct goroutine -{ - static int const N = 10; - static int count; - static coroutine_handle<> stack[N]; - - static void schedule(coroutine_handle<>& rh) - { - assert(count < N); - stack[count++] = rh; - rh = nullptr; - } - - ~goroutine() {} - - static void go(goroutine) {} - - static void run_one() - { - assert(count > 0); - stack[--count](); - } - - struct promise_type - { - suspend_never initial_suspend() { - return {}; - } - suspend_never final_suspend() noexcept { return {}; } - void return_void() {} - goroutine get_return_object() { - return{}; - } - void unhandled_exception() {} - }; -}; -int goroutine::count; -coroutine_handle<> goroutine::stack[N]; - -coroutine_handle workaround; - -class channel; - -struct push_awaiter { - channel* ch; - bool await_ready() {return false; } - void await_suspend(coroutine_handle<> rh); - void await_resume() {} -}; - -struct pull_awaiter { - channel * ch; - - bool await_ready(); - void await_suspend(coroutine_handle<> rh); - int await_resume(); -}; - -class channel -{ - using T = int; - - friend struct push_awaiter; - friend struct pull_awaiter; - - T const* pvalue = nullptr; - coroutine_handle<> reader = nullptr; - coroutine_handle<> writer = nullptr; -public: - push_awaiter push(T const& value) - { - assert(pvalue == nullptr); - assert(!writer); - pvalue = &value; - - return { this }; - } - - pull_awaiter pull() - { - assert(!reader); - - return { this }; - } - - void sync_push(T const& value) - { - assert(!pvalue); - pvalue = &value; - assert(reader); - reader(); - assert(!pvalue); - reader = nullptr; - } - - auto sync_pull() - { - while (!pvalue) goroutine::run_one(); - auto result = *pvalue; - pvalue = nullptr; - if (writer) - { - auto wr = writer; - writer = nullptr; - wr(); - } - return result; - } -}; - -void push_awaiter::await_suspend(coroutine_handle<> rh) -{ - ch->writer = rh; - if (ch->reader) goroutine::schedule(ch->reader); -} - - -bool pull_awaiter::await_ready() { - return !!ch->writer; -} -void pull_awaiter::await_suspend(coroutine_handle<> rh) { - ch->reader = rh; -} -int pull_awaiter::await_resume() { - auto result = *ch->pvalue; - ch->pvalue = nullptr; - if (ch->writer) { - //goroutine::schedule(ch->writer); - auto wr = ch->writer; - ch->writer = nullptr; - wr(); - } - return result; -} - -goroutine pusher(channel& left, channel& right) -{ - for (;;) { - auto val = co_await left.pull(); - co_await right.push(val + 1); - } -} - -const int N = 100; -channel* c = new channel[N + 1]; - -int main(int, char**) { - for (int i = 0; i < N; ++i) - goroutine::go(pusher(c[i], c[i + 1])); - - c[0].sync_push(0); - int result = c[N].sync_pull(); - - assert(result == 100); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/multishot_func.pass.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -// This file tests, multishot, movable std::function like thing using coroutine -// for compile-time type erasure and unerasure. -template struct func { - struct Input {R a, b;}; - - struct promise_type { - Input* I; - R result; - func get_return_object() { return {this}; } - suspend_always initial_suspend() { return {}; } - suspend_never final_suspend() noexcept { return {}; } - void return_void() {} - template - suspend_always yield_value(F&& f) { - result = f(I->a, I->b); - return {}; - } - void unhandled_exception() {} - }; - - R operator()(Input I) { - h.promise().I = &I; - h.resume(); - R result = h.promise().result; - return result; - }; - - func() {} - func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; } - func(func const &) = delete; - - func &operator=(func &&rhs) { - if (this != &rhs) { - if (h) - h.destroy(); - h = rhs.h; - rhs.h = nullptr; - } - return *this; - } - - template static func Create(F f) { - for (;;) { - co_yield f; - } - } - - template func(F f) : func(Create(f)) {} - - ~func() { - if (h) - h.destroy(); - } - -private: - func(promise_type *promise) - : h(coroutine_handle::from_promise(*promise)) {} - coroutine_handle h; -}; - -int Do(int acc, int n, func f) { - for (int i = 0; i < n; ++i) - acc = f({acc, i}); - return acc; -} - -int main(int, char**) { - int result = Do(1, 10, [](int a, int b) {return a + b;}); - assert(result == 46); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -#include -#include -#include - -#include "test_macros.h" - -using namespace std::experimental; - -// This file tests, one shot, movable std::function like thing using coroutine -// for compile-time type erasure and unerasure. - -template struct func { - struct promise_type { - R result; - func get_return_object() { return {this}; } - suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() noexcept { return {}; } - void return_value(R v) { result = v; } - void unhandled_exception() {} - }; - - R operator()() { - h.resume(); - R result = h.promise().result; - h.destroy(); - h = nullptr; - return result; - }; - - func() {} - func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; } - func(func const &) = delete; - - func &operator=(func &&rhs) { - if (this != &rhs) { - if (h) - h.destroy(); - h = rhs.h; - rhs.h = nullptr; - } - return *this; - } - - template static func Create(F f) { co_return f(); } - - template func(F f) : func(Create(f)) {} - - ~func() { - if (h) - h.destroy(); - } - -private: - func(promise_type *promise) - : h(coroutine_handle::from_promise(*promise)) {} - coroutine_handle h; -}; - -std::vector yielded_values = {}; -int yield(int x) { yielded_values.push_back(x); return x + 1; } -float fyield(int x) { yielded_values.push_back(x); return static_cast(x + 2); } - -void Do1(func f) { yield(f()); } -void Do2(func f) { yield(static_cast(f())); } - -int main(int, char**) { - Do1([] { return yield(43); }); - assert((yielded_values == std::vector{43, 44})); - - yielded_values = {}; - Do2([] { return fyield(44); }); - assert((yielded_values == std::vector{44, 46})); - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/includes.pass.cpp =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/includes.pass.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11 - -// - -// Test that includes - -#include - -int main(int, char**) { - // std::nothrow is not implicitly defined by the compiler when the include is - // missing, unlike other parts of . Therefore we use std::nothrow to - // test for #include - - (void)std::nothrow; - - return 0; -} Index: libcxx/test/std/experimental/language.support/support.coroutines/lit.local.cfg =================================================================== --- libcxx/test/std/experimental/language.support/support.coroutines/lit.local.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# If the compiler doesn't support coroutines mark all of the tests under -# this directory as unsupported. Otherwise add the required `-fcoroutines-ts` -# flag. -if 'fcoroutines-ts' not in config.available_features: - config.unsupported = True -else: - config.test_format.addCompileFlags(config, '-fcoroutines-ts') Index: libcxx/test/support/coroutine_experimental_types.h =================================================================== --- libcxx/test/support/coroutine_experimental_types.h +++ /dev/null @@ -1,74 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef SUPPORT_COROUTINE_EXPERIMENTAL_TYPES_H -#define SUPPORT_COROUTINE_EXPERIMENTAL_TYPES_H - -#include - -template struct generator { - struct promise_type { - Ty current_value; - std::experimental::suspend_always yield_value(Ty value) { - this->current_value = value; - return {}; - } - std::experimental::suspend_always initial_suspend() { return {}; } - std::experimental::suspend_always final_suspend() noexcept { return {}; } - generator get_return_object() { return generator{this}; }; - void return_void() {} - void unhandled_exception() {} - }; - - struct iterator { - std::experimental::coroutine_handle _Coro; - bool _Done; - - iterator(std::experimental::coroutine_handle Coro, bool Done) - : _Coro(Coro), _Done(Done) {} - - iterator &operator++() { - _Coro.resume(); - _Done = _Coro.done(); - return *this; - } - - bool operator==(iterator const &_Right) const { - return _Done == _Right._Done; - } - - bool operator!=(iterator const &_Right) const { return !(*this == _Right); } - - Ty const &operator*() const { return _Coro.promise().current_value; } - - Ty const *operator->() const { return &(operator*()); } - }; - - iterator begin() { - p.resume(); - return {p, p.done()}; - } - - iterator end() { return {p, true}; } - - generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; } - - ~generator() { - if (p) - p.destroy(); - } - -private: - explicit generator(promise_type *p) - : p(std::experimental::coroutine_handle::from_promise(*p)) {} - - std::experimental::coroutine_handle p; -}; - -#endif // SUPPORT_COROUTINE_EXPERIMENTAL_TYPES_H Index: libcxx/utils/generate_header_tests.py =================================================================== --- libcxx/utils/generate_header_tests.py +++ libcxx/utils/generate_header_tests.py @@ -49,9 +49,9 @@ "sstream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"], "streambuf": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"], "strstream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"], - - "experimental/coroutine": ["if defined(__cpp_coroutines)"], "experimental/regex": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"], + + "coroutine": ["if defined(__cpp_coroutines)"], } allowed_extensions = ['', '.h']