[libcxx] r303836 - Add <experimental/coroutine>

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Wed May 24 21:36:24 PDT 2017


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>
+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':




More information about the cfe-commits mailing list