Back to home page

EIC code displayed by LXR

 
 

    


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

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