//
// yield
// ~~~~~
// Stackful coroutines / resumable functions.
//
// Copyright (c) 2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef EXECUTORS_EXPERIMENTAL_YIELD_HEADER
#define EXECUTORS_EXPERIMENTAL_YIELD_HEADER

#include <memory>
#include <system_error>
#include <experimental/executor>
#include <experimental/type_traits>

namespace std {
namespace experimental {
inline namespace concurrency_v1 {

struct __yield_context_caller;
struct __yield_context_callee;

// Context object used to represent the currently executing coroutine.

template <class _Executor>
class basic_yield_context
{
public:
  typedef _Executor executor_type;

  // construct / copy / destroy:

  template <class _OtherExecutor>
    basic_yield_context(const basic_yield_context<_OtherExecutor>&);

  // basic_yield_context operations:

  executor_type get_executor() const noexcept;
  basic_yield_context operator[](error_code& __ec) const;

private:
  template <class> friend class basic_yield_context;
  template <class, class...> friend struct __yield_context_handler;
  template <class, class, class, class...> friend struct __yield_context_entry_point;

  basic_yield_context(const _Executor& __e) : _M_executor(__e), _M_error_code(nullptr) {}

  _Executor _M_executor;
  weak_ptr<__yield_context_callee> _M_callee;
  __yield_context_caller* _M_caller;
  error_code* _M_error_code;
};

template <class _Executor, class _R, class... _Args>
  struct handler_type<basic_yield_context<_Executor>, _R(_Args...)>;

typedef basic_yield_context<executor> yield_context;

} // inline namespace concurrency_v1
} // namespace experimental
} // namespace std

#include <experimental/bits/yield_context.h>

#endif
