--- a/common/tool/tool_manager.cpp
+++ b/common/tool/tool_manager.cpp
@@ -532,11 +532,11 @@
                     if( st->cofunc )
                         st->Push();
 
+                    st->cofunc = new COROUTINE<int, const TOOL_EVENT&>( tr.second );
+
                     // as the state changes, the transition table has to be set up again
                     st->transitions.clear();
 
-                    st->cofunc = new COROUTINE<int, const TOOL_EVENT&>( tr.second );
-
                     // got match? Run the handler.
                     st->cofunc->Call( aEvent );
 
--- a/include/tool/coroutine.h
+++ b/include/tool/coroutine.h
@@ -27,10 +28,15 @@
 
 #include <cstdlib>
 
-#include <boost/context/fcontext.hpp>
 #include <boost/version.hpp>
+#include <type_traits>
 
-#include "delegate.h"
+#if BOOST_VERSION <= 106000
+#include <boost/context/fcontext.hpp>
+#else
+#include <boost/context/execution_context.hpp>
+#include <boost/context/protected_fixedsize_stack.hpp>
+#endif
 
 /**
  *  Class COROUNTINE.
@@ -53,13 +59,12 @@
  *  See coroutine_example.cpp for sample code.
  */
 
-template <class ReturnType, class ArgType>
+template <typename ReturnType, typename ArgType>
 class COROUTINE
 {
 public:
     COROUTINE() :
-        m_saved( NULL ), m_self( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize ),
-        m_running( false )
+        COROUTINE( nullptr )
     {
     }
 
@@ -69,8 +74,7 @@
      */
     template <class T>
     COROUTINE( T* object, ReturnType(T::* ptr)( ArgType ) ) :
-        m_func( object, ptr ), m_self( NULL ), m_saved( NULL ), m_stack( NULL ),
-        m_stackSize( c_defaultStackSize ), m_running( false )
+        COROUTINE( std::bind( ptr, object, std::placeholders::_1 ) )
     {
     }
 
@@ -78,9 +82,15 @@
      * Constructor
      * Creates a coroutine from a delegate object
      */
-    COROUTINE( DELEGATE<ReturnType, ArgType> aEntry ) :
-        m_func( aEntry ), m_saved( NULL ), m_self( NULL ), m_stack( NULL ),
-        m_stackSize( c_defaultStackSize ), m_running( false )
+    COROUTINE( std::function<ReturnType(ArgType)> aEntry ) :
+        m_func( std::move( aEntry ) ),
+        m_running( false ),
+#if BOOST_VERSION <= 106000
+        m_stack( nullptr ),
+        m_stackSize( c_defaultStackSize ),
+#endif
+        m_caller( nullptr ),
+        m_callee( nullptr )
     {
         // Avoid not initialized members, and make static analysers quiet
         m_args = 0;
@@ -89,18 +99,26 @@
 
     ~COROUTINE()
     {
-        if( m_saved )
-            delete m_saved;
-
 #if BOOST_VERSION >= 105600
-        if( m_self )
-            delete m_self;
+        delete m_callee;
 #endif
 
+#if BOOST_VERSION <= 106000
+        delete m_caller;
+
         if( m_stack )
             free( m_stack );
+#endif
     }
 
+private:
+#if BOOST_VERSION <= 106000
+    using context_type = boost::context::fcontext_t;
+#else
+    using context_type = boost::context::execution_context<COROUTINE*>;
+#endif
+
+public:
     /**
      * Function Yield()
      *
@@ -110,7 +128,12 @@
      */
     void Yield()
     {
-        jump( m_self, m_saved, 0 );
+#if BOOST_VERSION <= 106000
+        jump( m_callee, m_caller, false );
+#else
+        auto result = (*m_caller)( this );
+        *m_caller = std::move( std::get<0>( result ) );
+#endif
     }
 
     /**
@@ -122,7 +145,11 @@
     void Yield( ReturnType& aRetVal )
     {
         m_retVal = aRetVal;
-        jump( m_self, m_saved, 0 );
+#if BOOST_VERSION <= 106000
+        jump( m_callee, m_caller, false );
+#else
+        m_caller( this );
+#endif
     }
 
     /**
@@ -130,9 +157,9 @@
      *
      * Defines the entry point for the coroutine, if not set in the constructor.
      */
-    void SetEntry( DELEGATE<ReturnType, ArgType> aEntry )
+    void SetEntry( std::function<ReturnType(ArgType)> aEntry )
     {
-        m_func = aEntry;
+        m_func = std::move( aEntry );
     }
 
     /* Function Call()
@@ -143,6 +170,10 @@
      */
     bool Call( ArgType aArgs )
     {
+        assert( m_callee == NULL );
+        assert( m_caller == NULL );
+
+#if BOOST_VERSION <= 106000
         // fixme: Clean up stack stuff. Add a guard
         m_stack = malloc( c_defaultStackSize );
 
@@ -151,22 +182,32 @@
 
         // correct the stack size
         m_stackSize -= ( (size_t) m_stack + m_stackSize - (size_t) sp );
-
-        assert( m_self == NULL );
-        assert( m_saved == NULL );
+#endif
 
         m_args = &aArgs;
-#if BOOST_VERSION >= 105600
-        m_self = new boost::context::fcontext_t();
-        *m_self = boost::context::make_fcontext( sp, m_stackSize, callerStub );
+
+#if BOOST_VERSION < 105600
+        m_callee = boost::context::make_fcontext( sp, m_stackSize, callerStub );
+#elif BOOST_VERSION <= 106000
+        m_callee = new context_type( boost::context::make_fcontext( sp, m_stackSize, callerStub ) );
 #else
-        m_self = boost::context::make_fcontext( sp, m_stackSize, callerStub );
+        m_callee = new context_type( std::allocator_arg_t(),
+                    boost::context::protected_fixedsize_stack( c_defaultStackSize ), &COROUTINE::callerStub );
+#endif
+
+#if BOOST_VERSION <= 106000
+        m_caller = new context_type();
 #endif
-        m_saved = new boost::context::fcontext_t();
 
         m_running = true;
+
         // off we go!
-        jump( m_saved, m_self, reinterpret_cast<intptr_t>( this ) );
+#if BOOST_VERSION <= 106000
+        jump( m_caller, m_callee, reinterpret_cast<intptr_t>( this ) );
+#else
+        auto result = (*m_callee)( this );
+        *m_callee = std::move( std::get<0>( result ) );
+#endif
         return m_running;
     }
 
@@ -179,7 +220,12 @@
      */
     bool Resume()
     {
-        jump( m_saved, m_self, 0 );
+#if BOOST_VERSION <= 106000
+        jump( m_caller, m_callee, false );
+#else
+        auto result = (*m_callee)( this );
+        *m_callee = std::move( std::get<0>( result ) );
+#endif
 
         return m_running;
     }
@@ -208,61 +254,66 @@
     static const int c_defaultStackSize = 2000000;    // fixme: make configurable
 
     /* real entry point of the coroutine */
+#if BOOST_VERSION <= 106000
     static void callerStub( intptr_t aData )
+#else
+    static context_type callerStub( context_type caller, COROUTINE* cor )
+#endif
     {
         // get pointer to self
+#if BOOST_VERSION <= 106000
         COROUTINE<ReturnType, ArgType>* cor = reinterpret_cast<COROUTINE<ReturnType, ArgType>*>( aData );
+#else
+        cor->m_caller = &caller;
+#endif
 
         // call the coroutine method
-        cor->m_retVal = cor->m_func( *cor->m_args );
+        cor->m_retVal = cor->m_func( *( cor->m_args ) );
         cor->m_running = false;
 
         // go back to wherever we came from.
-        jump( cor->m_self, cor->m_saved, 0 );    // reinterpret_cast<intptr_t>( this ));
+#if BOOST_VERSION <= 106000
+        jump( cor->m_callee, cor->m_caller, 0 );
+#else
+        return caller;
+#endif
     }
 
     ///> Wrapper for jump_fcontext to assure compatibility between different boost versions
-    static inline intptr_t jump(boost::context::fcontext_t* aOld, boost::context::fcontext_t* aNew,
+#if BOOST_VERSION <= 106000
+    static inline intptr_t jump( context_type* aOld, context_type* aNew,
                                 intptr_t aP, bool aPreserveFPU = true )
     {
-#if BOOST_VERSION >= 105600
-        return boost::context::jump_fcontext( aOld, *aNew, aP, aPreserveFPU );
-#else
+#if BOOST_VERSION < 105600
         return boost::context::jump_fcontext( aOld, aNew, aP, aPreserveFPU );
+#else
+        return boost::context::jump_fcontext( aOld, *aNew, aP, aPreserveFPU );
 #endif
     }
+#endif
 
-    template <typename T>
-    struct strip_ref
-    {
-        typedef T result;
-    };
+    std::function<ReturnType(ArgType)> m_func;
 
-    template <typename T>
-    struct strip_ref<T&>
-    {
-        typedef T result;
-    };
+    bool m_running;
 
-    DELEGATE<ReturnType, ArgType> m_func;
+#if BOOST_VERSION <= 106000
+    ///< coroutine stack
+    void* m_stack;
+
+    size_t m_stackSize;
+#endif
 
     ///< pointer to coroutine entry arguments. Stripped of references
     ///< to avoid compiler errors.
-    typename strip_ref<ArgType>::result* m_args;
+    typename std::remove_reference<ArgType>::type* m_args;
+
     ReturnType m_retVal;
 
     ///< saved caller context
-    boost::context::fcontext_t* m_saved;
+    context_type* m_caller;
 
     ///< saved coroutine context
-    boost::context::fcontext_t* m_self;
-
-    ///< coroutine stack
-    void* m_stack;
-
-    size_t m_stackSize;
-
-    bool m_running;
+    context_type* m_callee;
 };
 
 #endif
--- a/include/tool/tool_base.h
+++ b/include/tool/tool_base.h
@@ -31,7 +32,7 @@
 #include <tool/tool_event.h>
 #include <tool/tool_settings.h>
 
-#include <tool/delegate.h>
+#include <functional>
 
 class EDA_ITEM;
 class TOOL_MANAGER;
@@ -53,7 +54,9 @@
 
 /// Unique identifier for tools
 typedef int TOOL_ID;
-typedef DELEGATE<int, const TOOL_EVENT&> TOOL_STATE_FUNC;
+
+using TOOL_STATE_FUNC = std::function<int(const TOOL_EVENT&)>;
+
 
 /**
  * Class TOOL_BASE
--- a/include/tool/tool_interactive.h
+++ b/include/tool/tool_interactive.h
@@ -113,7 +114,7 @@
 void TOOL_INTERACTIVE::Go( int (T::* aStateFunc)( const TOOL_EVENT& ),
                            const TOOL_EVENT_LIST& aConditions )
 {
-    TOOL_STATE_FUNC sptr( static_cast<T*>( this ), aStateFunc );
+    TOOL_STATE_FUNC sptr = std::bind( aStateFunc, static_cast<T*>( this ), std::placeholders::_1 );
 
     goInternal( sptr, aConditions );
 }

