[libcxx] r303836 - Add <experimental/coroutine>

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu May 25 15:57:39 PDT 2017


On 24 May 2017 at 21:36, Eric Fiselier via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: ericwf
> Date: Wed May 24 23:36:24 2017
> New Revision: 303836
>
> URL: http://llvm.org/viewvc/llvm-project?rev=303836&view=rev
> Log:
> Add <experimental/coroutine>
>
> This patch adds the library portions of the coroutines PDTS,
> which should now be supported by Clang.
>
> Added:
>     libcxx/trunk/include/experimental/coroutine
>     libcxx/trunk/test/libcxx/experimental/language.support/
>     libcxx/trunk/test/libcxx/experimental/language.support/
> support.coroutines/
>     libcxx/trunk/test/libcxx/experimental/language.support/
> support.coroutines/version.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.capacity/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> capacity/operator_bool.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.compare/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> compare/equal_comp.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> compare/less_comp.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.completion/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> completion/done.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> export/from_address.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.hash/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.prom/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.resumption/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> resumption/destroy.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> resumption/resume.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/void_handle.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.traits/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.traits/promise_type.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp
>     libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/includes.sh.cpp
> Modified:
>     libcxx/trunk/CMakeLists.txt
>     libcxx/trunk/include/experimental/__config
>     libcxx/trunk/include/module.modulemap
>     libcxx/trunk/test/libcxx/double_include.sh.cpp
>     libcxx/trunk/test/support/test_macros.h
>     libcxx/trunk/utils/libcxx/test/config.py
>
> Modified: libcxx/trunk/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/
> CMakeLists.txt?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/CMakeLists.txt (original)
> +++ libcxx/trunk/CMakeLists.txt Wed May 24 23:36:24 2017
> @@ -452,6 +452,11 @@ add_compile_flags_if_supported(-nostdinc
>  # the dylib when get ODR used by another function.
>  add_compile_flags_if_supported(-fvisibility-inlines-hidden)
>
> +if (LIBCXX_CONFIGURE_IDE)
> +  # This simply allows IDE to process <experimental/coroutine>
> +  add_compile_flags_if_supported(-fcoroutines-ts)
> +endif()
> +
>  # Let the library headers know they are currently being used to build the
>  # library.
>  add_definitions(-D_LIBCPP_BUILDING_LIBRARY)
>
> Modified: libcxx/trunk/include/experimental/__config
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/
> experimental/__config?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/experimental/__config (original)
> +++ libcxx/trunk/include/experimental/__config Wed May 24 23:36:24 2017
> @@ -44,6 +44,13 @@
>  #define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM \
>      } } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
>
> +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES \
> +  _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace coroutines_v1 {
> +
> +#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES \
> +  } _LIBCPP_END_NAMESPACE_EXPERIMENTAL
> +
> +#define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1
>
>  #define _VSTD_FS ::std::experimental::filesystem::v1
>
>
> Added: libcxx/trunk/include/experimental/coroutine
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/
> experimental/coroutine?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/include/experimental/coroutine (added)
> +++ libcxx/trunk/include/experimental/coroutine Wed May 24 23:36:24 2017
> @@ -0,0 +1,260 @@
> +// -*- C++ -*-
> +//===----------------------------- coroutine
> -----------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +#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 <typename R, typename... ArgTypes>
> +class coroutine_traits;
> +// 18.11.2 coroutine handle
> +template <typename Promise = void>
> +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 <class T> struct hash;
> +template <class P> struct hash<coroutine_handle<P>>;
> +
> +} // namespace coroutines_v1
> +} // namespace experimental
> +} // namespace std
> +
> + */
> +
> +#include <experimental/__config>
> +#include <new>
> +#include <type_traits>
> +#include <functional>
> +#include <memory> // for hash<T*>
> +#include <cstddef>
> +#include <cassert>
> +#include <__debug>
> +
> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
> +#pragma GCC system_header
> +#endif
> +
> +#ifndef __cpp_coroutines
> +# if defined(_LIBCPP_WARNING)
> +    _LIBCPP_WARNING("<experimental/coroutine> cannot be used with this
> compiler")
> +# else
> +#   warning <experimental/coroutine> cannot be used with this compiler
> +# endif
> +#endif
> +
> +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES
> +
> +template <class _Tp, class = void>
> +struct __coroutine_traits_sfinae {};
> +
> +template <class _Tp>
> +struct __coroutine_traits_sfinae<
> +    _Tp, typename __void_t<typename _Tp::promise_type>::type>
> +{
> +  using promise_type = typename _Tp::promise_type;
> +};
> +
> +template <typename _Ret, typename... _Args>
> +struct _LIBCPP_TEMPLATE_VIS coroutine_traits
> +    : public __coroutine_traits_sfinae<_Ret>
> +{
> +};
> +
> +template <typename Promise = void>
>

This Promise needs more _Uglifying.


> +class _LIBCPP_TEMPLATE_VIS coroutine_handle;
> +
> +#if defined(__cpp_coroutines)
> +
> +template <>
> +class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
> +public:
> +    _LIBCPP_ALWAYS_INLINE
> +    constexpr coroutine_handle() noexcept : __handle_(nullptr) {}
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    constexpr coroutine_handle(nullptr_t) noexcept : __handle_(nullptr) {}
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    coroutine_handle& operator=(nullptr_t) noexcept {
> +        __handle_ = nullptr;
> +        return *this;
> +    }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    constexpr void* address() const noexcept { return __handle_; }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    constexpr explicit operator bool() const noexcept { return __handle_;
> }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    void operator()() const { resume(); }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    void resume() const {
> +      _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_ALWAYS_INLINE
> +    void destroy() const {
> +      _LIBCPP_ASSERT(__is_suspended(),
> +                     "destroy() can only be called on suspended
> coroutines");
> +      __builtin_coro_destroy(__handle_);
> +    }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    bool done() const {
> +      _LIBCPP_ASSERT(__is_suspended(),
> +                     "done() can only be called on suspended coroutines");
> +      return __builtin_coro_done(__handle_);
> +    }
> +
> +public:
> +    _LIBCPP_ALWAYS_INLINE
> +    static coroutine_handle from_address(void* __addr) noexcept {
> +        coroutine_handle __tmp;
> +        __tmp.__handle_ = __addr;
> +        return __tmp;
> +    }
> +
> +private:
> +  bool __is_suspended() const noexcept  {
> +    // FIXME actually implement a check for if the coro is suspended.
> +    return __handle_;
> +  }
> +
> +  template <class _PromiseT> friend class coroutine_handle;
> +  void* __handle_;
> +};
> +
> +// 18.11.2.7 comparison operators:
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return __x.address() == __y.address();
> +}
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return !(__x == __y);
> +}
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return less<void*>()(__x.address(), __y.address());
> +}
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return __y < __x;
> +}
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return !(__x > __y);
> +}
> +inline _LIBCPP_ALWAYS_INLINE
> +bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
> +    return !(__x < __y);
> +}
> +
> +template <typename _Promise>
> +class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> {
> +    using _Base = coroutine_handle<>;
> +public:
> +    // 18.11.2.1 construct/reset
> +    using coroutine_handle<>::coroutine_handle;
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    coroutine_handle& operator=(nullptr_t) noexcept {
> +        _Base::operator=(nullptr);
> +        return *this;
> +    }
> +
> +  _LIBCPP_INLINE_VISIBILITY
> +    _Promise& promise() {
> +        return *reinterpret_cast<_Promise*>(
> +            __builtin_coro_promise(this->__handle_, alignof(_Promise),
> false));
> +    }
> +
> +    _LIBCPP_INLINE_VISIBILITY
> +    _Promise const& promise() const {
> +        return *reinterpret_cast<_Promise const*>(
> +            __builtin_coro_promise(this->__handle_, alignof(_Promise),
> false));
> +    }
> +
> +public:
> +    _LIBCPP_ALWAYS_INLINE
> +    static coroutine_handle from_address(void* __addr) noexcept {
> +        coroutine_handle __tmp;
> +        __tmp.__handle_ = __addr;
> +        return __tmp;
> +    }
> +
> +    _LIBCPP_ALWAYS_INLINE
> +    static coroutine_handle from_promise(_Promise& __promise) noexcept {
> +        coroutine_handle __tmp;
> +        __tmp.__handle_ = __builtin_coro_promise(_VSTD::
> addressof(__promise),
> +                                                 alignof(_Promise), true);
> +        return __tmp;
> +    }
> +};
> +
> +#endif // defined(__cpp_coroutines)
> +
> +struct _LIBCPP_TYPE_VIS suspend_never {
> +  _LIBCPP_ALWAYS_INLINE
> +  bool await_ready() const noexcept { return true; }
> +  _LIBCPP_ALWAYS_INLINE
> +  void await_suspend(coroutine_handle<>) const noexcept {}
> +  _LIBCPP_ALWAYS_INLINE
> +  void await_resume() const noexcept {}
> +};
> +
> +struct _LIBCPP_TYPE_VIS suspend_always {
> +  _LIBCPP_ALWAYS_INLINE
> +  bool await_ready() const noexcept { return false; }
> +  _LIBCPP_ALWAYS_INLINE
> +  void await_suspend(coroutine_handle<>) const noexcept {}
> +  _LIBCPP_ALWAYS_INLINE
> +  void await_resume() const noexcept {}
> +};
> +
> +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES
> +
> +_LIBCPP_BEGIN_NAMESPACE_STD
> +
> +template <class _Tp>
> +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<void*>{}(__v.address());}
> +};
> +
> +_LIBCPP_END_NAMESPACE_STD
> +
> +#endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */
>
> Modified: libcxx/trunk/include/module.modulemap
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/
> module.modulemap?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/module.modulemap (original)
> +++ libcxx/trunk/include/module.modulemap Wed May 24 23:36:24 2017
> @@ -501,6 +501,10 @@ module std [system] {
>        header "experimental/chrono"
>        export *
>      }
> +    module coroutine {
> +      header "experimental/coroutine"
> +      export *
> +    }
>      module deque {
>        header "experimental/deque"
>        export *
>
> Modified: libcxx/trunk/test/libcxx/double_include.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/
> libcxx/double_include.sh.cpp?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/double_include.sh.cpp (original)
> +++ libcxx/trunk/test/libcxx/double_include.sh.cpp Wed May 24 23:36:24
> 2017
> @@ -137,6 +137,9 @@
>  #include <experimental/algorithm>
>  #include <experimental/any>
>  #include <experimental/chrono>
> +#if defined(__cpp_coroutines)
> +#include <experimental/coroutine>
> +#endif
>  #include <experimental/deque>
>  #include <experimental/dynarray>
>  #include <experimental/filesystem>
>
> Added: libcxx/trunk/test/libcxx/experimental/language.support/
> support.coroutines/version.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/
> libcxx/experimental/language.support/support.coroutines/
> version.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/libcxx/experimental/language.support/
> support.coroutines/version.sh.cpp (added)
> +++ libcxx/trunk/test/libcxx/experimental/language.support/
> support.coroutines/version.sh.cpp Wed May 24 23:36:24 2017
> @@ -0,0 +1,25 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +#include <experimental/coroutine>
> +
> +#ifndef _LIBCPP_VERSION
> +#error _LIBCPP_VERSION must be defined
> +#endif
> +
> +int main()
> +{
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> capacity/operator_bool.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.capacity/operator_bool.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.capacity/operator_bool.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,62 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// constexpr explicit operator bool() const noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test() {
> +  static_assert(std::is_nothrow_constructible<bool, C>::value, "");
> +  static_assert(!std::is_convertible<C, bool>::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
> +    int dummy = 42;
> +    C c = C::from_address(&dummy);
> +    assert(c.address() == &dummy);
> +    assert(bool(c) == true);
> +  }
> +}
> +
> +int main()
> +{
> +  do_test<coro::coroutine_handle<>>();
> +  do_test<coro::coroutine_handle<int>>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> compare/equal_comp.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.compare/equal_comp.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.compare/equal_comp.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,64 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// bool operator==(coroutine_handle<>, coroutine_handle<>) noexcept
> +// bool operator!=(coroutine_handle<>, coroutine_handle<>) noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
> +  const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
> +  const C RHS = C::from_address(reinterpret_cast<void*>(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()
> +{
> +  std::pair<uintptr_t, uintptr_t> const TestCases[] = {
> +      {0, 0},
> +      {16, 16},
> +      {0, 16},
> +      {16, 0}
> +  };
> +  for (auto& TC : TestCases) {
> +    do_test<coro::coroutine_handle<>>(TC.first, TC.second);
> +    do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> compare/less_comp.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.compare/less_comp.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.compare/less_comp.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,73 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// 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 <experimental/coroutine>
> +#include <type_traits>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
> +  const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
> +  const C RHS = C::from_address(reinterpret_cast<void*>(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()
> +{
> +  std::pair<uintptr_t, uintptr_t> const TestCases[] = {
> +      {0, 0},
> +      {16, 16},
> +      {0, 16},
> +      {16, 0}
> +  };
> +  for (auto& TC : TestCases) {
> +    do_test<coro::coroutine_handle<>>(TC.first, TC.second);
> +    do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> completion/done.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.completion/done.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.completion/done.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,48 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// bool done() const
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <memory>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class Promise>
> +void do_test(coro::coroutine_handle<Promise> const& H) {
> +  // FIXME Add a runtime test
> +  {
> +    ASSERT_SAME_TYPE(decltype(H.done()), bool);
> +    ASSERT_NOT_NOEXCEPT(H.done());
> +  }
> +}
> +
> +int main()
> +{
> +  do_test(coro::coroutine_handle<>{});
> +  do_test(coro::coroutine_handle<int>{});
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.con/assign.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/assign.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,58 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// coroutine_handle& operator=(nullptr_t) noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test() {
> +  int dummy = 42;
> +  void* dummy_h = &dummy;
> +  {
> +    C c; ((void)c);
> +    static_assert(std::is_nothrow_assignable<C&, std::nullptr_t>::value,
> "");
> +    static_assert(!std::is_assignable<C&, void*>::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()
> +{
> +  do_test<coro::coroutine_handle<>>();
> +  do_test<coro::coroutine_handle<int>>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.con/construct.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.con/construct.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,57 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// constexpr coroutine_handle() noexcept
> +// constexpr coroutine_handle(nullptr_t) noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test() {
> +  {
> +    constexpr C c;
> +    static_assert(std::is_nothrow_default_constructible<C>::value, "");
> +    static_assert(c.address() == nullptr, "");
> +  }
> +  {
> +    constexpr C c(nullptr);
> +    static_assert(std::is_nothrow_constructible<C,
> std::nullptr_t>::value, "");
> +    static_assert(c.address() == nullptr, "");
> +  }
> +  {
> +    C c;
> +    assert(c.address() == nullptr);
> +  }
> +  {
> +    C c(nullptr);
> +    assert(c.address() == nullptr);
> +  }
> +}
> +
> +int main()
> +{
> +  do_test<coro::coroutine_handle<>>();
> +  do_test<coro::coroutine_handle<int>>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.export/address.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/address.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,55 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// constexpr void* address() const noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +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);
> +  }
> +  {
> +    int dummy = 42;
> +    C c = C::from_address(&dummy);
> +    assert(c.address() == &dummy);
> +  }
> +}
> +
> +int main()
> +{
> +  do_test<coro::coroutine_handle<>>();
> +  do_test<coro::coroutine_handle<int>>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> export/from_address.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.export/from_address.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.export/from_address.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,50 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// static coroutine_handle from_address(void*) noexcept
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +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<decltype(C::from_address(nullptr)),
> C>::value, "");
> +    assert(c.address() == nullptr);
> +  }
> +  {
> +    int dummy = 42;
> +    C c = C::from_address(&dummy);
> +    assert(c.address() == &dummy);
> +  }
> +}
> +
> +int main()
> +{
> +  do_test<coro::coroutine_handle<>>();
> +  do_test<coro::coroutine_handle<int>>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.hash/hash.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.hash/hash.sh.cpp Wed
> May 24 23:36:24 2017
> @@ -0,0 +1,67 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// namespace std {
> +//  template <class P> struct hash<experimental::coroutine_handle<P>>;
> +// }
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <memory>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class C>
> +void do_test(uintptr_t LHSVal, uintptr_t RHSVal) {
> +  const size_t ExpectLHS = std::hash<void*>{}(reinterpret_cast<void*>(
> LHSVal));
> +  const size_t ExpectRHS = std::hash<void*>{}(reinterpret_cast<void*>(
> RHSVal));
> +  const C LHS = C::from_address(reinterpret_cast<void*>(LHSVal));
> +  const C RHS = C::from_address(reinterpret_cast<void*>(RHSVal));
> +  const std::hash<C> 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<C>{}(LHS));
> +  }
> +}
> +
> +int main()
> +{
> +  std::pair<uintptr_t, uintptr_t> const TestCases[] = {
> +      {0, 0},
> +      {0, 8},
> +      {8, 8},
> +      {8, 16}
> +  };
> +  for (auto& TC : TestCases) {
> +    do_test<coro::coroutine_handle<>>(TC.first, TC.second);
> +    do_test<coro::coroutine_handle<int>>(TC.first, TC.second);
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.prom/promise.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.prom/promise.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,54 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise>
> +// struct coroutine_handle<Promise>;
> +
> +// Promise& promise()
> +// Promise const& promise() const
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <memory>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class Promise>
> +void do_test(coro::coroutine_handle<Promise>&& H) {
> +
> +  // FIXME Add a runtime test
> +  {
> +    ASSERT_SAME_TYPE(decltype(H.promise()), Promise&);
> +    ASSERT_NOT_NOEXCEPT(H.promise());
> +  }
> +  {
> +    auto const& CH = H;
> +    ASSERT_SAME_TYPE(decltype(CH.promise()), Promise const&);
> +    ASSERT_NOT_NOEXCEPT(CH.promise());
> +  }
> +}
> +
> +int main()
> +{
> +  do_test(coro::coroutine_handle<int>{});
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> resumption/destroy.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.resumption/destroy.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.resumption/destroy.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,48 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// void destroy() const
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <memory>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class Promise>
> +void do_test(coro::coroutine_handle<Promise> const& H) {
> +  // FIXME Add a runtime test
> +  {
> +    ASSERT_SAME_TYPE(decltype(H.destroy()), void);
> +    ASSERT_NOT_NOEXCEPT(H.destroy());
> +  }
> +}
> +
> +int main()
> +{
> +  do_test(coro::coroutine_handle<>{});
> +  do_test(coro::coroutine_handle<int>{});
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.
> resumption/resume.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/coroutine.handle.resumption/resume.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/coroutine.handle.resumption/resume.sh.cpp
> Wed May 24 23:36:24 2017
> @@ -0,0 +1,51 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// template <class Promise = void>
> +// struct coroutine_handle;
> +
> +// void operator()() const
> +// void resume() const
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <memory>
> +#include <utility>
> +#include <cstdint>
> +#include <cassert>
> +
> +#include "test_macros.h"
> +
> +namespace coro = std::experimental;
> +
> +template <class Promise>
> +void do_test(coro::coroutine_handle<Promise> const& H) {
> +  // 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());
> +  }
> +}
> +
> +int main()
> +{
> +  do_test(coro::coroutine_handle<>{});
> +  do_test(coro::coroutine_handle<int>{});
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/void_handle.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> handle/void_handle.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/void_handle.sh.cpp (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.handle/void_handle.sh.cpp Wed May 24
> 23:36:24 2017
> @@ -0,0 +1,55 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +#include <experimental/coroutine>
> +
> +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 <class ...Args>
> +  struct coroutine_traits<::B, Args...> {
> +    using promise_type = B*;
> +  };
> +  template <>
> +  struct coroutine_traits<::C> {
> +    using promise_type = void;
> +  };
> +}}
> +
> +template <class Expect, class T, class ...Args>
> +void check_type() {
> +  using P = typename coro::coroutine_traits<T, Args...>::promise_type ;
> +  static_assert(std::is_same<P, Expect>::value, "");
> +};
> +
> +int main()
> +{
> +  check_type<A*, A>();
> +  check_type<int*, A, int>();
> +  check_type<B*, B>();
> +  check_type<void, C>();
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.traits/promise_type.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> traits/promise_type.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.traits/promise_type.sh.cpp (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.traits/promise_type.sh.cpp Wed May 24
> 23:36:24 2017
> @@ -0,0 +1,81 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +#include <experimental/coroutine>
> +
> +namespace coro = std::experimental;
> +
> +template <class T, class = typename T::promise_type>
> +constexpr bool has_promise_type(int) { return true; }
> +template <class>
> +constexpr bool has_promise_type(long) { return false; }
> +template <class T>
> +constexpr bool has_promise_type() { return has_promise_type<T>(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 <class ...Args>
> +  struct coroutine_traits<::B, Args...> {
> +    using promise_type = B*;
> +  };
> +  template <>
> +  struct coroutine_traits<::C> {
> +    using promise_type = void;
> +  };
> +}}
> +
> +template <class Expect, class T, class ...Args>
> +void check_type() {
> +  using Traits = coro::coroutine_traits<T, Args...>;
> +  static_assert(has_promise_type<Traits>(), "");
> +  static_assert(std::is_same<typename Traits::promise_type,
> Expect>::value, "");
> +}
> +
> +template <class T, class ...Args>
> +void check_no_type() {
> +  using Traits = coro::coroutine_traits<T, Args...>;
> +  static_assert(!has_promise_type<Traits>(), "");
> +}
> +
> +int main()
> +{
> +  {
> +    check_type<A*, A>();
> +    check_type<int*, A, int>();
> +    check_type<B*, B>();
> +    check_type<void, C>();
> +  }
> +  {
> +    check_no_type<D>();
> +    check_no_type<E>();
> +    check_no_type<C, int>();
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> trivial.awaitables/suspend_always.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_always.sh.cpp Wed
> May 24 23:36:24 2017
> @@ -0,0 +1,73 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +#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()
> +{
> +  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<decltype(s.await_ready()), bool>::value,
> "");
> +    assert(s.await_ready() == false);
> +    assert(cs.await_ready() == false);
> +  }
> +  {
> +    LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), "");
> +    static_assert(std::is_same<decltype(s.await_suspend(h)),
> void>::value, "");
> +    s.await_suspend(h);
> +    cs.await_suspend(h);
> +  }
> +  {
> +    LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), "");
> +    static_assert(std::is_same<decltype(s.await_resume()), void>::value,
> "");
> +    s.await_resume();
> +    cs.await_resume();
> +  }
> +  {
> +    static_assert(std::is_nothrow_default_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_copy_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_move_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_copy_assignable<S>::value, "");
> +    static_assert(std::is_nothrow_move_assignable<S>::value, "");
> +    static_assert(std::is_trivially_copyable<S>::value, "");
> +    static_assert(check_suspend_constexpr(), "");
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/coroutine.
> trivial.awaitables/suspend_never.sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp
> (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/coroutine.trivial.awaitables/suspend_never.sh.cpp Wed
> May 24 23:36:24 2017
> @@ -0,0 +1,75 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +#include <experimental/coroutine>
> +#include <type_traits>
> +#include <cassert>
> +
> +#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()
> +{
> +  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<decltype(s.await_ready()), bool>::value,
> "");
> +    assert(s.await_ready() == true);
> +    assert(cs.await_ready() == true);
> +  }
> +  {
> +    LIBCPP_STATIC_ASSERT(noexcept(s.await_suspend(h)), "");
> +    static_assert(std::is_same<decltype(s.await_suspend(h)),
> void>::value, "");
> +    s.await_suspend(h);
> +    cs.await_suspend(h);
> +  }
> +  {
> +    LIBCPP_STATIC_ASSERT(noexcept(s.await_resume()), "");
> +    static_assert(std::is_same<decltype(s.await_resume()), void>::value,
> "");
> +    s.await_resume();
> +    cs.await_resume();
> +  }
> +  {
> +    static_assert(std::is_nothrow_default_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_copy_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_move_constructible<S>::value, "");
> +    static_assert(std::is_nothrow_copy_assignable<S>::value, "");
> +    static_assert(std::is_nothrow_move_assignable<S>::value, "");
> +    static_assert(std::is_trivially_copyable<S>::value, "");
> +    static_assert(check_suspend_constexpr(), "");
> +  }
> +}
>
> Added: libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/includes.sh.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> experimental/language.support/support.coroutines/includes.
> sh.cpp?rev=303836&view=auto
> ============================================================
> ==================
> --- libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/includes.sh.cpp (added)
> +++ libcxx/trunk/test/std/experimental/language.support/
> support.coroutines/includes.sh.cpp Wed May 24 23:36:24 2017
> @@ -0,0 +1,31 @@
> +// -*- C++ -*-
> +//===------------------------------------------------------
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is dual licensed under the MIT and the University of
> Illinois Open
> +// Source Licenses. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +
> +// UNSUPPORTED: c++98, c++03, c++11
> +// REQUIRES: fcoroutines-ts
> +
> +// RUN: %build -fcoroutines-ts
> +// RUN: %run
> +
> +// <experimental/coroutine>
> +
> +// Test that <experimental/coroutine> includes <new>
> +
> +#include <experimental/coroutine>
> +
> +
> +
> +int main(){
> +  // std::nothrow is not implicitly defined by the compiler when the
> include is
> +  // missing, unlike other parts of <new>. Therefore we use std::nothrow
> to
> +  // test for #include <new>
> +  (void)std::nothrow;
> +
> +}
>
> Modified: libcxx/trunk/test/support/test_macros.h
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/
> support/test_macros.h?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/support/test_macros.h (original)
> +++ libcxx/trunk/test/support/test_macros.h Wed May 24 23:36:24 2017
> @@ -154,6 +154,12 @@
>  #define TEST_NORETURN [[noreturn]]
>  #endif
>
> +#if defined(_LIBCPP_SAFE_STATIC)
> +#define TEST_SAFE_STATIC _LIBCPP_SAFE_STATIC
> +#else
> +#define TEST_SAFE_STATIC
> +#endif
> +
>  #if TEST_STD_VER < 11
>  #define ASSERT_NOEXCEPT(...)
>  #define ASSERT_NOT_NOEXCEPT(...)
>
> Modified: libcxx/trunk/utils/libcxx/test/config.py
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/
> libcxx/test/config.py?rev=303836&r1=303835&r2=303836&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/utils/libcxx/test/config.py (original)
> +++ libcxx/trunk/utils/libcxx/test/config.py Wed May 24 23:36:24 2017
> @@ -142,6 +142,7 @@ class Configuration(object):
>          self.configure_sanitizer()
>          self.configure_coverage()
>          self.configure_modules()
> +        self.configure_coroutines()
>          self.configure_substitutions()
>          self.configure_features()
>
> @@ -954,6 +955,10 @@ class Configuration(object):
>              self.cxx.flags += ['-g', '--coverage']
>              self.cxx.compile_flags += ['-O0']
>
> +    def configure_coroutines(self):
> +        if self.cxx.hasCompileFlag('-fcoroutines-ts'):
> +            self.config.available_features.add('fcoroutines-ts')
> +
>      def configure_modules(self):
>          modules_flags = ['-fmodules']
>          if platform.system() != 'Darwin':
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170525/48fa8ac6/attachment-0001.html>


More information about the cfe-commits mailing list