libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
future_fwd.hpp
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_FUTURE_HPP_
8 # define _QI_FUTURE_HPP_
9 
10 # include <stdexcept>
11 # include <type_traits>
12 # include <vector>
13 
14 # include <ka/functional.hpp>
15 # include <qi/api.hpp>
16 # include <qi/assert.hpp>
17 # include <qi/atomic.hpp>
18 # include <qi/config.hpp>
19 # include <qi/clock.hpp>
20 # include <qi/detail/mpl.hpp>
21 # include <qi/either.hpp>
22 # include <qi/log.hpp>
23 # include <qi/os.hpp>
24 # include <qi/tag.hpp>
25 
26 # include <boost/shared_ptr.hpp>
27 # include <boost/make_shared.hpp>
28 # include <boost/function.hpp>
29 # include <boost/bind.hpp>
30 # include <boost/thread/recursive_mutex.hpp>
31 # include <boost/exception/diagnostic_information.hpp>
32 
33 # ifdef _MSC_VER
34 # pragma warning( push )
35 # pragma warning( disable: 4251 )
36 # pragma warning( disable: 4275 ) //std::runtime_error: no dll interface
37 # endif
38 
39 namespace qi {
40 
41  class AnyReference;
42 
43  namespace detail
44  {
45  template<typename T>
46  struct FutureType
47  {
48  using type = T;
49  using typecast = T;
50  };
51 
52  struct FutureHasNoValue {};
53  // Hold a void* for Future<void>
54  template<>
55  struct FutureType<void>
56  {
57  using type = void*;
59  };
60 
61  template <typename T>
62  class AddUnwrap
63  {};
64  }
65 
66  class Actor;
67  class Strand;
68 
69  template <typename T> class Future;
70  template <typename T> class FutureSync;
71  template <typename T> class Promise;
72 
73  namespace detail {
74  template <typename T> class FutureBaseTyped;
75 
76  template<typename FT>
77  void futureCancelAdapter(boost::weak_ptr<detail::FutureBaseTyped<FT> > wf);
78  }
79 
82  enum FutureState {
88  };
89 
90  inline std::ostream& operator<<(std::ostream& o, FutureState x)
91  {
92  switch (x)
93  {
94  case FutureState_None: return o << "FutureState_None";
95  case FutureState_Running: return o << "FutureState_Running";
96  case FutureState_Canceled: return o << "FutureState_Canceled";
97  case FutureState_FinishedWithError: return o << "FutureState_FinishedWithError";
98  case FutureState_FinishedWithValue: return o << "FutureState_FinishedWithValue";
99  }
100  throw std::runtime_error("Unknown FutureState value: " + os::to_string(x));
101  }
102 
103 
108  };
109 
111  FutureTimeout_Infinite = INT_MAX, // TODO: replace by numeric_limits<int>::max() when we get
112  // rid of VS2013
114  };
115 
116  namespace detail
117  {
118  struct VisitTimeout : boost::static_visitor<MilliSeconds::rep>
119  {
120  MilliSeconds::rep operator()(MilliSeconds x) const {
121  return x.count();
122  }
123  MilliSeconds::rep operator()(Infinity) const {
124  return static_cast<MilliSeconds::rep>(FutureTimeout_Infinite);
125  }
126  };
127  } // namespace detail
128 
132  };
133 
134  using FutureUniqueId = void*;
135 
138  class QI_API FutureException : public std::runtime_error {
139  public:
147  };
148 
149  explicit FutureException(const ExceptionState &es, const std::string &str = std::string())
150  : std::runtime_error(stateToString(es) + str)
151  , _state(es)
152  {}
153 
154  inline ExceptionState state() const { return _state; }
155 
156  std::string stateToString(const ExceptionState &es);
157 
158  virtual ~FutureException() throw()
159  {}
160 
161  private:
162  ExceptionState _state;
163  };
164 
169  public:
170 
171  explicit FutureUserException(const std::string &str = std::string())
172  : FutureException(ExceptionState_FutureUserError, str)
173  {}
174 
175  virtual ~FutureUserException() throw()
176  {}
177  };
178 
183  template <typename T>
184  class Future : public detail::AddUnwrap<T> {
185  static_assert(!std::is_const<T>::value, "can't create a future of const");
186  public:
189  using TemplateValue = T;
190 
191  public:
193  : _p(boost::make_shared<detail::FutureBaseTyped<T> >())
194  {
195  }
196 
197  Future(const Future<T>& b)
198  : _p(b._p)
199  {}
200 
201  bool operator==(const Future<T> &other) const
202  {
203  return _p.get() == other._p.get();
204  }
205 
207  {
208  _p = b._p;
209  return *this;
210  }
211 
212  bool operator < (const Future<T>& b) const
213  {
214  return _p.get() < b._p.get();
215  }
216 
218  {
219  return _p.get();
220  }
221 
223  bool isValid() const
224  {
225  return _p->state() != FutureState_None;
226  }
227 
231  {
232  Promise<T> promise(async);
233  promise.setValue(v);
234  *this = promise.future();
235  }
236 
249  inline const ValueType& value(int msecs = FutureTimeout_Infinite) const
250  {
251  return _p->value(msecs);
252  }
253 
254  inline const ValueType& value(Either<MilliSeconds, Infinity> timeout) const
255  {
256  return _p->value(static_cast<int>(visit(detail::VisitTimeout{}, timeout)));
257  }
258 
263  {
264  // Copy happens because of the return type.
265  return value(static_cast<int>(visit(detail::VisitTimeout{}, timeout)));
266  }
267 
271  boost::shared_ptr<const T> valueSharedPtr(Either<MilliSeconds, Infinity> timeout = Infinity{}) const
272  {
273  // Make the returned pointer increment the shared state reference count.
274  return boost::shared_ptr<const T>(_p, &_p->value(visit(detail::VisitTimeout{}, timeout)));
275  }
276 
281  inline ValueType operator*() const
282  {
283  return valueCopy();
284  }
285 
288  QI_API_DEPRECATED_MSG("Use either `then`, `andThen`, `value` or `wait` functions instead.")
289  inline operator const ValueTypeCast&() const
290  { return _p->value(FutureTimeout_Infinite); }
291 
296  inline FutureState wait(int msecs = FutureTimeout_Infinite) const
297  { return _p->wait(msecs); }
298 
303  inline FutureState wait(qi::Duration duration) const
304  { return _p->wait(duration); }
305 
306  inline FutureState waitFor(qi::Duration duration) const
307  { return this->wait(duration); }
308 
314  { return _p->wait(timepoint); }
315 
317  { return this->wait(timepoint); }
318 
323  inline bool isFinished() const
324  { return _p->isFinished(); }
325 
330  inline bool isRunning() const
331  { return _p->isRunning(); }
332 
339  inline bool isCanceled() const
340  { return _p->isCanceled(); }
341 
348  inline bool hasError(int msecs = FutureTimeout_Infinite) const
349  { return _p->hasError(msecs); }
350 
358  inline bool hasValue(int msecs = FutureTimeout_Infinite) const
359  { return _p->hasValue(msecs); }
360 
367  inline const std::string &error(int msecs = FutureTimeout_Infinite) const
368  { return _p->error(msecs); }
369 
374  {
375  return FutureSync<T>(*this);
376  };
377 
383  void cancel()
384  {
385  _p->cancel(*this);
386  }
387 
392  QI_API_DEPRECATED_MSG("Method implementation removed, always returns 'true'")
393  bool isCancelable() const
394  {
395  return true;
396  }
397 
412  template <typename R, typename AF>
413  QI_API_DEPRECATED_MSG(Use 'then' instead)
414  Future<R> thenR(FutureCallbackType type, AF&& func);
415 
421  template <typename R, typename AF>
422  QI_API_DEPRECATED_MSG(Use 'then' instead)
423  Future<R> thenR(AF&& func)
424  {
425  return thenRImpl<R>(FutureCallbackType_Auto, std::forward<AF>(func));
426  }
427 
431  template <typename R, typename AF, typename Arg0, typename... Args>
432  QI_API_DEPRECATED_MSG(Use 'then' instead)
433  Future<R> thenR(AF&& func, Arg0&& arg0, Args&&... args);
434 
438  template <typename R, typename AF, typename Arg0, typename... Args>
439  QI_API_DEPRECATED_MSG(Use 'then' instead)
440  Future<R> thenR(FutureCallbackType type, AF&& func, Arg0&& arg0, Args&&... args);
441 
452  template <typename F>
453  auto then(FutureCallbackType type, F&& func)
455  {
456  return thenRImpl<typename std::result_of<F(Future<T>)>::type, F>(type, std::forward<F>(func));
457  }
458 
462  template <typename AF>
463  auto then(AF&& func)
465  {
466  return this->then(FutureCallbackType_Auto, std::forward<AF>(func));
467  }
468 
480  template <typename R, typename AF>
481  QI_API_DEPRECATED_MSG(Use 'andThen' instead)
482  Future<R> andThenR(FutureCallbackType type, AF&& func);
483 
489  template <typename R, typename AF>
490  QI_API_DEPRECATED_MSG(Use 'andThen' instead)
491  Future<R> andThenR(AF&& func)
492  {
493  return andThenRImpl<R>(FutureCallbackType_Auto, std::forward<AF>(func));
494  }
495 
505  template <typename F>
506  auto andThen(FutureCallbackType type, F&& func)
508  {
509  return this->andThenRImpl<typename std::decay<typename std::result_of<F(ValueType)>::type>::type, F>(type, std::forward<F>(func));
510  }
511 
515  template <typename AF>
516  auto andThen(AF&& func)
518  {
519  return this->andThen(FutureCallbackType_Auto, std::forward<AF>(func));
520  }
521 
530  boost::function<void()> makeCanceler();
531 
532  public:
533  using Connection = boost::function<void(Future<T>)>;
534 
544  template<typename AF>
545  inline void connect(const AF& fun,
547  {
548  _p->connect(*this, fun, type);
549  }
550 #ifdef DOXYGEN
551 
557  template<typename FUNCTYPE, typename ARG0>
558  void connect(FUNCTYPE fun, ARG0 tracked, ...,
560 #else
561 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
562  template <typename AF, typename ARG0 comma ATYPEDECL> \
563  QI_API_DEPRECATED_MSG(please use overload taking only a function and not argument instead)\
564  void connect(const AF& fun, const ARG0& arg0 comma ADECL, \
565  FutureCallbackType type = FutureCallbackType_Auto);
566  QI_GEN(genCall)
567 #undef genCall
568 #endif
569 
571  QI_API_DEPRECATED_MSG(Use overload with 'Strand&' instead)
572  void connectWithStrand(qi::Strand* strand,
573  const boost::function<void(const Future<T>&)>& cb);
574  void connectWithStrand(qi::Strand& strand,
575  const boost::function<void(const Future<T>&)>& cb);
576 
577  // Our companion library libqitype requires a connect with same signature for all instantiations
578  inline void _connect(const boost::function<void()>& s)
579  {
580  connect(boost::bind(s));
581  }
582 
583  // KLUDGE: ExecutionContext uses the shared state of the future for gloomy reasons!
584  friend class ExecutionContext;
585 
586  protected:
588  boost::shared_ptr<detail::FutureBaseTyped<T> > impl() { return _p;}
589 
591  Future(boost::shared_ptr<detail::FutureBaseTyped<T> > p) :
592  _p(p)
593  {
594  QI_ASSERT(_p);
595  }
596 
597  // C4251 needs to have dll-interface to be used by clients of class 'qi::Future<T>'
598  boost::shared_ptr< detail::FutureBaseTyped<T> > _p;
599  friend class Promise<T>;
600  friend class FutureSync<T>;
601 
602  template<typename R>
604  template<typename FT, typename PT>
605  friend void adaptFuture(const Future<FT>& f, Promise<PT>& p, AdaptFutureOption option);
606  template<typename FT, typename PT, typename CONV>
607  friend void adaptFuture(const Future<FT>& f, Promise<PT>& p,
608  CONV converter, AdaptFutureOption option);
609  template<typename R>
610  friend void adaptFuture(Future<AnyReference>& f, Promise<R>& p);
611 
612  template<typename FT>
613  friend void detail::futureCancelAdapter(
614  boost::weak_ptr<detail::FutureBaseTyped<FT> > wf);
615  friend class detail::AddUnwrap<T>;
616 
617  private:
618  friend class ServiceBoundObject;
619  // Private forward impl to then
620  template <typename R, typename AF>
621  Future<R> andThenRImpl(FutureCallbackType type, AF&& func);
622 
623  // Private forward impl to then
624  template <typename R, typename AF>
625  Future<R> thenRImpl(FutureCallbackType type, AF&& func);
626 
627  // Nuke this when C++03 ends
628  void setOnDestroyed(boost::function<void(ValueType)> cb)
629  {
630  _p->setOnDestroyed(cb);
631  }
632 
633  static void _weakCancelCb(const boost::weak_ptr<detail::FutureBaseTyped<T> >& wfuture);
634  };
635 
644  template<typename T>
645  class FutureSync
646  {
647  public:
648  using ValueType = typename Future<T>::ValueType;
651  // This future cannot be set, so sync starts at false
652  FutureSync() : _sync(false) {}
653 
655  : _sync(true)
656  {
657  _future = b;
658  }
659 
661  : _sync(true)
662  {
663  _future = b._future;
664  b._sync = false;
665  }
666 
667  explicit FutureSync<T>(const ValueType& v)
668  : _sync(false)
669  {
670  Promise<T> promise;
671  promise.setValue(v);
672  _future = promise.future();
673  }
674 
676  {
677  _future = b;
678  _sync = true;
679  b._sync = false;
680  return *this;
681  }
682 
684  {
685  _future = b;
686  _sync = true;
687  return *this;
688  }
689 
694  {
695  if (_sync)
696  {
697  static const auto logKnownError = [](const char* message)
698  {
699  qiLogWarning("qi.FutureSync")
700  << "Error in future on destruction: '" << message
701  << "' - continuing stack unwinding...";
702  };
703 
704  try
705  {
706  _future.value();
707  }
708  catch(const std::exception& err)
709  {
710  logKnownError(err.what());
711  throw;
712  }
713  catch(const boost::exception& err)
714  {
715  logKnownError(boost::diagnostic_information(err).c_str());
716  throw;
717  }
718  catch(...)
719  {
720  qiLogWarning("qi.FutureSync")
721  << "Unknown error in future on destruction - continuing stack unwinding...";
722  throw;
723  }
724  }
725  }
726 
727  operator Future<T>()
728  {
729  return async();
730  }
731 
732  bool operator < (const FutureSync<T>& b) const
733  {
734  return _future._p.get() < b._future._p.get();
735  }
736 
738  {
739  return _future.uniqueId();
740  }
741 
742  const ValueType& value(int msecs = FutureTimeout_Infinite) const { _sync = false; return _future.value(msecs); }
743  ValueType valueCopy(int msecs = FutureTimeout_Infinite) const { return value(msecs); }
744  boost::shared_ptr<const T> valueSharedPtr(int msecs = FutureTimeout_Infinite) const {
745  _sync = false; return _future.valueSharedPtr(msecs);
746  }
747  QI_API_DEPRECATED_MSG("Use either `then`, `andThen`, `value` or `wait` functions instead.")
748  operator const typename Future<T>::ValueTypeCast&() const { _sync = false; return _future.value(); }
749  FutureState wait(int msecs = FutureTimeout_Infinite) const { _sync = false; return _future.wait(msecs); }
750  FutureState wait(qi::Duration duration) const { _sync = false; return _future.wait(duration); }
751  FutureState waitFor(qi::Duration duration) const { _sync = false; return _future.waitFor(duration); }
752  FutureState wait(qi::SteadyClock::time_point timepoint) const { _sync = false; return _future.wait(timepoint); }
753  FutureState waitUntil(qi::SteadyClock::time_point timepoint) const { _sync = false; return _future.waitUntil(timepoint); }
754  bool isValid() const { _sync = false; return _future.isValid(); }
755  bool isRunning() const { _sync = false; return _future.isRunning(); }
756  bool isFinished() const { _sync = false; return _future.isFinished(); }
757  bool isCanceled() const { _sync = false; return _future.isCanceled(); }
758  bool hasError(int msecs = FutureTimeout_Infinite) const { _sync = false; return _future.hasError(msecs); }
759  bool hasValue(int msecs = FutureTimeout_Infinite) const { _sync = false; return _future.hasValue(msecs); }
760  const std::string &error(int msecs = FutureTimeout_Infinite) const { _sync = false; return _future.error(msecs); }
761  void cancel() { _sync = false; _future.cancel(); }
762  bool isCancelable() const { _sync = false; return true; }
763  void connect(const Connection& s) { _sync = false; _future.connect(s);}
764  void _connect(const boost::function<void()>& s) { _sync = false; _future._connect(s);}
765 
766 #ifdef DOXYGEN
767 
773  template<typename FUNCTYPE, typename ARG0>
774  void connect(FUNCTYPE fun, ARG0 tracked, ...);
775 #else
776 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
777  template<typename AF, typename ARG0 comma ATYPEDECL> \
778  QI_API_DEPRECATED_MSG(please use overload taking only a function and not argument instead)\
779  void connect(const AF& fun, const ARG0& arg0 comma ADECL);
780  QI_GEN(genCall)
781 #undef genCall
782 #endif
783 
785  {
786  _sync = false;
787  return _future;
788  }
789 
790  protected:
791  mutable bool _sync;
793  friend class Future<T>;
794  };
795 
800  template <typename T>
801  class Promise {
802  public:
804 
811  _f._p->reportStart();
812  _f._p->_async = async;
813  ++_f._p->_promiseCount;
814  }
815 
821  template <typename FUNC,
822  typename std::enable_if<!std::is_same<
823  typename std::decay<FUNC>::type,
824  typename std::decay<qi::Promise<T> >::type
825  >::value
826  >::type* = nullptr>
827  explicit Promise(FUNC&& cancelCallback,
829  {
830  setup(std::forward<FUNC>(cancelCallback), async);
831  ++_f._p->_promiseCount;
832  }
833 
834  explicit Promise(boost::function<void (qi::Promise<T>)> cancelCallback,
836  {
837  setup([cancelCallback](qi::Promise<T>& p){ cancelCallback(p); }, async);
838  ++_f._p->_promiseCount;
839  }
840 
842  : _f(rhs._f)
843  {
844  ++_f._p->_promiseCount;
845  }
846 
848  decRefcnt();
849  }
850 
855  void setValue(const ValueType &value) {
856  _f._p->setValue(_f, value);
857  }
858 
862  void setError(const std::string &msg) {
863  _f._p->setError(_f, msg);
864  }
865 
869  void setCanceled() {
870  _f._p->setCanceled(_f);
871  }
872 
876  bool isCancelRequested() const {
877  return _f._p->isCancelRequested();
878  }
879 
881  Future<T> future() const { return _f; }
882 
887  ValueType& value() { return _f._p->_value;}
890  void trigger() { _f._p->set(_f);}
891 
897  void setOnCancel(boost::function<void (qi::Promise<T>&)> cancelCallback)
898  {
899  qi::Future<T> fut = this->future();
900  this->_f._p->setOnCancel(*this, cancelCallback);
901  }
902 
904  {
905  if (_f._p == rhs._f._p)
906  return *this;
907 
908  decRefcnt();
909  _f = rhs._f;
910  ++_f._p->_promiseCount;
911  return *this;
912  }
913 
914  protected:
915  void setup(boost::function<void (qi::Promise<T>&)> cancelCallback, FutureCallbackType async = FutureCallbackType_Auto)
916  {
917  this->_f._p->reportStart();
918  this->_f._p->setOnCancel(*this, cancelCallback);
919  this->_f._p->_async = async;
920  }
921  explicit Promise(Future<T>& f) : _f(f) {
922  ++_f._p->_promiseCount;
923  }
924  template<typename> friend class ::qi::detail::FutureBaseTyped;
926 
927  template<typename R>
929  template<typename FT, typename PT>
930  friend void adaptFuture(const Future<FT>& f, Promise<PT>& p, AdaptFutureOption option);
931  template<typename FT, typename PT, typename CONV>
932  friend void adaptFuture(const Future<FT>& f, Promise<PT>& p,
933  CONV converter, AdaptFutureOption option);
934  template<typename R>
935  friend void adaptFuture(Future<AnyReference>& f, Promise<R>& p);
936 
937  private:
938  void decRefcnt()
939  {
940  QI_ASSERT(_f._p->_promiseCount.load() > 0);
941  // this is race-free because if we reach 0 it means that this is the last Promise pointing to a state and since it
942  // is the last, no one could be trying to make a copy from it while destroying it. Also no one could be changing
943  // the promise state (from running to finished or whatever) while destroying it.
944  if (--_f._p->_promiseCount == 0 && _f._p.use_count() > 1 && _f.isRunning())
945  _f._p->setBroken(_f);
946  }
947  };
948 
949  namespace detail
950  {
951  class FutureBasePrivate;
953  public:
954  FutureBase();
955  ~FutureBase();
956 
957  FutureState wait(int msecs) const;
958  FutureState wait(qi::Duration duration) const;
959  FutureState wait(qi::SteadyClock::time_point timepoint) const;
960  FutureState state() const;
961  bool isRunning() const;
962  bool isFinished() const;
963  bool isCanceled() const;
964  bool isCancelRequested() const;
965  bool hasError(int msecs) const;
966  bool hasValue(int msecs) const;
967  const std::string &error(int msecs) const;
968  void reportStart();
969 
970  protected:
971  void reportValue();
972  void reportError(const std::string &message);
973  void requestCancel();
974  void reportCanceled();
975  boost::recursive_mutex& mutex();
976  void notifyFinish();
977 
978  public:
979  FutureBasePrivate *_p;
980  };
981 
982 
983  //common state shared between a Promise and multiple Futures
984  template <typename T>
985  class FutureBaseTyped : public FutureBase {
986  public:
987  using CancelCallback = boost::function<void(Promise<T>&)>;
988  using ValueType = typename FutureType<T>::type;
989  FutureBaseTyped();
991 
992  void cancel(qi::Future<T>& future);
993 
994  /*
995  * inplace api for promise
996  */
997  void set(qi::Future<T>& future);
998  void setValue(qi::Future<T>& future, const ValueType &value);
999  void setError(qi::Future<T>& future, const std::string &message);
1000  void setBroken(qi::Future<T>& future);
1001  void setCanceled(qi::Future<T>& future);
1002 
1003  void setOnCancel(const qi::Promise<T>& promise, CancelCallback onCancel);
1004  void setOnDestroyed(boost::function<void (ValueType)> f);
1005 
1006  void connect(qi::Future<T> future,
1007  const boost::function<void (qi::Future<T>)> &callback,
1008  FutureCallbackType type);
1009 
1010  const ValueType& value(int msecs) const;
1011 
1012  private:
1013  friend class Promise<T>;
1014  using CallbackType = boost::function<void(qi::Future<T>)>;
1015  struct Callback
1016  {
1017  CallbackType callback;
1018  FutureCallbackType callType;
1019 
1020  Callback(CallbackType callback, FutureCallbackType callType)
1021  : callback(callback)
1022  , callType(callType)
1023  {}
1024  };
1025  using Callbacks = std::vector<Callback>;
1026  Callbacks _onResult;
1027  ValueType _value;
1028  CancelCallback _onCancel;
1029  boost::function<void (ValueType)> _onDestroyed;
1030  std::atomic<FutureCallbackType> _async;
1031  qi::Atomic<unsigned int> _promiseCount;
1032 
1033  template <typename F> // FunctionObject<R()> F (R unconstrained)
1034  void finish(qi::Future<T>& future, F&& finishTask);
1035 
1037  Callbacks takeOutResultCallbacks();
1038 
1040  void clearCancelCallback();
1041 
1042  static void executeCallbacks(bool defaultAsync, const Callbacks& callbacks, qi::Future<T>& future);
1043  };
1044  }
1045 
1050  template <typename T>
1051  qi::Future<T> makeFutureError(const std::string& error);
1052 
1056  template <typename T>
1057  QI_API_DEPRECATED_MSG("you can remove this occurrence")
1058  void PromiseNoop(qi::Promise<T>&)
1059  {
1060  }
1061 
1063  template<typename FT, typename PT>
1065  {
1066  void operator()(const FT& vIn, PT& vOut) { vOut = vIn;}
1067  };
1068 
1072  template<typename R>
1073  void adaptFutureUnwrap(Future<AnyReference>& f, Promise<R>& p);
1074 
1082  template<typename FT, typename PT>
1083  void adaptFuture(const Future<FT>& f, Promise<PT>& p, AdaptFutureOption option = AdaptFutureOption_ForwardCancel);
1084 
1086  template<typename FT, typename PT, typename CONV>
1087  void adaptFuture(const Future<FT>& f, Promise<PT>& p, CONV converter,
1089 
1091  template <typename T>
1092  inline boost::function<void()> makeCanceler(Future<T>& future)
1093  {
1094  return future.makeCanceler();
1095  }
1096 
1097  class AnyValue;
1098 
1099  template <typename T>
1100  Future<AnyValue> toAnyValueFuture(Future<T> future);
1101 
1102  struct SrcFuture;
1103 
1119  struct UnitFuture
1120  {
1121  // Regular:
1122  // Constructor added because of an error with Clang on Mac.
1123  // TODO: Remove this constructor when Clang is upgraded.
1125  {
1126  }
1127 
1128  KA_GENERATE_FRIEND_REGULAR_OPS_0(UnitFuture)
1129  // PolymorphicFunction<Future<T> (T), Future<void> ()>:
1131  template<typename T>
1132  Future<ka::Decay<T>> operator()(T&& t) const
1133  {
1134  return Future<ka::Decay<T>>{std::forward<T>(t)};
1135  }
1136 
1138  {
1139  return Future<void>{nullptr};
1140  }
1141 
1142  // Isomorphism:
1143  // TODO: Remove this when get rid of VS2013.
1145  };
1146 
1153  struct SrcFuture
1154  {
1155  // Regular:
1156  KA_GENERATE_FRIEND_REGULAR_OPS_0(SrcFuture)
1157 
1158  // PolymorphicFunction<T (Future<T>)>:
1161  template<typename T>
1162  auto operator()(const Future<T>& x) const QI_NOEXCEPT_EXPR(*x) -> decltype(*x)
1163  {
1164  return *x;
1165  }
1166 
1167  // Isomorphism:
1168  // TODO: Remove this when get rid of VS2013.
1170 
1177  {
1178  return {};
1179  }
1180  };
1181 
1183  {
1184  return {};
1185  }
1186 
1199  template<typename... T>
1200  auto futurize(T&&... t)
1201  -> decltype(UnitFuture{}(ka::fwd<T>(t)...))
1202  {
1203  return UnitFuture{}(ka::fwd<T>(t)...);
1204  }
1205 
1223  template<typename Proc>
1224  auto futurizeOutput(Proc&& p)
1225  -> decltype(ka::semilift(std::forward<Proc>(p), UnitFuture{}))
1226  {
1227  return ka::semilift(std::forward<Proc>(p), UnitFuture{});
1228  }
1229 } // namespace qi
1230 
1231 // KLUDGE: all definitions related to qi::bind or qi::Trackable are to be defined last,
1232 // because qi::bind, found in trackable.hxx needs to know Future first!
1233 // TODO: all functions below appear to be deprecated, they should be removed at some point.
1234 #include <qi/trackable.hpp>
1235 
1236 namespace qi
1237 {
1238  template <typename T>
1239  template <typename R, typename AF, typename Arg0, typename... Args>
1240  Future<R> Future<T>::thenR(AF&& func, Arg0&& arg0, Args&&... args)
1241  {
1242  return thenRImpl<R>(
1244  qi::bind(std::forward<AF>(func), std::forward<Arg0>(arg0), std::forward<Args>(args)...));
1245  }
1246 
1247  template <typename T>
1248  template <typename R, typename AF, typename Arg0, typename... Args>
1249  Future<R> Future<T>::thenR(FutureCallbackType type, AF&& func, Arg0&& arg0, Args&&... args)
1250  {
1251  return thenRImpl<R>(
1252  type,
1253  qi::bind(std::forward<AF>(func), arg0, std::forward<Args>(args)...));
1254  }
1255 
1256 #ifndef DOXYGEN // skip those complicated macros in documentation
1257 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
1258  template <typename T> \
1259  template <typename AF, typename ARG0 comma ATYPEDECL> \
1260  void Future<T>::connect( \
1261  const AF& fun, const ARG0& arg0 comma ADECL, FutureCallbackType type) \
1262  { \
1263  this->then(type, qi::bind(fun, arg0 comma AUSE)); \
1264  }
1265  QI_GEN(genCall)
1266 #undef genCall
1267 
1268 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
1269  template <typename T> \
1270  template <typename AF, typename ARG0 comma ATYPEDECL> \
1271  void FutureSync<T>::connect(const AF& fun, const ARG0& arg0 comma ADECL) \
1272  { \
1273  _sync = false; \
1274  connect(::qi::bind<void(FutureSync<T>)>(fun, arg0 comma AUSE)); \
1275  }
1276  QI_GEN(genCall)
1277 #undef genCall
1278 #endif
1279 }
1280 
1281 #ifdef _MSC_VER
1282 # pragma warning( pop )
1283 #endif
1284 
1285 #endif // _QI_FUTURE_HPP_
auto then(AF &&func) -> Future< typename std::result_of< AF(Future< T >)>::type >
Same as then(), but with type defaulted to FutureCallbackType_Auto.
Definition: future_fwd.hpp:463
FutureSync< T > sync()
Definition: future_fwd.hpp:373
asked for error, but there is no error
Definition: future_fwd.hpp:143
void setError(qi::Future< T > &future, const std::string &message)
Definition: future.hxx:284
AdaptFutureOption
Definition: future_fwd.hpp:129
Future< AnyValue > toAnyValueFuture(Future< T > future)
Definition: future.hxx:556
void operator()(const FT &vIn, PT &vOut)
ValueType operator*() const
Return the value associated to a Future.
Definition: future_fwd.hpp:281
bool isValid() const
Definition: future_fwd.hpp:223
Future< T > _future
Definition: future_fwd.hpp:792
void setup(boost::function< void(qi::Promise< T > &)> cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:915
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:545
The future has been canceled.
Definition: future_fwd.hpp:85
friend void adaptFuture(const Future< FT > &f, Promise< PT > &p, AdaptFutureOption option)
Feed a promise from a future of possibly different type.
Definition: future.hxx:537
#define QI_API
Definition: api.hpp:33
void PromiseNoop(qi::Promise< T > &)
friend UnitFuture retract(SrcFuture)
MilliSeconds::rep operator()(Infinity) const
Definition: future_fwd.hpp:123
FutureTimeout
Definition: future_fwd.hpp:110
void setCanceled(qi::Future< T > &future)
Definition: future.hxx:300
void connect(const Connection &s)
Definition: future_fwd.hpp:763
typename Future< T >::Connection Connection
Definition: future_fwd.hpp:650
FutureState waitFor(qi::Duration duration) const
Definition: future_fwd.hpp:751
FutureBasePrivate * _p
Definition: future_fwd.hpp:979
void _connect(const boost::function< void()> &s)
Definition: future_fwd.hpp:578
void setValue(qi::Future< T > &future, const ValueType &value)
Definition: future.hxx:267
bool isValid() const
Definition: future_fwd.hpp:754
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...
Definition: future.hxx:528
TimePoint< SteadyClock > time_point
Definition: clock.hpp:53
void setError(const std::string &msg)
Definition: future_fwd.hpp:862
FutureState wait(qi::Duration duration) const
Definition: future_fwd.hpp:750
ValueType & value()
Definition: future_fwd.hpp:887
std::ostream & operator<<(std::ostream &o, FutureState x)
Definition: future_fwd.hpp:90
void set(qi::Future< T > &future)
Definition: future.hxx:276
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...
Definition: future.hxx:528
#define QI_ASSERT(expr__)
Definition: assert.hpp:27
Promise(Future< T > &f)
Definition: future_fwd.hpp:921
ExceptionState state() const
Definition: future_fwd.hpp:154
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:742
bool isCanceled() const
Definition: future_fwd.hpp:757
FutureUserException(const std::string &str=std::string())
Definition: future_fwd.hpp:171
FutureState wait(qi::SteadyClock::time_point timepoint) const
Definition: future_fwd.hpp:313
dll import/export and compiler message
bool isCanceled() const
Definition: future_fwd.hpp:339
auto futurize(T &&...t) -> decltype(UnitFuture
FutureSync(const Future< T > &b)
Definition: future_fwd.hpp:654
boost::function< void()> makeCanceler()
Get a functor that will cancel the future.
Definition: future.hxx:153
boost::shared_ptr< const T > valueSharedPtr(Either< MilliSeconds, Infinity > timeout=Infinity{}) const
Return a shared pointer to the value associated to a Future.
Definition: future_fwd.hpp:271
void trigger()
Definition: future_fwd.hpp:890
typename Future< T >::ValueType ValueType
Definition: future_fwd.hpp:648
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.
Definition: future.hxx:466
#define qiLogWarning(...)
Log in warning mode.
Definition: log.hpp:109
void _connect(const boost::function< void()> &s)
Definition: future_fwd.hpp:764
const std::string & error(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:760
void connect(qi::Future< T > future, const boost::function< void(qi::Future< T >)> &callback, FutureCallbackType type)
Definition: future.hxx:315
auto then(FutureCallbackType type, F &&func) -> Future< typename std::result_of< F(Future< T >)>::type >
Execute a callback when the future is finished.
Definition: future_fwd.hpp:453
NanoSeconds Duration
Definition: clock.hpp:32
bool isCancelRequested() const
Definition: future_fwd.hpp:876
Future< void > operator()() const
#define QI_NOEXCEPT(cond)
Specify that a function may throw or not. Do nothing if noexcept is not available.
Definition: macro.hpp:318
const ValueType & value(Either< MilliSeconds, Infinity > timeout) const
Definition: future_fwd.hpp:254
Future< T > _f
Definition: future_fwd.hpp:925
typename detail::FutureType< void >::type ValueType
Definition: future_fwd.hpp:803
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Definition: future_fwd.hpp:881
typename Future< T >::ValueTypeCast ValueTypeCast
Definition: future_fwd.hpp:649
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:89
boost::shared_ptr< detail::FutureBaseTyped< T > > _p
Definition: future_fwd.hpp:598
virtual ~FutureUserException()
Definition: future_fwd.hpp:175
boost::function< void(Future< void >)> Connection
Definition: future_fwd.hpp:533
the future is not associated to a promise
Definition: future_fwd.hpp:146
const ValueType & value(int msecs) const
Definition: future.hxx:359
DurationType< int64_t, boost::milli > MilliSeconds
Definition: clock.hpp:27
boost::shared_ptr< const T > valueSharedPtr(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:744
FutureState
Definition: future_fwd.hpp:82
FutureState wait(qi::SteadyClock::time_point timepoint) const
Definition: future_fwd.hpp:752
typename FutureType< T >::type ValueType
Definition: future_fwd.hpp:988
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)
Definition: session.hpp:175
friend class ServiceBoundObject
Definition: future_fwd.hpp:618
Future< T > async()
Definition: future_fwd.hpp:784
Future is not tied to a promise.
Definition: future_fwd.hpp:83
boost::function< void()> makeCanceler(Future< T > &future)
Operation pending.
Definition: future_fwd.hpp:84
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
auto operator()(const Future< T > &x) const QI_NOEXCEPT_EXPR(*x) -> decltype(*x)
FutureState waitUntil(qi::SteadyClock::time_point timepoint) const
Definition: future_fwd.hpp:753
FutureException(const ExceptionState &es, const std::string &str=std::string())
Definition: future_fwd.hpp:149
void setOnDestroyed(boost::function< void(ValueType)> f)
Definition: future.hxx:308
auto async(F &&callback) -> decltype(asyncDelay(std::forward< F >(callback), qi::Duration(0)))
Definition: async.hpp:53
~FutureSync() QI_NOEXCEPT(false)
Definition: future_fwd.hpp:693
Promise(FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:810
bool operator==(const Future< T > &other) const
Definition: future_fwd.hpp:201
auto visit(Proc &&proc, T &&variant) -> decltype(boost::apply_visitor(ka::fwd< Proc >(proc), ka::fwd< T >(variant)))
Definition: either.hpp:53
bool isCancelable() const
Definition: future_fwd.hpp:393
typename detail::FutureType< void >::type ValueType
Definition: future_fwd.hpp:187
bool isRunning() const
Definition: future_fwd.hpp:330
boost::variant< A, B > Either
Convenient alias to a variant of two types.
Definition: either.hpp:11
void cancel()
Definition: future_fwd.hpp:383
Future(const Future< T > &b)
Definition: future_fwd.hpp:197
FutureState wait(qi::Duration duration) const
Definition: future_fwd.hpp:303
bool isCancelable() const
Definition: future_fwd.hpp:762
The operation is finished with an error.
Definition: future_fwd.hpp:86
auto andThen(AF &&func) -> Future< typename std::decay< typename std::result_of< AF(ValueType)>::type >::type >
Same as andThen(), but with type defaulted to FutureCallbackType_Auto.
Definition: future_fwd.hpp:516
Future< R > thenR(FutureCallbackType type, AF &&func)
Execute a callback when the future is finished.
Definition: future.hxx:58
FutureSync< T > & operator=(const Future< T > &b)
Definition: future_fwd.hpp:683
auto andThen(FutureCallbackType type, F &&func) -> Future< typename std::decay< typename std::result_of< F(ValueType)>::type >::type >
Same as then(), but the callback is called only if this future finishes with a value.
Definition: future_fwd.hpp:506
FutureState waitFor(qi::Duration duration) const
Definition: future_fwd.hpp:306
bool isRunning() const
Definition: future_fwd.hpp:755
void setCanceled()
Definition: future_fwd.hpp:869
boost::function< void(Promise< T > &)> CancelCallback
Definition: future_fwd.hpp:987
FutureState wait(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:749
virtual ~FutureException()
Definition: future_fwd.hpp:158
FutureState wait(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:296
void cancel(qi::Future< T > &future)
Definition: future.hxx:176
bool hasValue(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:759
void setOnCancel(boost::function< void(qi::Promise< T > &)> cancelCallback)
Definition: future_fwd.hpp:897
friend void adaptFuture(const Future< FT > &f, Promise< PT > &p, AdaptFutureOption option)
Feed a promise from a future of possibly different type.
Definition: future.hxx:537
void futureCancelAdapter(boost::weak_ptr< FutureBaseTyped< FT > > wf)
Definition: future.hxx:496
Promise(FUNC &&cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:827
const std::string & error(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:367
Promise< T > & operator=(const Promise< T > &rhs)
Definition: future_fwd.hpp:903
bool isFinished() const
Definition: future_fwd.hpp:323
#define QI_NOEXCEPT_EXPR(expr)
Specify that a function may throw if the given expression may throw. Do nothing if noexcept is not av...
Definition: macro.hpp:325
bool hasValue(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:358
const ValueType & value(int msecs=FutureTimeout_Infinite) const
Return the value associated to a Future.
Definition: future_fwd.hpp:249
FutureSync(const FutureSync< T > &b)
Definition: future_fwd.hpp:660
FutureUniqueId uniqueId() const
Definition: future_fwd.hpp:737
Convenient log macro.
Promise(const qi::Promise< T > &rhs)
Definition: future_fwd.hpp:841
FutureUniqueId uniqueId() const
Definition: future_fwd.hpp:217
FutureCallbackType
Definition: future_fwd.hpp:104
std::string to_string(N n)
(Arithmetic or Enum) N
Definition: os.hpp:683
void setBroken(qi::Future< T > &future)
Definition: future.hxx:292
void setValue(const ValueType &value)
Definition: future_fwd.hpp:855
FutureSync< T > & operator=(const FutureSync< T > &b)
Definition: future_fwd.hpp:675
Promise(boost::function< void(qi::Promise< T >)> cancelCallback, FutureCallbackType async=FutureCallbackType_Auto)
Definition: future_fwd.hpp:834
Future< T > & operator=(const Future< T > &b)
Definition: future_fwd.hpp:206
void setOnCancel(const qi::Promise< T > &promise, CancelCallback onCancel)
Definition: future.hxx:194
ValueType valueCopy(Either< MilliSeconds, Infinity > timeout=Infinity{}) const
Return by copy the value associated to a Future.
Definition: future_fwd.hpp:262
bool hasError(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:758
void adaptFuture(const Future< FT > &f, Promise< PT > &p, AdaptFutureOption option)
Feed a promise from a future of possibly different type.
Definition: future.hxx:537
bool isFinished() const
Definition: future_fwd.hpp:756
void * FutureUniqueId
Definition: future_fwd.hpp:134
boost::shared_ptr< detail::FutureBaseTyped< T > > impl()
An accessor to the shared state. TODO: remove it, it should not exist.
Definition: future_fwd.hpp:588
FutureState waitUntil(qi::SteadyClock::time_point timepoint) const
Definition: future_fwd.hpp:316
void connectWithStrand(qi::Strand *strand, const boost::function< void(const Future< T > &)> &cb)
Definition: future.hxx:126
The operation is finished with a value.
Definition: future_fwd.hpp:87
typename detail::FutureType< void >::typecast ValueTypeCast
Definition: future_fwd.hpp:188
SrcFuture retract(UnitFuture)
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:308
#define QI_GEN(f)
Definition: preproc.hpp:476
Future(boost::shared_ptr< detail::FutureBaseTyped< T > > p)
The constructor from the shared state.
Definition: future_fwd.hpp:591
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:528
ValueType valueCopy(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:743
auto futurizeOutput(Proc &&p) -> decltype(ka::semilift(std::forward< Proc >(p), UnitFuture
bool hasError(int msecs=FutureTimeout_Infinite) const
Definition: future_fwd.hpp:348
MilliSeconds::rep operator()(MilliSeconds x) const
Definition: future_fwd.hpp:120