libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
future.hxx
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2012 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QI_DETAIL_FUTURE_HXX_
8 #define _QI_DETAIL_FUTURE_HXX_
9 
10 #include <vector>
11 #include <utility> // pair
12 #include <boost/bind.hpp>
13 #include <qi/eventloop.hpp>
14 #include <qi/actor.hpp>
16 #include <qi/log.hpp>
17 
18 namespace qi {
19 
20 namespace detail {
21 
22  template <typename T, typename R>
23  struct Caller
24  {
25  inline static R _callfunc(const T& arg,
26  const boost::function<R(const T&)>& func)
27  {
28  return func(arg);
29  }
30  };
31 
32  template <typename T>
33  struct Caller<T, void>
34  {
35  inline static void* _callfunc(const T& future,
36  const boost::function<void(const T&)>& func)
37  {
38  func(future);
39  return 0;
40  }
41  };
42 
43  template <typename T, typename R>
44  void continueThen(const Future<T>& future,
45  const boost::function<R(const Future<T>&)>& func,
46  qi::Promise<R>& promise)
47  {
48  try
49  {
50  promise.setValue(Caller<Future<T>, R>::_callfunc(future, func));
51  }
52  catch (std::exception& e)
53  {
54  promise.setError(e.what());
55  }
56  catch (...)
57  {
58  promise.setError("unknown exception");
59  }
60  }
61 
62  template <typename T, typename R>
63  void continueThenAsync(const Future<T>& future,
64  const boost::function<qi::Future<R>(const Future<T>&)>& func,
65  qi::Promise<R>& promise)
66  {
67  try
68  {
69  qi::Future<R> fut = func(future);
71  }
72  catch (std::exception& e)
73  {
74  promise.setError(e.what());
75  }
76  catch (...)
77  {
78  promise.setError("unknown exception");
79  }
80  }
81 
82  template <bool Async, typename T, typename R>
84 
85  template <typename T, typename R>
86  struct ContinueThenMaybeAsync<true, T, R>
87  {
88  template <typename AF>
89  static boost::function<void(const Future<T>&)> makeFunc(AF&& func, const qi::Promise<R>& promise)
90  {
91  return boost::bind(&detail::continueThenAsync<T, R>,
92  _1,
93  // this cast seems necessary :(
94  boost::function<qi::Future<R>(const Future<T>&)>(std::forward<AF>(func)),
95  promise);
96  }
97  };
98 
99  template <typename T, typename R>
100  struct ContinueThenMaybeAsync<false, T, R>
101  {
102  template <typename AF>
103  static boost::function<void(const Future<T>&)> makeFunc(AF&& func, const qi::Promise<R>& promise)
104  {
105  QI_ASSERT(false && "unreachable code");
106  return {};
107  }
108  };
109 
110  template <typename T, typename R>
111  void continueAndThen(const Future<T>& future,
112  const boost::function<R(const typename Future<T>::ValueType&)>& func,
113  qi::Promise<R>& promise)
114  {
115  if (future.isCanceled())
116  promise.setCanceled();
117  else if (future.hasError())
118  promise.setError(future.error());
119  else if (promise.isCancelRequested())
120  promise.setCanceled();
121  else
122  {
123  try
124  {
125  promise.setValue(Caller<typename Future<T>::ValueType, R>::_callfunc(future.value(), func));
126  }
127  catch (std::exception& e)
128  {
129  promise.setError(e.what());
130  }
131  catch (...)
132  {
133  promise.setError("unknown exception");
134  }
135  }
136  }
137 
138  template <typename T, typename R>
139  void continueAndThenAsync(const Future<T>& future,
140  const boost::function<qi::Future<R>(const typename Future<T>::ValueType&)>& func,
141  qi::Promise<R>& promise)
142  {
143  if (future.isCanceled())
144  promise.setCanceled();
145  else if (future.hasError())
146  promise.setError(future.error());
147  else if (promise.isCancelRequested())
148  promise.setCanceled();
149  else
150  {
151  try
152  {
153  qi::Future<R> fut = func(future.value());
154  qi::adaptFuture(fut, promise);
155  }
156  catch (std::exception& e)
157  {
158  promise.setError(e.what());
159  }
160  catch (...)
161  {
162  promise.setError("unknown exception");
163  }
164  }
165  }
166 
167  template <bool Async, typename T, typename R>
169 
170  template <typename T, typename R>
171  struct ContinueAndThenMaybeAsync<true, T, R>
172  {
173  template <typename AF>
174  static boost::function<void(const Future<T>&)> makeFunc(AF&& func, const qi::Promise<R>& promise)
175  {
176  return boost::bind(&detail::continueAndThenAsync<T, R>,
177  _1,
178  // this cast seems necessary :(
179  boost::function<qi::Future<R>(const typename Future<T>::ValueType&)>(std::forward<AF>(func)),
180  promise);
181  }
182  };
183 
184  template <typename T, typename R>
185  struct ContinueAndThenMaybeAsync<false, T, R>
186  {
187  template <typename AF>
188  static boost::function<void(const Future<T>&)> makeFunc(AF&& func, const qi::Promise<R>& promise)
189  {
190  QI_ASSERT(false && "unreachable code");
191  return {};
192  }
193  };
194 
195 } // namespace detail
196 
197  template <typename T>
198  template <typename R, typename AF>
200  {
201  return thenRImpl<R>(type, std::forward<AF>(func));
202  }
203 
204  template <typename T>
205  template <typename R, typename AF>
206  inline Future<R> Future<T>::thenRImpl(FutureCallbackType type, AF&& func)
207  {
208  boost::weak_ptr<detail::FutureBaseTyped<T> > weakp(_p);
209  qi::Promise<R> promise([weakp](const qi::Promise<R>&){
210  if (auto futureb = weakp.lock())
211  Future<T>(futureb).cancel();
212  });
213 
214  if (type == FutureCallbackType_Auto && detail::IsAsyncBind<AF>::value)
215  {
217  _p->connect(*this,
218  detail::ContinueThenMaybeAsync<detail::IsAsyncBind<AF>::value, T, R>
219  ::makeFunc(std::forward<AF>(func), promise),
220  type);
221  }
222  else
223  {
224  _p->connect(*this,
225  boost::bind(
226  &detail::continueThen<T, R>,
227  _1,
228  // this cast seems necessary :(
229  boost::function<R(const Future<T>&)>(std::forward<AF>(func)),
230  promise),
231  type);
232  }
233  return promise.future();
234  }
235 
236  template <typename T>
237  template <typename R, typename AF>
239  {
240  return andThenRImpl<R>(type, std::forward(func));
241  }
242 
243  template <typename T>
244  template <typename R, typename AF>
246  {
247  boost::weak_ptr<detail::FutureBaseTyped<T> > weakp(_p);
248  qi::Promise<R> promise([weakp](const qi::Promise<R>&){
249  if (auto futureb = weakp.lock())
250  Future<T>(futureb).cancel();
251  });
252 
253  if (type == FutureCallbackType_Auto && detail::IsAsyncBind<AF>::value)
254  {
256  _p->connect(*this,
257  detail::ContinueAndThenMaybeAsync<detail::IsAsyncBind<AF>::value, T, R>
258  ::makeFunc(std::forward<AF>(func), promise),
259  type);
260  }
261  else
262  {
263  _p->connect(*this,
264  boost::bind(&detail::continueAndThen<T, R>,
265  _1,
266  // this cast seems necessary :(
267  boost::function<R(const typename Future<T>::ValueType&)>(std::forward<AF>(func)),
268  promise),
269  type);
270  }
271  return promise.future();
272  }
273 
274  template <typename T>
276  const boost::function<void(const Future<T>&)>& cb)
277  {
278  connectWithStrand(*strand, cb);
279  }
280 
281  template <typename T>
283  const boost::function<void(const Future<T>&)>& cb)
284  {
285  _p->connect(
286  *this,
287  strand.schedulerFor(cb),
289  }
290 
291  template <typename T>
292  void Future<T>::_weakCancelCb(const boost::weak_ptr<detail::FutureBaseTyped<T> >& wfuture)
293  {
294  if (boost::shared_ptr<detail::FutureBaseTyped<T> > fbt = wfuture.lock())
295  {
296  Future<T> future(fbt);
297  future.cancel();
298  }
299  }
300 
301  template <typename T>
302  boost::function<void()> Future<T>::makeCanceler()
303  {
304  return boost::bind(&Future<T>::_weakCancelCb, boost::weak_ptr<detail::FutureBaseTyped<T> >(_p));
305  }
306 
307  namespace detail {
308 
309  template <typename T>
311  : _value()
312  , _async(FutureCallbackType_Auto)
313  {
314  }
315 
316  template <typename T>
318  {
319  if (_onDestroyed && hasValue(0))
320  _onDestroyed(_value);
321  }
322 
323  template <typename T>
325  {
326  CancelCallback onCancel;
327  {
328  boost::recursive_mutex::scoped_lock lock(mutex());
329  if (isFinished())
330  return;
331  requestCancel();
332  onCancel = _onCancel;
333  }
334  if (onCancel)
335  {
336  qi::Promise<T> prom(future);
337  onCancel(prom);
338  }
339  }
340 
341  template <typename T>
343  {
344  bool doCancel = false;
345  {
346  boost::recursive_mutex::scoped_lock lock(mutex());
347  _onCancel = onCancel;
348  doCancel = isCancelRequested();
349  }
350  qi::Future<T> fut = promise.future();
351  if (doCancel)
352  cancel(fut);
353  }
354 
355  template <typename T>
357  {
358  for (unsigned i = 0; i < _onResult.size(); ++i)
359  {
360  const bool async = [&]{
361  if (_onResult[i].callType != FutureCallbackType_Auto)
362  return _onResult[i].callType != FutureCallbackType_Sync;
363  else
364  return _async != FutureCallbackType_Sync;
365  }();
366 
367  if (async)
368  getEventLoop()->post(boost::bind(_onResult[i].callback, future));
369  else
370  try
371  {
372  _onResult[i].callback(future);
373  }
374  catch (const qi::PointerLockException&)
375  { // do nothing
376  }
377  catch (const std::exception& e)
378  {
379  qiLogError("qi.future") << "Exception caught in future callback " << e.what();
380  }
381  catch (...)
382  {
383  qiLogError("qi.future") << "Unknown exception caught in future callback";
384  }
385  }
386  notifyFinish();
387  clearCallbacks();
388  }
389 
390  template <typename T>
392  {
393  // report-ready + onResult() must be Atomic to avoid
394  // missing callbacks/double calls in case connect() is invoked at
395  // the same time
396  boost::recursive_mutex::scoped_lock lock(mutex());
397  if (!isRunning())
399 
400  _value = value;
401  reportValue();
402  callCbNotify(future);
403  }
404 
405  template <typename T>
407  {
408  // report-ready + onResult() must be Atomic to avoid
409  // missing callbacks/double calls in case connect() is invoked at
410  // the same time
411  boost::recursive_mutex::scoped_lock lock(mutex());
412  if (!isRunning())
414 
415  reportValue();
416  callCbNotify(future);
417  }
418 
419  template <typename T>
420  void FutureBaseTyped<T>::setError(qi::Future<T>& future, const std::string& message)
421  {
422  boost::recursive_mutex::scoped_lock lock(mutex());
423  if (!isRunning())
425 
426  reportError(message);
427  callCbNotify(future);
428  }
429 
430  template <typename T>
432  {
433  boost::recursive_mutex::scoped_lock lock(mutex());
434  QI_ASSERT(isRunning());
435 
436  reportError("Promise broken (all promises are destroyed)");
437  callCbNotify(future);
438  }
439 
440  template <typename T>
442  {
443  boost::recursive_mutex::scoped_lock lock(mutex());
444  if (!isRunning())
446 
447  reportCanceled();
448  callCbNotify(future);
449  }
450 
451  template <typename T>
452  void FutureBaseTyped<T>::setOnDestroyed(boost::function<void(ValueType)> f)
453  {
454  _onDestroyed = f;
455  }
456 
457  template <typename T>
459  const boost::function<void(qi::Future<T>)>& s,
460  FutureCallbackType type)
461  {
462  if (state() == FutureState_None)
464 
465  bool ready;
466  {
467  boost::recursive_mutex::scoped_lock lock(mutex());
468  ready = isFinished();
469  if (!ready)
470  _onResult.push_back(Callback(s, type));
471  }
472 
473  // result already ready, notify the callback
474  if (ready)
475  {
476  const bool async = [&]{
477  if (type != FutureCallbackType_Auto)
478  return type != FutureCallbackType_Sync;
479  else
480  return _async != FutureCallbackType_Sync;
481  }();
482 
483  if (async)
484  getEventLoop()->post(boost::bind(s, future));
485  else
486  {
487  try
488  {
489  s(future);
490  }
491  catch (const ::qi::PointerLockException&)
492  { /*do nothing*/
493  }
494  }
495  }
496  }
497 
498  template <typename T>
500  {
501  FutureState state = wait(msecs);
502  if (state == FutureState_None)
504  if (state == FutureState_Running)
506  if (state == FutureState_Canceled)
508  if (state == FutureState_FinishedWithError)
510  return _value;
511  }
512 
513  template <typename T>
515  {
516  _onResult.clear();
517  if (_onCancel)
518  {
519  _onCancel = CancelCallback(PromiseNoop<T>);
520  }
521  }
522 
523  template <typename T>
525  qi::Future<T>& fut,
526  qi::Atomic<int>* count) {
527  if (!prom.future().isFinished() && !fut.hasError())
528  {
529  // An other future can trigger at the same time.
530  // Don't bother to lock, just catch the FutureAlreadySet exception
531  try
532  {
533  prom.setValue(fut);
534  }
535  catch(const FutureException&)
536  {}
537  }
538  if (! --*count)
539  {
540  // I'm the last
541  if (!prom.future().isFinished())
542  {
543  // same 'race' as above. between two setError, not between a value and
544  // an error.
545  try
546  {
547  prom.setValue(makeFutureError<T>("No future returned successfully."));
548  }
549  catch(const FutureException&)
550  {}
551  }
552  delete count;
553  }
554  }
555 
556  template <typename T>
557  class AddUnwrap<Future<T> >
558  {
559  public:
561  {
562  Future<Future<T> >* self = static_cast<Future<Future<T> >*>(this);
563 
564  Promise<T> promise(boost::bind(&AddUnwrap<Future<T> >::_cancel, _1,
565  boost::weak_ptr<FutureBaseTyped<Future<T> > >(self->_p)));
566 
567  self->connect(
568  boost::bind(&AddUnwrap<Future<T> >::_forward, _1, promise),
570 
571  return promise.future();
572  }
573 
574  private:
575  static void _forward(const Future<Future<T> >& future,
576  Promise<T>& promise)
577  {
578  if (future.isCanceled())
579  promise.setCanceled();
580  else if (future.hasError())
581  promise.setError(future.error());
582  else
583  adaptFuture(future.value(), promise);
584  }
585 
586  static void _cancel(Promise<T>& promise,
587  const boost::weak_ptr<FutureBaseTyped<Future<T> > >& wfuture)
588  {
589  if (boost::shared_ptr<FutureBaseTyped<Future<T> > > fbt =
590  wfuture.lock())
591  {
592  Future<Future<T> > future(fbt);
593  future.cancel();
594  }
595  }
596  };
597 
598  } // namespace detail
599 
600  template <typename T>
601  qi::Future<T> makeFutureError(const std::string &error) {
602  qi::Promise<T> prom;
603  prom.setError(error);
604  return prom.future();
605  }
606 
607  namespace detail
608  {
609  template<typename FT, typename PT, typename CONV>
610  void futureAdapter(const Future<FT>& f, Promise<PT> p, CONV converter)
611  {
612  if (f.hasError())
613  p.setError(f.error());
614  else if (f.isCanceled())
615  p.setCanceled();
616  else
617  {
618  try {
619  converter(f.value(), p.value());
620  }
621  catch (const std::exception& e)
622  {
623  p.setError(std::string("futureAdapter conversion error: ") + e.what());
624  return;
625  }
626  p.trigger();
627  }
628  }
629 
630  template<typename FT>
631  void futureCancelAdapter(boost::weak_ptr<FutureBaseTyped<FT> > wf)
632  {
633  if (boost::shared_ptr<FutureBaseTyped<FT> > f = wf.lock())
634  Future<FT>(f).cancel();
635  }
636  }
637 
638  template <>
639  struct FutureValueConverter<void, void>
640  {
641  void operator()(void* in, void* out)
642  {
643  }
644  };
645 
646  template <typename T>
647  struct FutureValueConverter<T, void>
648  {
649  void operator()(const T& in, void* out)
650  {
651  }
652  };
653 
654  template <typename T>
655  struct FutureValueConverter<void, T>
656  {
657  void operator()(void* in, const T& out)
658  {
659  }
660  };
661 
662  template<typename R>
664  {
665  p.setup(boost::bind(&detail::futureCancelAdapter<AnyReference>,
666  boost::weak_ptr<detail::FutureBaseTyped<AnyReference> >(f._p)));
667  f.connect(boost::function<void(const qi::Future<AnyReference>&)>(
668  boost::bind(&detail::futureAdapter<R>, _1, p)),
670  }
671 
672  template<typename FT, typename PT>
674  {
675  if (option == AdaptFutureOption_ForwardCancel)
676  p.setup(boost::bind(&detail::futureCancelAdapter<FT>,
677  boost::weak_ptr<detail::FutureBaseTyped<FT> >(f._p)));
678  const_cast<Future<FT>&>(f).connect(boost::bind(detail::futureAdapter<FT, PT, FutureValueConverter<FT, PT> >, _1, p,
680  }
681 
682  template<typename FT, typename PT, typename CONV>
683  void adaptFuture(const Future<FT>& f, Promise<PT>& p, CONV converter, AdaptFutureOption option)
684  {
685  if (option == AdaptFutureOption_ForwardCancel)
686  p.setup(boost::bind(&detail::futureCancelAdapter<FT>,
687  boost::weak_ptr<detail::FutureBaseTyped<FT> >(f._p)));
688  const_cast<Future<FT>&>(f).connect(boost::bind(detail::futureAdapter<FT, PT, CONV>, _1, p, converter),
690  }
691 
692  namespace detail
693  {
694 
695  template <typename T>
697  {
698  void operator,(const T& val)
699  {
700  future = Future<T>(val);
701  }
702 
703  void operator,(const Future<T>& val)
704  {
705  future = val;
706  }
707 
709  {
710  return *this;
711  }
712 
714  };
715 
716  template <>
717  struct FutureWrapper<void>
718  {
719  // initialize the future as operator, wont be called if the function returns void
720  // if it returns a future, then this value will be overwritten anyway, so no problem
722  : future(0)
723  {}
724 
725  void operator,(const Future<void>& val)
726  {
727  future = val;
728  }
729 
731  {
732  return *this;
733  }
734 
736  };
737 
738  }
739 
740 }
741 
743 
744 #endif // _QI_DETAIL_FUTURE_HXX_
static void * _callfunc(const T &future, const boost::function< void(const T &)> &func)
Definition: future.hxx:35
void setError(qi::Future< T > &future, const std::string &message)
Definition: future.hxx:420
AdaptFutureOption
Definition: future_fwd.hpp:94
void setup(boost::function< void(qi::Promise< T > &)> cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:820
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:484
FutureWrapper< T > & operator()()
Definition: future.hxx:708
The future has been canceled.
Definition: future_fwd.hpp:78
void futureAdapter(const Future< FT > &f, Promise< PT > p, CONV converter)
Definition: future.hxx:610
void continueThen(const Future< T > &future, const boost::function< R(const Future< T > &)> &func, qi::Promise< R > &promise)
Definition: future.hxx:44
auto schedulerFor(F &&func, boost::function< void()> onFail={}) -> detail::WrapInStrand< typename std::decay< F >::type >
Definition: strand.hpp:153
void operator()(const T &in, void *out)
Definition: future.hxx:649
void continueAndThen(const Future< T > &future, const boost::function< R(const typename Future< T >::ValueType &)> &func, qi::Promise< R > &promise)
Definition: future.hxx:111
void operator,(const T &val)
Definition: future.hxx:698
void operator()(void *in, void *out)
Definition: future.hxx:641
void setCanceled(qi::Future< T > &future)
Definition: future.hxx:441
void setValue(qi::Future< T > &future, const ValueType &value)
Definition: future.hxx:391
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
Definition: future.hxx:174
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
Definition: future.hxx:188
void setError(const std::string &msg)
Definition: future_fwd.hpp:767
ValueType & value()
Definition: future_fwd.hpp:792
void set(qi::Future< T > &future)
Definition: future.hxx:406
void callCbNotify(qi::Future< T > &future)
Definition: future.hxx:356
#define QI_ASSERT(expr__)
Definition: assert.hpp:27
bool isCanceled() const
Definition: future_fwd.hpp:269
boost::function< void()> makeCanceler()
Get a functor that will cancel the future.
Definition: future.hxx:302
void trigger()
Definition: future_fwd.hpp:795
Specialize this struct to provide conversion between future values.
Definition: future_fwd.hpp:959
FutureWrapper< void > & operator()()
Definition: future.hxx:730
qi::Future< T > makeFutureError(const std::string &error)
Helper function to return a future with the error set.
Definition: future.hxx:601
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
Definition: future.hxx:103
bool isCancelRequested() const
Definition: future_fwd.hpp:781
void post(const boost::function< void()> &callback, uint64_t usDelay)
Similar to async() but without cancelation or notification.
Definition: eventloop.hpp:123
qi::Future< T > future
Definition: future.hxx:713
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Definition: future_fwd.hpp:786
Future< R > andThenR(FutureCallbackType type, AF &&func)
Same as thenR(), but the callback is called only if this future finishes with a value.
Definition: future.hxx:238
boost::shared_ptr< detail::FutureBaseTyped< T > > _p
Definition: future_fwd.hpp:533
#define qiLogError(...)
Log in error mode.
Definition: log.hpp:112
the future is not associated to a promise
Definition: future_fwd.hpp:111
const ValueType & value(int msecs) const
Definition: future.hxx:499
FutureState
Definition: future_fwd.hpp:75
void continueThenAsync(const Future< T > &future, const boost::function< qi::Future< R >(const Future< T > &)> &func, qi::Promise< R > &promise)
Definition: future.hxx:63
Future< R > async(boost::function< R()> callback, uint64_t usDelay)
Definition: eventloop.hpp:186
typename FutureType< T >::type ValueType
Definition: future_fwd.hpp:893
qi::Future< void > future
Definition: future.hxx:735
Future is not tied to a promise.
Definition: future_fwd.hpp:76
Operation pending.
Definition: future_fwd.hpp:77
void continueAndThenAsync(const Future< T > &future, const boost::function< qi::Future< R >(const typename Future< T >::ValueType &)> &func, qi::Promise< R > &promise)
Definition: future.hxx:139
void setOnDestroyed(boost::function< void(ValueType)> f)
Definition: future.hxx:452
void operator,(const Future< void > &val)
Definition: future.hxx:725
static boost::function< void(const Future< T > &)> makeFunc(AF &&func, const qi::Promise< R > &promise)
Definition: future.hxx:89
typename detail::FutureType< T >::type ValueType
Definition: future_fwd.hpp:152
void cancel()
Definition: future_fwd.hpp:314
EventLoop * getEventLoop()
Return the global eventloop, created on demand on first call.
void connect(qi::Future< T > future, const boost::function< void(qi::Future< T >)> &s, FutureCallbackType type)
Definition: future.hxx:458
The operation is finished with an error.
Definition: future_fwd.hpp:79
Future< R > thenR(FutureCallbackType type, AF &&func)
Execute a callback when the future is finished.
Definition: future.hxx:199
void waitForFirstHelper(qi::Promise< qi::Future< T > > &prom, qi::Future< T > &fut, qi::Atomic< int > *count)
Definition: future.hxx:524
void setCanceled()
Definition: future_fwd.hpp:774
boost::function< void(Promise< T > &)> CancelCallback
Definition: future_fwd.hpp:892
void cancel(qi::Future< T > &future)
Definition: future.hxx:324
void futureCancelAdapter(boost::weak_ptr< FutureBaseTyped< FT > > wf)
Definition: future.hxx:631
void operator,(const Future< T > &val)
Definition: future.hxx:703
const std::string & error(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:297
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
Definition: future_fwd.hpp:214
Convenient log macro.
FutureCallbackType
Definition: future_fwd.hpp:83
void setBroken(qi::Future< T > &future)
Definition: future.hxx:431
void setValue(const ValueType &value)
Definition: future_fwd.hpp:760
void setOnCancel(qi::Promise< T > &promise, CancelCallback onCancel)
Definition: future.hxx:342
void adaptFuture(const Future< FT > &f, Promise< PT > &p, AdaptFutureOption option)
Feed a promise from a future of possibly different type.
Definition: future.hxx:673
static R _callfunc(const T &arg, const boost::function< R(const T &)> &func)
Definition: future.hxx:25
void connectWithStrand(qi::Strand *strand, const boost::function< void(const Future< T > &)> &cb)
Definition: future.hxx:275
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:327
void operator()(void *in, const T &out)
Definition: future.hxx:657
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...
Definition: future.hxx:663
bool hasError(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:278