Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 09:10:05

0001 /*************************************************************************
0002  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
0003  * All rights reserved.                                                  *
0004  *                                                                       *
0005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0007  *************************************************************************/
0008 
0009 #ifndef ROOT7_Browsable_RHolder
0010 #define ROOT7_Browsable_RHolder
0011 
0012 #include "TClass.h"
0013 
0014 #include <memory>
0015 
0016 namespace ROOT {
0017 
0018 class RLogChannel;
0019 
0020 /// Log channel for Browsable diagnostics.
0021 ROOT::RLogChannel &BrowsableLog(); // implemented in RElement.cxx
0022 
0023 namespace Browsable {
0024 
0025 /** \class RHolder
0026 \ingroup rbrowser
0027 \brief Basic class for object holder of any kind. Could be used to transfer shared_ptr or unique_ptr or plain pointer
0028 \author Sergey Linev <S.Linev@gsi.de>
0029 \date 2019-10-19
0030 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
0031 */
0032 
0033 class RHolder {
0034 protected:
0035 
0036    /** Returns pointer on existing shared_ptr<T> */
0037    virtual void *GetShared() const { return nullptr; }
0038 
0039    /** Returns pointer with ownership, normally via unique_ptr<T>::release() or tobj->Clone() */
0040    virtual void *TakeObject() { return nullptr; }
0041 
0042    /** Returns plain object pointer without care about ownership, should not be used often */
0043    virtual void *AccessObject() { return nullptr; }
0044 
0045    /** Create copy of container, works only when pointer can be shared */
0046    virtual RHolder *DoCopy() const { return nullptr; }
0047 
0048 public:
0049    virtual ~RHolder() = default;
0050 
0051    /** Returns class of contained object */
0052    virtual const TClass *GetClass() const = 0;
0053 
0054    /** Returns direct (temporary) object pointer */
0055    virtual const void *GetObject() const = 0;
0056 
0057    /** Clear all pointers without performing cleanup */
0058    virtual void Forget() {}
0059 
0060    template <class T>
0061    bool InheritsFrom() const
0062    {
0063       return TClass::GetClass<T>()->InheritsFrom(GetClass());
0064    }
0065 
0066    template <class T>
0067    bool CanCastTo() const
0068    {
0069       return const_cast<TClass *>(GetClass())->GetBaseClassOffset(TClass::GetClass<T>()) >= 0;
0070    }
0071 
0072    /** Returns direct object pointer cast to provided class */
0073 
0074    template<class T>
0075    const T *Get() const
0076    {
0077       auto offset = const_cast<TClass *>(GetClass())->GetBaseClassOffset(TClass::GetClass<T>());
0078       if (offset >= 0)
0079          return (const T *) ((char *) GetObject() + offset);
0080 
0081       return nullptr;
0082    }
0083 
0084    /** Clone container. Trivial for shared_ptr and TObject holder, does not work for unique_ptr */
0085    auto Copy() const { return std::unique_ptr<RHolder>(DoCopy()); }
0086 
0087    /** Returns unique_ptr of contained object */
0088    template<class T>
0089    std::unique_ptr<T> get_unique()
0090    {
0091       // ensure that direct inheritance is used
0092       auto offset = const_cast<TClass *>(GetClass())->GetBaseClassOffset(TClass::GetClass<T>());
0093       if (offset < 0)
0094          return nullptr;
0095       auto pobj = TakeObject();
0096       if (pobj) {
0097          std::unique_ptr<T> unique;
0098          unique.reset((T *)((char *) pobj + offset));
0099          return unique;
0100       }
0101       return nullptr;
0102    }
0103 
0104    /** Returns shared_ptr of contained object */
0105    template<class T>
0106    std::shared_ptr<T> get_shared()
0107    {
0108       // ensure that direct inheritance is used
0109       if (!CanCastTo<T>())
0110          return nullptr;
0111       auto pshared = GetShared();
0112       if (pshared)
0113          return *(static_cast<std::shared_ptr<T> *>(pshared));
0114 
0115       // automatically convert unique pointer to shared
0116       return get_unique<T>();
0117    }
0118 
0119    /** Returns plains pointer on object without ownership, only can be used for TObjects */
0120    template<class T>
0121    T *get_object()
0122    {
0123       auto offset = const_cast<TClass *>(GetClass())->GetBaseClassOffset(TClass::GetClass<T>());
0124       if (offset < 0)
0125          return nullptr;
0126 
0127       return (T *) ((char *)AccessObject() + offset);
0128    }
0129 };
0130 
0131 } // namespace Browsable
0132 } // namespace ROOT
0133 
0134 
0135 #endif