diff DEPENDENCIES/generic/include/boost/asio/impl/spawn.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/asio/impl/spawn.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,330 @@
+//
+// impl/spawn.hpp
+// ~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 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 BOOST_ASIO_IMPL_SPAWN_HPP
+#define BOOST_ASIO_IMPL_SPAWN_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_cont_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/shared_ptr.hpp>
+#include <boost/asio/handler_type.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+  template <typename Handler, typename T>
+  class coro_handler
+  {
+  public:
+    coro_handler(basic_yield_context<Handler> ctx)
+      : coro_(ctx.coro_.lock()),
+        ca_(ctx.ca_),
+        handler_(ctx.handler_),
+        ec_(ctx.ec_),
+        value_(0)
+    {
+    }
+
+    void operator()(T value)
+    {
+      *ec_ = boost::system::error_code();
+      *value_ = value;
+      (*coro_)();
+    }
+
+    void operator()(boost::system::error_code ec, T value)
+    {
+      *ec_ = ec;
+      *value_ = value;
+      (*coro_)();
+    }
+
+  //private:
+    shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
+    typename basic_yield_context<Handler>::caller_type& ca_;
+    Handler& handler_;
+    boost::system::error_code* ec_;
+    T* value_;
+  };
+
+  template <typename Handler>
+  class coro_handler<Handler, void>
+  {
+  public:
+    coro_handler(basic_yield_context<Handler> ctx)
+      : coro_(ctx.coro_.lock()),
+        ca_(ctx.ca_),
+        handler_(ctx.handler_),
+        ec_(ctx.ec_)
+    {
+    }
+
+    void operator()()
+    {
+      *ec_ = boost::system::error_code();
+      (*coro_)();
+    }
+
+    void operator()(boost::system::error_code ec)
+    {
+      *ec_ = ec;
+      (*coro_)();
+    }
+
+  //private:
+    shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
+    typename basic_yield_context<Handler>::caller_type& ca_;
+    Handler& handler_;
+    boost::system::error_code* ec_;
+  };
+
+  template <typename Handler, typename T>
+  inline void* asio_handler_allocate(std::size_t size,
+      coro_handler<Handler, T>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, this_handler->handler_);
+  }
+
+  template <typename Handler, typename T>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      coro_handler<Handler, T>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, this_handler->handler_);
+  }
+
+  template <typename Handler, typename T>
+  inline bool asio_handler_is_continuation(coro_handler<Handler, T>*)
+  {
+    return true;
+  }
+
+  template <typename Function, typename Handler, typename T>
+  inline void asio_handler_invoke(Function& function,
+      coro_handler<Handler, T>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+  template <typename Function, typename Handler, typename T>
+  inline void asio_handler_invoke(const Function& function,
+      coro_handler<Handler, T>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename Handler, typename ReturnType>
+struct handler_type<basic_yield_context<Handler>, ReturnType()>
+{
+  typedef detail::coro_handler<Handler, void> type;
+};
+
+template <typename Handler, typename ReturnType, typename Arg1>
+struct handler_type<basic_yield_context<Handler>, ReturnType(Arg1)>
+{
+  typedef detail::coro_handler<Handler, Arg1> type;
+};
+
+template <typename Handler, typename ReturnType>
+struct handler_type<basic_yield_context<Handler>,
+    ReturnType(boost::system::error_code)>
+{
+  typedef detail::coro_handler<Handler, void> type;
+};
+
+template <typename Handler, typename ReturnType, typename Arg2>
+struct handler_type<basic_yield_context<Handler>,
+    ReturnType(boost::system::error_code, Arg2)>
+{
+  typedef detail::coro_handler<Handler, Arg2> type;
+};
+
+template <typename Handler, typename T>
+class async_result<detail::coro_handler<Handler, T> >
+{
+public:
+  typedef T type;
+
+  explicit async_result(detail::coro_handler<Handler, T>& h)
+    : ca_(h.ca_)
+  {
+    out_ec_ = h.ec_;
+    if (!out_ec_) h.ec_ = &ec_;
+    h.value_ = &value_;
+  }
+
+  type get()
+  {
+    ca_();
+    if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
+    return value_;
+  }
+
+private:
+  typename basic_yield_context<Handler>::caller_type& ca_;
+  boost::system::error_code* out_ec_;
+  boost::system::error_code ec_;
+  type value_;
+};
+
+template <typename Handler>
+class async_result<detail::coro_handler<Handler, void> >
+{
+public:
+  typedef void type;
+
+  explicit async_result(detail::coro_handler<Handler, void>& h)
+    : ca_(h.ca_)
+  {
+    out_ec_ = h.ec_;
+    if (!out_ec_) h.ec_ = &ec_;
+  }
+
+  void get()
+  {
+    ca_();
+    if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
+  }
+
+private:
+  typename basic_yield_context<Handler>::caller_type& ca_;
+  boost::system::error_code* out_ec_;
+  boost::system::error_code ec_;
+};
+
+namespace detail {
+
+  template <typename Handler, typename Function>
+  struct spawn_data : private noncopyable
+  {
+    spawn_data(BOOST_ASIO_MOVE_ARG(Handler) handler,
+        bool call_handler, BOOST_ASIO_MOVE_ARG(Function) function)
+      : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+        call_handler_(call_handler),
+        function_(BOOST_ASIO_MOVE_CAST(Function)(function))
+    {
+    }
+
+    weak_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
+    Handler handler_;
+    bool call_handler_;
+    Function function_;
+  };
+
+  template <typename Handler, typename Function>
+  struct coro_entry_point
+  {
+    void operator()(typename basic_yield_context<Handler>::caller_type& ca)
+    {
+      shared_ptr<spawn_data<Handler, Function> > data(data_);
+      ca(); // Yield until coroutine pointer has been initialised.
+      const basic_yield_context<Handler> yield(
+          data->coro_, ca, data->handler_);
+      (data->function_)(yield);
+      if (data->call_handler_)
+        (data->handler_)();
+    }
+
+    shared_ptr<spawn_data<Handler, Function> > data_;
+  };
+
+  template <typename Handler, typename Function>
+  struct spawn_helper
+  {
+    void operator()()
+    {
+      typedef typename basic_yield_context<Handler>::callee_type callee_type;
+      coro_entry_point<Handler, Function> entry_point = { data_ };
+      shared_ptr<callee_type> coro(new callee_type(entry_point, attributes_));
+      data_->coro_ = coro;
+      (*coro)();
+    }
+
+    shared_ptr<spawn_data<Handler, Function> > data_;
+    boost::coroutines::attributes attributes_;
+  };
+
+  inline void default_spawn_handler() {}
+
+} // namespace detail
+
+template <typename Handler, typename Function>
+void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler,
+    BOOST_ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  detail::spawn_helper<Handler, Function> helper;
+  helper.data_.reset(
+      new detail::spawn_data<Handler, Function>(
+        BOOST_ASIO_MOVE_CAST(Handler)(handler), true,
+        BOOST_ASIO_MOVE_CAST(Function)(function)));
+  helper.attributes_ = attributes;
+  boost_asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
+}
+
+template <typename Handler, typename Function>
+void spawn(basic_yield_context<Handler> ctx,
+    BOOST_ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  Handler handler(ctx.handler_); // Explicit copy that might be moved from.
+  detail::spawn_helper<Handler, Function> helper;
+  helper.data_.reset(
+      new detail::spawn_data<Handler, Function>(
+        BOOST_ASIO_MOVE_CAST(Handler)(handler), false,
+        BOOST_ASIO_MOVE_CAST(Function)(function)));
+  helper.attributes_ = attributes;
+  boost_asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
+}
+
+template <typename Function>
+void spawn(boost::asio::io_service::strand strand,
+    BOOST_ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  boost::asio::spawn(strand.wrap(&detail::default_spawn_handler),
+      BOOST_ASIO_MOVE_CAST(Function)(function), attributes);
+}
+
+template <typename Function>
+void spawn(boost::asio::io_service& io_service,
+    BOOST_ASIO_MOVE_ARG(Function) function,
+    const boost::coroutines::attributes& attributes)
+{
+  boost::asio::spawn(boost::asio::io_service::strand(io_service),
+      BOOST_ASIO_MOVE_CAST(Function)(function), attributes);
+}
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_SPAWN_HPP