Support both boost.coroutine v1 and v2.
diff --git a/asio/include/asio/impl/spawn.hpp b/asio/include/asio/impl/spawn.hpp
index 142defb..a9f79bd 100644
--- a/asio/include/asio/impl/spawn.hpp
+++ b/asio/include/asio/impl/spawn.hpp
@@ -57,8 +57,8 @@
     }
 
   //private:
-    detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
-    boost::coroutines::coroutine<void()>::caller_type& ca_;
+    shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
+    typename basic_yield_context<Handler>::caller_type& ca_;
     Handler& handler_;
     asio::error_code* ec_;
     T* value_;
@@ -89,8 +89,8 @@
     }
 
   //private:
-    detail::shared_ptr<boost::coroutines::coroutine<void()> > coro_;
-    boost::coroutines::coroutine<void()>::caller_type& ca_;
+    shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
+    typename basic_yield_context<Handler>::caller_type& ca_;
     Handler& handler_;
     asio::error_code* ec_;
   };
@@ -185,7 +185,7 @@
   }
 
 private:
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
+  typename basic_yield_context<Handler>::caller_type& ca_;
   asio::error_code* out_ec_;
   asio::error_code ec_;
   type value_;
@@ -211,7 +211,7 @@
   }
 
 private:
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
+  typename basic_yield_context<Handler>::caller_type& ca_;
   asio::error_code* out_ec_;
   asio::error_code ec_;
 };
@@ -229,7 +229,7 @@
     {
     }
 
-    weak_ptr<boost::coroutines::coroutine<void()> > coro_;
+    weak_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
     Handler handler_;
     bool call_handler_;
     Function function_;
@@ -238,7 +238,7 @@
   template <typename Handler, typename Function>
   struct coro_entry_point
   {
-    void operator()(boost::coroutines::coroutine<void()>::caller_type& ca)
+    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.
@@ -257,9 +257,9 @@
   {
     void operator()()
     {
+      typedef typename basic_yield_context<Handler>::callee_type callee_type;
       coro_entry_point<Handler, Function> entry_point = { data_ };
-      shared_ptr<boost::coroutines::coroutine<void()> > coro(
-          new boost::coroutines::coroutine<void()>(entry_point, attributes_));
+      shared_ptr<callee_type> coro(new callee_type(entry_point, attributes_));
       data_->coro_ = coro;
       (*coro)();
     }
diff --git a/asio/include/asio/spawn.hpp b/asio/include/asio/spawn.hpp
index 501e073..4c0512e 100644
--- a/asio/include/asio/spawn.hpp
+++ b/asio/include/asio/spawn.hpp
@@ -48,6 +48,36 @@
 class basic_yield_context
 {
 public:
+  /// The coroutine callee type, used by the implementation.
+  /**
+   * When using Boost.Coroutine v1, this type is:
+   * @code typename coroutine<void()> @endcode
+   * When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
+   * @code push_coroutine<void> @endcode
+   */
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined callee_type;
+#elif defined(BOOST_COROUTINES_UNIDRECT) || defined(BOOST_COROUTINES_V2)
+  typedef boost::coroutines::push_coroutine<void> callee_type;
+#else
+  typedef boost::coroutines::coroutine<void()> callee_type;
+#endif
+  
+  /// The coroutine caller type, used by the implementation.
+  /**
+   * When using Boost.Coroutine v1, this type is:
+   * @code typename coroutine<void()>::caller_type @endcode
+   * When using Boost.Coroutine v2 (unidirectional coroutines), this type is:
+   * @code pull_coroutine<void> @endcode
+   */
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined caller_type;
+#elif defined(BOOST_COROUTINES_UNIDRECT) || defined(BOOST_COROUTINES_V2)
+  typedef boost::coroutines::pull_coroutine<void> caller_type;
+#else
+  typedef boost::coroutines::coroutine<void()>::caller_type caller_type;
+#endif
+
   /// Construct a yield context to represent the specified coroutine.
   /**
    * Most applications do not need to use this constructor. Instead, the
@@ -55,8 +85,8 @@
    * function.
    */
   basic_yield_context(
-      const detail::weak_ptr<boost::coroutines::coroutine<void()> >& coro,
-      boost::coroutines::coroutine<void()>::caller_type& ca, Handler& handler)
+      const detail::weak_ptr<callee_type>& coro,
+      caller_type& ca, Handler& handler)
     : coro_(coro),
       ca_(ca),
       handler_(handler),
@@ -83,7 +113,7 @@
    *   ...
    * } @endcode
    */
-  basic_yield_context operator[](asio::error_code& ec)
+  basic_yield_context operator[](asio::error_code& ec) const
   {
     basic_yield_context tmp(*this);
     tmp.ec_ = &ec;
@@ -93,8 +123,8 @@
 #if defined(GENERATING_DOCUMENTATION)
 private:
 #endif // defined(GENERATING_DOCUMENTATION)
-  detail::weak_ptr<boost::coroutines::coroutine<void()> > coro_;
-  boost::coroutines::coroutine<void()>::caller_type& ca_;
+  detail::weak_ptr<callee_type> coro_;
+  caller_type& ca_;
   Handler& handler_;
   asio::error_code* ec_;
 };