Logo ROOT  
Reference Guide
RResultHandle.hxx
Go to the documentation of this file.
1// Author: Stefan Wunsch, Enrico Guiraud CERN 09/2020
2
3/*************************************************************************
4 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDF_RRESULTHANDLE
12#define ROOT_RDF_RRESULTHANDLE
13
14#include "ROOT/RResultPtr.hxx"
17#include "ROOT/RDF/Utils.hxx" // TypeID2TypeName
18
19#include <memory>
20#include <sstream>
21#include <typeinfo>
22#include <stdexcept> // std::runtime_error
23
24namespace ROOT {
25namespace RDF {
26
28 ROOT::Detail::RDF::RLoopManager *fLoopManager = nullptr; //< Pointer to the loop manager
29 /// Owning pointer to the action that will produce this result.
30 /// Ownership is shared with RResultPtrs and RResultHandles that refer to the same result.
31 std::shared_ptr<ROOT::Internal::RDF::RActionBase> fActionPtr;
32 std::shared_ptr<void> fObjPtr; ///< Type erased shared pointer encapsulating the wrapped result
33 const std::type_info *fType = nullptr; ///< Type of the wrapped result
34
35 // The ROOT::RDF::RunGraphs helper has to access the loop manager to check whether two RResultHandles belong to the same computation graph
36 friend void RunGraphs(std::vector<RResultHandle>);
37
38 /// Get the pointer to the encapsulated result.
39 /// Ownership is not transferred to the caller.
40 /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
41 void* Get()
42 {
43 if (!fActionPtr->HasRun())
45 return fObjPtr.get();
46 }
47
48 /// Compare given type to the type of the wrapped result and throw if the types don't match.
49 void CheckType(const std::type_info& type)
50 {
51 if (*fType != type) {
52 std::stringstream ss;
53 ss << "Got the type " << ROOT::Internal::RDF::TypeID2TypeName(type)
54 << " but the RResultHandle refers to a result of type " << ROOT::Internal::RDF::TypeID2TypeName(*fType)
55 << ".";
56 throw std::runtime_error(ss.str());
57 }
58 }
59
61 {
62 if (fObjPtr == nullptr)
63 throw std::runtime_error("Trying to access the contents of a null RResultHandle.");
64 }
65
66public:
67 template <class T>
68 RResultHandle(const RResultPtr<T> &resultPtr) : fLoopManager(resultPtr.fLoopManager), fActionPtr(resultPtr.fActionPtr), fObjPtr(resultPtr.fObjPtr), fType(&typeid(T)) {}
69
70 RResultHandle(const RResultHandle&) = default;
72 RResultHandle() = default;
73
74 /// Get the pointer to the encapsulated object.
75 /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
76 /// \tparam T Type of the action result
77 template <class T>
79 {
81 CheckType(typeid(T));
82 return static_cast<T*>(Get());
83 }
84
85 /// Get a const reference to the encapsulated object.
86 /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
87 /// \tparam T Type of the action result
88 template <class T>
89 const T& GetValue()
90 {
92 CheckType(typeid(T));
93 return *static_cast<T*>(Get());
94 }
95
96 /// Get an RResultPtr to the encapsulated object.
97 /// \tparam T Type of the action result
98 template <class T>
100 {
101 CheckType(typeid(T));
102 return RResultPtr<T>(std::static_pointer_cast<T>(fObjPtr), fLoopManager, fActionPtr);
103 }
104
105 /// Check whether the result has already been computed
106 ///
107 /// ~~~{.cpp}
108 /// std::vector<RResultHandle> results;
109 /// results.emplace_back(df.Mean<double>("var"));
110 /// res.IsReady(); // false, access will trigger event loop
111 /// std::cout << res.GetValue<double>() << std::endl; // triggers event loop
112 /// res.IsReady(); // true
113 /// ~~~
114 bool IsReady() const {
115 if (fActionPtr == nullptr)
116 return false;
117 return fActionPtr->HasRun();
118 }
119
120 bool operator==(const RResultHandle &rhs) const
121 {
122 return fObjPtr == rhs.fObjPtr;
123 }
124
125 bool operator!=(const RResultHandle &rhs) const
126 {
127 return !(fObjPtr == rhs.fObjPtr);
128 }
129};
130
131} // namespace RDF
132} // namespace ROOT
133
134#endif // ROOT_RDF_RRESULTHANDLE
int type
Definition: TGX11.cxx:121
The head node of a RDF computation graph.
void Run()
Start the event loop with a different mechanism depending on IMT/no IMT, data source/no data source.
bool operator!=(const RResultHandle &rhs) const
T * GetPtr()
Get the pointer to the encapsulated object.
std::shared_ptr< void > fObjPtr
Type erased shared pointer encapsulating the wrapped result.
ROOT::Detail::RDF::RLoopManager * fLoopManager
void * Get()
Get the pointer to the encapsulated result.
bool IsReady() const
Check whether the result has already been computed.
std::shared_ptr< ROOT::Internal::RDF::RActionBase > fActionPtr
Owning pointer to the action that will produce this result.
void CheckType(const std::type_info &type)
Compare given type to the type of the wrapped result and throw if the types don't match.
friend void RunGraphs(std::vector< RResultHandle >)
Trigger the event loop of multiple RDataFrames concurrently.
RResultPtr< T > GetResultPtr()
Get an RResultPtr to the encapsulated object.
RResultHandle(const RResultPtr< T > &resultPtr)
RResultHandle(const RResultHandle &)=default
const T & GetValue()
Get a const reference to the encapsulated object.
RResultHandle(RResultHandle &&)=default
const std::type_info * fType
Type of the wrapped result.
bool operator==(const RResultHandle &rhs) const
Smart pointer for the return type of actions.
Definition: RResultPtr.hxx:95
std::string TypeID2TypeName(const std::type_info &id)
Returns the name of a type starting from its type_info An empty string is returned in case of failure...
Definition: RDFUtils.cxx:99
double T(double x)
Definition: ChebyshevPol.h:34
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...