view gcc/testsuite/g++.dg/coroutines/coro.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
line wrap: on
line source

#if __has_include(<coroutine>)

#include <coroutine>

#  if __clang__
#    include <utility>
#  endif

namespace coro = std;

#elif __has_include(<experimental/coroutine>)

#include <experimental/coroutine>

#  if __clang__
#    include <utility>
#  endif

namespace coro = std::experimental;

#else

#warning "no installed coroutine headers found, using test-suite local one"

/* Dummy version to allow tests without an installed header.  */
#  ifndef __TESTSUITE_CORO_H_n4835
#  define __TESTSUITE_CORO_H_n4835

// Fragments (with short-cuts) to mimic enough of the library header to
// make some progress.

#  if __cpp_coroutines

namespace std {
inline namespace __n4835 {

// 21.11.1 coroutine traits
template<typename _R, typename...> struct coroutine_traits {
  using promise_type = typename _R::promise_type;
};

// 21.11.2  coroutine handle
template <typename Promise = void> struct coroutine_handle;

template <> 
struct coroutine_handle<void> {
  public:
      // 21.11.2.1 construct/reset
  constexpr coroutine_handle () noexcept
    : __fr_ptr (0) {}
  constexpr coroutine_handle (decltype(nullptr) __h) noexcept
    : __fr_ptr (__h) {}
  coroutine_handle &operator= (decltype(nullptr)) noexcept {
    __fr_ptr = nullptr;
    return *this;
  }

  public:
    // 21.11.2.2 export/import
    constexpr void *address () const noexcept { return __fr_ptr; }
    constexpr static coroutine_handle from_address (void *__a) noexcept {
      coroutine_handle __self;
      __self.__fr_ptr = __a;
      return __self;
    }
  public:
      // 21.11.2.3 observers
    constexpr explicit operator bool () const noexcept {
      return bool (__fr_ptr);
    }
    bool done () const noexcept {
      return __builtin_coro_done (__fr_ptr);
    }
      // 21.11.2.4 resumption
    void operator () () const { resume (); }
    void resume () const {
      __builtin_coro_resume (__fr_ptr);
    }
    void destroy () const {
      __builtin_coro_destroy (__fr_ptr);
    }
  protected:
    void *__fr_ptr;
};

template <class _Promise>
struct coroutine_handle : coroutine_handle<> {
  // 21.11.2.1 construct/reset
  using coroutine_handle<>::coroutine_handle;
  static coroutine_handle from_promise(_Promise &p) {
    coroutine_handle __self;
    __self.__fr_ptr = 
      __builtin_coro_promise((char *)&p,  __alignof(_Promise), true);
    return __self;
  }
  coroutine_handle& operator=(decltype(nullptr)) noexcept {
    coroutine_handle<>::operator=(nullptr);
    return *this;
  }
  // 21.11.2.2 export/import
  constexpr static coroutine_handle from_address(void* __a){
    coroutine_handle __self;
    __self.__fr_ptr = __a;
    return __self;
  }
  // 21.11.2.5 promise access
  _Promise& promise() const {
    void * __t = __builtin_coro_promise(this->__fr_ptr,
					__alignof(_Promise), false);
    return *static_cast<_Promise*>(__t);
  }
};

// n4760 - 21.11.5 trivial awaitables

struct suspend_always {
  bool await_ready() { return false; }
  void await_suspend(coroutine_handle<>) {}
  void await_resume() {}
};

struct suspend_never {
  bool await_ready() { return true; }
  void await_suspend(coroutine_handle<>) {}
  void await_resume() {}
};

} // namespace __n4835
} // namespace std

namespace coro = std;

#  else
#    error "coro.h requires support for coroutines, add -fcoroutines"
#  endif
#  endif // __TESTSUITE_CORO_H_n4835

#endif // __has_include(<experimental/coroutine>)

/* just to avoid cluttering dump files. */
extern "C" int puts (const char *);
extern "C" int printf (const char *, ...);

#include <cstdlib> /* for abort () */

#ifndef OUTPUT
#  define PRINT(X)
#  define PRINTF (void)
#else
#  define PRINT(X) puts(X)
#  define PRINTF printf
#endif