/* Copyright 2017 The MathWorks, Inc. */ #ifndef CPPSHAREDLIB_FUTURE_HPP #define CPPSHAREDLIB_FUTURE_HPP #include #include #include #include namespace matlab { namespace cpplib { class MATLABLibrary; } } namespace matlab { namespace execution { using namespace matlab::cpplib; namespace runtime_future_detail { struct Impl { uint64_t handle; bool state; bool cancelled; bool interrupted; Impl(); Impl(uint64_t aHandle); ~Impl(); }; } template <> class FutureResult>: public std::future>{ public: FutureResult(std::shared_ptr other); FutureResult(std::future>&& rhs); FutureResult(FutureResult>&& rhs); FutureResult>& operator=(FutureResult>&& rhs); FutureResult(); ~FutureResult(); void swap(FutureResult>& rhs); std::unique_ptr get(); SharedFutureResult> share(); bool valid() const; void wait() const; template std::future_status wait_until(const std::chrono::time_point& abs_time) const; template std::future_status wait_for(const std::chrono::duration& rel_time) const; bool cancel(bool allowInterrupt = true); private: FutureResult(std::future>&) = delete; FutureResult(FutureResult&) = delete; FutureResult& operator= (FutureResult&) = delete; std::future> future; std::shared_ptr impl; friend SharedFutureResult>; }; template <> class SharedFutureResult>: public std::shared_future>{ public: SharedFutureResult(); ~SharedFutureResult(); void swap(SharedFutureResult>& rhs); SharedFutureResult(const SharedFutureResult& rhs); SharedFutureResult(SharedFutureResult&& rhs); SharedFutureResult(FutureResult>&& rhs); SharedFutureResult>& operator=(SharedFutureResult>&& rhs); SharedFutureResult>& operator=(const SharedFutureResult>& rhs); const std::unique_ptr& get() const; bool valid() const; void wait() const; template std::future_status wait_until(const std::chrono::time_point& abs_time) const; template std::future_status wait_for(const std::chrono::duration& rel_time) const; bool cancel(bool allowInterrupt = true); private: std::shared_future> sharedFuture; std::shared_ptr impl; }; } } namespace matlab { namespace execution { namespace runtime_future_detail { inline Impl::Impl(uint64_t aHandle) : handle(aHandle), state(true), cancelled(false), interrupted(false) { } inline Impl::Impl() : handle(0), state(true), cancelled(false), interrupted(false) { } inline Impl::~Impl(){ } } inline FutureResult>::FutureResult() : std::future>(), future(), impl() {} inline FutureResult>::FutureResult(std::shared_ptr rhs) : std::future>(), future(), impl(rhs) { } inline void FutureResult>::swap(FutureResult>& rhs) { impl.swap(rhs.impl); std::swap(future, rhs.future); std::swap(*static_cast>*>(this), static_cast>&>(rhs)); } inline FutureResult>::FutureResult(std::future>&& rhs) : std::future>(), future(std::move(rhs)), impl() { } inline FutureResult>::FutureResult(FutureResult>&& rhs) : std::future>(), future(), impl() { swap(rhs); } inline FutureResult>& FutureResult>::operator=(FutureResult>&& rhs) { swap(rhs); return *this; } inline FutureResult>::~FutureResult() { } inline std::unique_ptr FutureResult>::get() { return future.get(); } inline SharedFutureResult> FutureResult>::share() { return SharedFutureResult>(std::move(*this)); } inline bool FutureResult>::valid() const { return future.valid(); } inline void FutureResult>::wait() const { return future.wait(); } template std::future_status FutureResult >::wait_until(const std::chrono::time_point& abs_time) const { return future.wait_until(abs_time); } template std::future_status FutureResult >::wait_for(const std::chrono::duration& rel_time) const { return future.wait_for(rel_time); } inline bool FutureResult >::cancel(bool allowInterrupt) { /*if (allowInterrupt) { std::async(std::launch::async, [this](){ std::unique_ptr enginePtr = future.get(); enginePtr->disconnect(); }); impl->interrupted = true; return true; } impl->interrupted = false; impl->cancelled = false;*/ return false; } inline SharedFutureResult>::SharedFutureResult() : std::shared_future>(), sharedFuture(), impl() { } inline SharedFutureResult>::~SharedFutureResult() { } inline SharedFutureResult>::SharedFutureResult(const SharedFutureResult& rhs) : std::shared_future>(), sharedFuture(rhs.sharedFuture), impl(rhs.impl) { } inline void SharedFutureResult>::swap(SharedFutureResult>& rhs) { impl.swap(rhs.impl); std::swap(sharedFuture, rhs.sharedFuture); std::swap(*static_cast>*>(this), static_cast>&>(rhs)); } inline SharedFutureResult>::SharedFutureResult(SharedFutureResult&& rhs) : std::shared_future>(), sharedFuture(), impl() { swap(rhs); } inline SharedFutureResult>::SharedFutureResult(FutureResult>&& rhs) : std::shared_future>(), sharedFuture(std::move(rhs.future)), impl() { impl.swap(rhs.impl); } inline SharedFutureResult>& SharedFutureResult>::operator=(SharedFutureResult>&& rhs) { swap(rhs); return *this; } inline SharedFutureResult>& SharedFutureResult>::operator=(const SharedFutureResult>& rhs) { *(static_cast>*>(this)) = rhs; sharedFuture = rhs.sharedFuture; impl = rhs.impl; return *this; } inline const std::unique_ptr& SharedFutureResult>::get() const { return sharedFuture.get(); } inline bool SharedFutureResult>::valid() const { return sharedFuture.valid(); } inline void SharedFutureResult>::wait() const { return sharedFuture.wait(); } template std::future_status SharedFutureResult>::wait_until(const std::chrono::time_point& abs_time) const { return sharedFuture.wait_until(abs_time); } template std::future_status SharedFutureResult>::wait_for(const std::chrono::duration& rel_time) const { return sharedFuture.wait_for(rel_time); } inline bool SharedFutureResult>::cancel(bool allowInterrupt) { if (allowInterrupt) { //TODO //engine_cancel_matlab_async(impl->handle); impl->interrupted = true; return true; } impl->interrupted = false; impl->cancelled = false; return false; } } } #endif // CPPSHAREDLIB_FUTURE_HPP