7 #ifndef _QI_FUTURE_HPP_
8 # define _QI_FUTURE_HPP_
13 # include <qi/config.hpp>
19 # include <boost/shared_ptr.hpp>
20 # include <boost/make_shared.hpp>
21 # include <boost/function.hpp>
22 # include <boost/bind.hpp>
23 # include <boost/thread/recursive_mutex.hpp>
26 # pragma warning( push )
27 # pragma warning( disable: 4251 )
28 # pragma warning( disable: 4275 ) //std::runtime_error: no dll interface
61 template <
typename T>
class Future;
66 template <
typename T>
class FutureBaseTyped;
109 : std::runtime_error(stateToString(es) + str)
115 std::string stateToString(
const ExceptionState &es);
121 ExceptionState _state;
142 template <
typename T>
143 class Future :
public detail::AddUnwrap<T> {
150 :
_p(boost::make_shared<detail::FutureBaseTyped<T> >())
160 return _p.get() == other._p.get();
169 bool operator < (const Future<T>& b)
const
171 return _p.get() < b._p.get();
201 {
return _p->value(msecs); }
213 {
return _p->wait(msecs); }
220 {
return _p->wait(duration); }
223 {
return this->
wait(duration); }
230 {
return _p->wait(timepoint); }
233 {
return this->
wait(timepoint); }
240 {
return _p->isFinished(); }
247 {
return _p->isRunning(); }
256 {
return _p->isCanceled(); }
265 {
return _p->hasError(msecs); }
275 {
return _p->hasValue(msecs); }
284 {
return _p->error(msecs); }
310 return _p->isCancelable();
313 template <
typename R>
316 const boost::function<R(
const Future<T>&)>& func);
318 template <
typename R>
320 const boost::function<R(
const Future<T>&)>& func)
325 template <
typename R>
330 template <
typename R>
337 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
338 template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
339 Future<R> thenR(const AF& func, const ARG0& arg0 comma ADECL) \
341 return this->thenR<R>(FutureCallbackType_Async, func, arg0 comma AUSE); \
343 template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
344 Future<R> thenR(FutureCallbackType type, const AF& func, \
345 const ARG0& arg0 comma ADECL) \
347 return _thenMaybeActor<R, ARG0>( \
348 arg0, ::qi::bind<R(const Future<T>&)>(func, arg0 comma AUSE), type); \
375 template<
typename AF>
379 _p->connect(*
this, fun, type);
388 template<
typename FUNCTYPE,
typename ARG0>
389 void connect(FUNCTYPE fun, ARG0 tracked, ...,
392 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
393 template <typename AF, typename ARG0 comma ATYPEDECL> \
394 inline void connect(const AF& fun, const ARG0& arg0 comma ADECL, \
395 FutureCallbackType type = FutureCallbackType_Async) \
397 _connectMaybeActor<ARG0>( \
398 arg0, ::qi::bind<void(Future<T>)>(fun, arg0 comma AUSE), type); \
405 const boost::function<
void(
const Future<T>&)>& cb)
409 transformStrandedCallback(strand, cb),
414 inline void _connect(
const boost::function<
void()>& s)
419 boost::shared_ptr<detail::FutureBaseTyped<T> >
impl() {
return _p;}
428 boost::shared_ptr< detail::FutureBaseTyped<T> >
_p;
434 template<
typename FT,
typename PT>
436 template<
typename FT,
typename PT,
typename CONV>
442 template<
typename FT>
451 void setOnDestroyed(boost::function<
void(
ValueType)> cb)
453 _p->setOnDestroyed(cb);
456 template <
typename Arg>
458 const boost::function<
void(
const boost::function<
void()>&)>& poster,
459 const boost::function<
void(
const Arg&)>& callback,
const Arg& fut);
461 template <
typename Arg>
462 boost::function<void(const Arg&)> transformStrandedCallback(
464 const boost::function<
void(
const Arg&)>& cb);
466 template <
typename ARG0>
467 typename boost::enable_if<
468 boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
470 _connectMaybeActor(
const ARG0& arg0,
471 const boost::function<
void(
const Future<T>&)>& cb,
473 template <
typename ARG0>
474 typename boost::disable_if<
475 boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
477 _connectMaybeActor(
const ARG0& arg0,
478 const boost::function<
void(
const Future<T>&)>& cb,
481 template <
typename R>
482 static void _continuate(
const Future<T>& future,
483 const boost::function<R(
const Future<T>&)>& func,
486 static void _cancelContinuation(
const Future<T>& future,
489 template <
typename R,
typename ARG0,
typename AF>
490 typename boost::enable_if<
491 boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
493 _thenMaybeActor(
const ARG0& arg0,
496 template <
typename R,
typename ARG0,
typename AF>
497 typename boost::disable_if<
498 boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
500 _thenMaybeActor(
const ARG0& arg0,
575 bool operator < (const FutureSync<T>& b)
const
577 return _future._p.get() < b._future._p.get();
610 template<
typename FUNCTYPE,
typename ARG0>
611 void connect(FUNCTYPE fun, ARG0 tracked, ...);
613 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
614 template<typename AF, typename ARG0 comma ATYPEDECL> \
615 inline void connect(const AF& fun, const ARG0& arg0 comma ADECL) \
618 connect(::qi::bind<void(FutureSync<T>)>(fun, arg0 comma AUSE)); \
640 template <
typename T>
651 _f._p->reportStart();
653 ++
_f._p->_promiseCount;
665 ++
_f._p->_promiseCount;
671 ++
_f._p->_promiseCount;
683 _f._p->setValue(
_f, value);
690 _f._p->setError(
_f, msg);
697 _f._p->setCanceled(
_f);
704 return _f._p->isCancelRequested();
726 if (!this->
_f._p->isCancelable())
727 throw std::runtime_error(
"Promise was not created as a cancelable one");
729 this->
_f._p->setOnCancel(*
this, cancelCallback);
734 if (
_f._p == rhs.
_f._p)
739 ++
_f._p->_promiseCount;
746 this->
_f._p->reportStart();
747 this->
_f._p->setOnCancel(*
this, cancelCallback);
751 ++
_f._p->_promiseCount;
753 template<
typename>
friend class ::qi::detail::FutureBaseTyped;
758 template<
typename FT,
typename PT>
760 template<
typename FT,
typename PT,
typename CONV>
769 assert(*
_f._p->_promiseCount > 0);
773 if (--
_f._p->_promiseCount == 0 &&
_f.isRunning())
774 _f._p->setBroken(
_f);
782 template <
typename T>
786 template <
typename T>
792 template<
typename FT,
typename PT>
811 template<
typename FT,
typename PT>
812 void adaptFuture(
const Future<FT>& f, Promise<PT>& p);
815 void adaptFuture(Future<AnyReference>& f, Promise<R>& p);
818 template<
typename FT,
typename PT,
typename CONV>
819 void adaptFuture(
const Future<FT>& f, Promise<PT>& p, CONV converter);
822 template <
typename T>
825 return future.makeCanceler();
830 # pragma warning( pop )
833 #endif // _QI_FUTURE_HPP_
Future< T >::ValueTypeCast ValueTypeCast
asked for error, but there is no error
Promise(FutureCallbackType async=FutureCallbackType_Async)
when the promise is already set.
void operator()(const FT &vIn, PT &vOut)
bool operator==(const Future< T > &other)
The future has been canceled.
friend void adaptFuture(const Future< FT > &f, Promise< PT > &p)
Feed a promise from a future of possibly different type.
void PromiseNoop(qi::Promise< T > &)
Helper function that does nothing on future cancelation.
boost::function< RF > bind(const AF &fun,...)
void connect(const Connection &s)
boost::chrono::duration< int64_t, boost::nano > Duration
Convenience typedefs.
FutureState waitFor(qi::Duration duration) const
The future has been canceled.
void setup(boost::function< void(qi::Promise< T >)> cancelCallback, FutureCallbackType async=FutureCallbackType_Async)
void _connect(const boost::function< void()> &s)
friend void adaptFutureUnwrap(Future< AnyReference > &f, Promise< R > &p)
Feed a promise from a generic future which may be unwrapped if it contains itself a future...
Future< T >::ValueType ValueType
Promise(boost::function< void(qi::Promise< T >)> cancelCallback, FutureCallbackType async=FutureCallbackType_Async)
void setError(const std::string &msg)
FutureState wait(qi::Duration duration) const
friend void adaptFutureUnwrap(Future< AnyReference > &f, Promise< R > &p)
Feed a promise from a generic future which may be unwrapped if it contains itself a future...
ExceptionState state() const
const ValueType & value(int msecs=FutureTimeout_Infinite) const
FutureUserException(const std::string &str=std::string())
FutureState wait(qi::SteadyClock::time_point timepoint) const
dll import/export and compiler message
FutureSync(const Future< T > &b)
boost::function< void()> makeCanceler()
Get a functor that will cancel the future.
Specialize this struct to provide conversion between future values.
qi::Future< T > makeFutureError(const std::string &error)
Helper function to return a future with the error set.
void _connect(const boost::function< void()> &s)
const std::string & error(int msecs=FutureTimeout_Infinite) const
bool isCancelRequested() const
FutureHasNoValue typecast
#define QI_NOEXCEPT(cond)
Specify that a function may throw or not.
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Async)
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Future< R > andThenR(const boost::function< R(const typename Future< T >::ValueType &)> &func)
boost::shared_ptr< detail::FutureBaseTyped< T > > _p
boost::function< void(Future< void >) > Connection
virtual ~FutureUserException()
Future< R > async(boost::function< R()> callback, uint64_t usDelay=0)
FutureState wait(qi::SteadyClock::time_point timepoint) const
friend class ServiceBoundObject
Future is not tied to a promise.
boost::function< void()> makeCanceler(Future< T > &future)
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)
FutureState waitUntil(qi::SteadyClock::time_point timepoint) const
detail::FutureType< T >::typecast ValueTypeCast
FutureException(const ExceptionState &es, const std::string &str=std::string())
~FutureSync() QI_NOEXCEPT(false)
void setOnCancel(boost::function< void(qi::Promise< T >)> cancelCallback)
bool isCancelable() const
Future(const Future< T > &b)
detail::FutureType< T >::type ValueType
FutureState wait(qi::Duration duration) const
bool isCancelable() const
The operation is finished with an error.
FutureSync< T > & operator=(const Future< T > &b)
detail::FutureType< T >::type ValueType
FutureState waitFor(qi::Duration duration) const
FutureState wait(int msecs=FutureTimeout_Infinite) const
virtual ~FutureException()
FutureState wait(int msecs=FutureTimeout_Infinite) const
bool hasValue(int msecs=FutureTimeout_Infinite) const
void adaptFuture(const Future< FT > &f, Promise< PT > &p)
Feed a promise from a future of possibly different type.
void futureCancelAdapter(boost::weak_ptr< FutureBaseTyped< FT > > wf)
const std::string & error(int msecs=FutureTimeout_Infinite) const
Promise< T > & operator=(const Promise< T > &rhs)
bool hasValue(int msecs=FutureTimeout_Infinite) const
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
FutureSync(const FutureSync< T > &b)
FutureUniqueId uniqueId() const
Promise(const qi::Promise< T > &rhs)
FutureUniqueId uniqueId() const
void setValue(const ValueType &value)
FutureSync< T > & operator=(const FutureSync< T > &b)
Future< T > & operator=(const Future< T > &b)
boost::chrono::time_point< SteadyClock > time_point
The future is not cancelable.
Future< R > andThenR(FutureCallbackType type, const boost::function< R(const typename Future< T >::ValueType &)> &func)
Future< R > thenR(FutureCallbackType type, const boost::function< R(const Future< T > &)> &func)
Future< R > thenR(const boost::function< R(const Future< T > &)> &func)
friend void adaptFuture(const Future< FT > &f, Promise< PT > &p)
Feed a promise from a future of possibly different type.
bool hasError(int msecs=FutureTimeout_Infinite) const
boost::shared_ptr< detail::FutureBaseTyped< T > > impl()
FutureState waitUntil(qi::SteadyClock::time_point timepoint) const
void connectWithStrand(qi::Strand *strand, const boost::function< void(const Future< T > &)> &cb)
The operation is finished with a value.
Future< T >::Connection Connection
Future(boost::shared_ptr< detail::FutureBaseTyped< T > > p)
void adaptFutureUnwrap(Future< AnyReference > &f, Promise< R > &p)
Feed a promise from a generic future which may be unwrapped if it contains itself a future...
bool hasError(int msecs=FutureTimeout_Infinite) const