#pragma once #include #include #include #include namespace fc { struct context; class spin_lock; class task_base : virtual public promise_base { public: void run(); protected: ~task_base(); uint64_t _posted_num; priority _prio; time_point _when; void _set_active_context(context*); context* _active_context; task_base* _next; task_base(void* func); // opaque internal / private data used by // thread/thread_private friend class thread; friend class thread_d; fwd _spinlock; // avoid rtti info for every possible functor... void* _promise_impl; void* _functor; void (*_destroy_functor)(void*); void (*_run_functor)(void*, void* ); }; namespace detail { template struct functor_destructor { static void destroy( void* v ) { ((T*)v)->~T(); } }; template struct functor_run { static void run( void* functor, void* prom ) { ((promise*)prom)->set_value( (*((T*)functor))() ); } }; template struct void_functor_run { static void run( void* functor, void* prom ) { (*((T*)functor))(); ((promise*)prom)->set_value(); } }; } template class task : virtual public task_base, virtual public promise { public: template task( Functor&& f ):task_base(&_functor) { typedef typename fc::deduce::type FunctorType; static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" ); new ((char*)&_functor) FunctorType( fc::forward(f) ); _destroy_functor = &detail::functor_destructor::destroy; _promise_impl = static_cast*>(this); _run_functor = &detail::functor_run::run; } aligned _functor; private: ~task(){} }; template class task : virtual public task_base, virtual public promise { public: template task( Functor&& f ):task_base(&_functor) { typedef typename fc::deduce::type FunctorType; static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" ); new ((char*)&_functor) FunctorType( fc::forward(f) ); _destroy_functor = &detail::functor_destructor::destroy; _promise_impl = static_cast*>(this); _run_functor = &detail::void_functor_run::run; } aligned _functor; private: ~task(){} }; }