15 #include "RConfigure.h" 
   19 #include <type_traits> 
   25 #if !defined(__ROOTCLING__) && !defined(G__DICTIONARY) 
   26 #error "Cannot use ROOT::Experimental::Async without defining R__USE_IMT." 
   33 namespace Experimental {
 
   42    friend class Experimental::TFuture;
 
   45    using TTaskGroup = Experimental::TTaskGroup;
 
   46    std::future<T> fStdFut;
 
   47    std::unique_ptr<TTaskGroup> fTg{
nullptr};
 
   49    TFutureImpl(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg) : fStdFut(std::move(fut))
 
   55    TFutureImpl(std::future<T> &&fut) : fStdFut(std::move(fut)) {}
 
   57    TFutureImpl(TFutureImpl<T> &&other) : fStdFut(std::move(other.fStdFut)), fTg(std::move(other.fTg)) {}
 
   59    TFutureImpl &operator=(std::future<T> &&other) { fStdFut = std::move(other); }
 
   61    TFutureImpl<T> &operator=(TFutureImpl<T> &&other) = 
default;
 
   64    TFutureImpl<T> &operator=(TFutureImpl<T> &other) = 
delete;
 
   66    TFutureImpl(
const TFutureImpl<T> &other) = 
delete;
 
   74    bool valid()
 const { 
return fStdFut.valid(); };
 
   78 namespace Experimental {
 
   83 class TFuture final : 
public ROOT::Detail::TFutureImpl<T> {
 
   84    template <
class Function, 
class... Args>
 
   86       typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
 
   87    Async(Function &&f, Args &&... args);
 
   90    TFuture(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg)
 
   91       : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut), std::move(tg)){};
 
   94    TFuture(std::future<T> &&fut) : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut)){};
 
   99       return this->fStdFut.get();
 
  105 class TFuture<void> final : 
public ROOT::Detail::TFutureImpl<void> {
 
  106    template <
class Function, 
class... Args>
 
  108       typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
 
  109    Async(Function &&f, Args &&... args);
 
  112    TFuture(std::future<void> &&fut, std::unique_ptr<TTaskGroup> &&tg)
 
  113       : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut), std::move(tg)){};
 
  116    TFuture(std::future<void> &&fut) : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut)){};
 
  125 template <
typename T>
 
  126 class TFuture<T &> 
final : 
public ROOT::Detail::TFutureImpl<T &> {
 
  127    template <
class Function, 
class... Args>
 
  129       typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
 
  130    Async(Function &&f, Args &&... args);
 
  133    TFuture(std::future<T &> &&fut, std::unique_ptr<TTaskGroup> &&tg)
 
  134       : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut), std::move(tg)){};
 
  137    TFuture(std::future<T &> &&fut) : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut)){};
 
  142       return this->fStdFut.get();
 
  150 template <
class Function, 
class... Args>
 
  151 TFuture<typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type>
 
  152 Async(Function &&f, Args &&... args)
 
  158    using Ret_t = 
typename std::result_of<typename std::decay<Function>::type(
typename std::decay<Args>::type...)>::type;
 
  160    auto thisPt = std::make_shared<std::packaged_task<Ret_t()>>(std::bind(f, args...));
 
  161    std::unique_ptr<ROOT::Experimental::TTaskGroup> tg(
new ROOT::Experimental::TTaskGroup());
 
  162    tg->Run([thisPt]() { (*thisPt)(); });
 
  164    return ROOT::Experimental::TFuture<Ret_t>(thisPt->get_future(), std::move(tg));