Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:48

0001 // Author: Stefan Wunsch, Enrico Guiraud CERN  09/2020
0002 
0003 /*************************************************************************
0004  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
0005  * All rights reserved.                                                  *
0006  *                                                                       *
0007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0009  *************************************************************************/
0010 
0011 #ifndef ROOT_RDF_RRESULTHANDLE
0012 #define ROOT_RDF_RRESULTHANDLE
0013 
0014 #include "ROOT/RResultPtr.hxx"
0015 #include "ROOT/RDF/RLoopManager.hxx"
0016 #include "ROOT/RDF/RActionBase.hxx"
0017 #include "ROOT/RDF/Utils.hxx" // TypeID2TypeName
0018 
0019 #include <memory>
0020 #include <sstream>
0021 #include <typeinfo>
0022 #include <stdexcept> // std::runtime_error
0023 
0024 namespace ROOT {
0025 namespace RDF {
0026 
0027 /// \brief A type-erased version of RResultPtr and RResultMap.
0028 /// RResultHandles are used to invoke ROOT::RDF::RunGraphs() and can also be useful
0029 /// to store result pointers of different types in the same collection. Knowledge
0030 /// about the actual result type will still be needed to access it.
0031 /// \note Varied results are stripped away when a RResultMap is converted to a RResultHandle:
0032 ///       Only the nominal result will be accessible from the RResultHandle.
0033 class RResultHandle {
0034    ROOT::Detail::RDF::RLoopManager *fLoopManager = nullptr; //< Pointer to the loop manager
0035    /// Owning pointer to the action that will produce this result.
0036    /// Ownership is shared with RResultPtrs and RResultHandles that refer to the same result.
0037    std::shared_ptr<ROOT::Internal::RDF::RActionBase> fActionPtr;
0038    std::shared_ptr<void> fObjPtr; ///< Type erased shared pointer encapsulating the wrapped result
0039    /// Owning pointer to the varied action that will produce these results if any.
0040    /// Null if the RResultHandle was created from a RResultPtr, so no variations were present.
0041    std::shared_ptr<ROOT::Internal::RDF::RActionBase> fVariedActionPtr;
0042    const std::type_info *fType = nullptr; ///< Type of the wrapped result
0043 
0044    // The ROOT::RDF::RunGraphs helper has to access the loop manager to check whether two RResultHandles belong to the same computation graph
0045    friend unsigned int RunGraphs(std::vector<RResultHandle>);
0046 
0047    /// Get the pointer to the encapsulated result.
0048    /// Ownership is not transferred to the caller.
0049    /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
0050    void* Get()
0051    {
0052       if (!fActionPtr->HasRun())
0053          fLoopManager->Run();
0054       return fObjPtr.get();
0055    }
0056 
0057    /// Compare given type to the type of the wrapped result and throw if the types don't match.
0058    void CheckType(const std::type_info& type)
0059    {
0060       if (*fType != type) {
0061          std::stringstream ss;
0062          ss << "Got the type " << ROOT::Internal::RDF::TypeID2TypeName(type)
0063             << " but the RResultHandle refers to a result of type " << ROOT::Internal::RDF::TypeID2TypeName(*fType)
0064             << ".";
0065          throw std::runtime_error(ss.str());
0066       }
0067    }
0068 
0069    void ThrowIfNull()
0070    {
0071       if (fObjPtr == nullptr)
0072          throw std::runtime_error("Trying to access the contents of a null RResultHandle.");
0073    }
0074 
0075 public:
0076    template <class T>
0077    RResultHandle(const RResultPtr<T> &resultPtr) : fLoopManager(resultPtr.fLoopManager), fActionPtr(resultPtr.fActionPtr), fObjPtr(resultPtr.fObjPtr), fType(&typeid(T)) {}
0078    template <class T>
0079    RResultHandle(const Experimental::RResultMap<T> &resultMap)
0080       : fLoopManager(resultMap.fLoopManager),
0081         fActionPtr(resultMap.fNominalAction),
0082         fObjPtr(resultMap.fMap.at("nominal")),
0083         fVariedActionPtr(resultMap.fVariedAction),
0084         fType(&typeid(T))
0085    {
0086    }
0087 
0088    RResultHandle(const RResultHandle&) = default;
0089    RResultHandle(RResultHandle&&) = default;
0090    RResultHandle() = default;
0091 
0092    /// Get the pointer to the encapsulated object.
0093    /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
0094    /// If the RResultHandle was created from a RResultMap, this returns a pointer to the nominal value.
0095    /// \tparam T Type of the action result
0096    template <class T>
0097    T* GetPtr()
0098    {
0099       ThrowIfNull();
0100       CheckType(typeid(T));
0101       return static_cast<T*>(Get());
0102    }
0103 
0104    /// Get a const reference to the encapsulated object.
0105    /// Triggers event loop and execution of all actions booked in the associated RLoopManager.
0106    /// If the RResultHandle was created from a RResultMap, this returns a pointer to the nominal value.
0107    /// \tparam T Type of the action result
0108    template <class T>
0109    const T& GetValue()
0110    {
0111       ThrowIfNull();
0112       CheckType(typeid(T));
0113       return *static_cast<T*>(Get());
0114    }
0115 
0116    /// Check whether the result has already been computed
0117    ///
0118    /// ~~~{.cpp}
0119    /// std::vector<RResultHandle> results;
0120    /// results.emplace_back(df.Mean<double>("var"));
0121    /// res.IsReady(); // false, access will trigger event loop
0122    /// std::cout << res.GetValue<double>() << std::endl; // triggers event loop
0123    /// res.IsReady(); // true
0124    /// ~~~
0125    bool IsReady() const {
0126       if (fActionPtr == nullptr)
0127          return false;
0128       return fActionPtr->HasRun();
0129    }
0130 
0131    bool operator==(const RResultHandle &rhs) const
0132    {
0133       return fObjPtr == rhs.fObjPtr && fVariedActionPtr == rhs.fVariedActionPtr;
0134    }
0135 
0136    bool operator!=(const RResultHandle &rhs) const
0137    {
0138       return !(fObjPtr == rhs.fObjPtr) && fVariedActionPtr == rhs.fVariedActionPtr;
0139    }
0140 };
0141 
0142 } // namespace RDF
0143 } // namespace ROOT
0144 
0145 #endif // ROOT_RDF_RRESULTHANDLE