CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/CondCore/ORA/interface/UniqueRef.h

Go to the documentation of this file.
00001 #ifndef INCLUDE_ORA_UNIQUEREF_H
00002 #define INCLUDE_ORA_UNIQUEREF_H
00003 
00004 #include "Ptr.h"
00005 
00006 namespace ora {
00007 
00013   template <typename T> class UniqueRef {
00014 
00015     public:
00016     
00017     // default constructor
00018     UniqueRef();
00019     
00020     // from a real pointer
00021     explicit UniqueRef(T* anObject);
00022     
00023     // copy constructor
00024     UniqueRef(const UniqueRef<T>&); 
00025 
00026     // extended copy constructor
00027     template <class C> UniqueRef(const UniqueRef<C>&);  
00028 
00029     // destructor
00030     virtual ~UniqueRef();
00031 
00032     // Assignment operator with real pointer 
00033     UniqueRef<T>& operator=(T*);
00034 
00035     // assignment operator
00036     UniqueRef<T>& operator=(const UniqueRef<T>&);
00037 
00038     // extended assignment operator 
00039     template <class C> UniqueRef<T>& operator=(const UniqueRef<C>&);
00040 
00041     // copy operator for up/down casting 
00042     template <class C> UniqueRef<T>& cast(const UniqueRef<C>&);
00043 
00044     // dereference operator
00045     T* operator->() const;
00046 
00047     // dereference operator
00048     T& operator*() const;
00049 
00050     // implicit bool conversion
00051     operator bool () const;
00052 
00053     // return the real pointer
00054     T* get() const;
00055 
00056     // return the shared ptr
00057     boost::shared_ptr<T>& share() const;
00058 
00059     // return the naked pointer, without to trigger the loading.
00060     void* address() const;
00061 
00062     // return the real ptr type
00063     const std::type_info* typeInfo() const;
00064       
00065     // 'not' operator for consistency with pointers common use
00066     bool operator!() const;
00067 
00068     // equality operator
00069     template <class C>
00070     bool operator==(const UniqueRef<C>& aPtr) const {
00071       return m_ptr == static_cast<C*>(aPtr.address());
00072     }
00073     template <class C>
00074     bool operator!=(const UniqueRef<C>& aPtr) const {
00075       return !(this->operator==(aPtr));     
00076     }
00077     
00078     public:
00079 
00080     // clear the embedded pointer and invalidates the loader,if any.
00081     void reset();
00082 
00083     // returns the current loader
00084     boost::shared_ptr<IPtrLoader>& loader() const {
00085       return m_loader;
00086     }
00087 
00088     // returns true if the emebedded object data have been loaded.
00089     bool isLoaded() const {
00090       return m_isLoaded;
00091     }
00092     
00093     private:
00094     
00095     // pointer with throw exception clause
00096     T* ptr(bool throw_flag) const;
00097 
00098   private:
00099 
00100     // embedded object pointer
00101     mutable boost::shared_ptr<T> m_ptr;
00102 
00103     // data loader, istalled by the storage system
00104     mutable boost::shared_ptr<IPtrLoader> m_loader;
00105 
00106     // object loaded flag
00107     mutable bool m_isLoaded;
00108 
00109   };
00110   
00111   
00112 }
00113 
00114 template <class T> ora::UniqueRef<T>::UniqueRef() :
00115   m_ptr(),m_loader(),m_isLoaded(false) {}
00116 
00117 template <class T> ora::UniqueRef<T>::UniqueRef(T* anObject) :
00118   m_ptr(anObject),m_loader(),m_isLoaded(true) {}
00119 
00120 template <class T> ora::UniqueRef<T>::UniqueRef(const UniqueRef<T>& aPtr) :
00121   m_ptr(aPtr.m_ptr),m_loader(aPtr.m_loader),m_isLoaded(false){
00122 }
00123 
00124 template <class T> 
00125 template <class C> ora::UniqueRef<T>::UniqueRef(const UniqueRef<C>& aPtr) :
00126   m_ptr(aPtr.share()),m_loader(aPtr.loader()),m_isLoaded(aPtr.isLoaded()) {
00127   // compile-time type checking
00128   C* c = 0; T* t(c); assert(t==0);
00129 }
00130 
00131 template <class T> ora::UniqueRef<T>::~UniqueRef() {
00132 }
00133 
00134 template <class T> ora::UniqueRef<T>& ora::UniqueRef<T>::operator=(T* aPtr) {
00135   reset();
00136   m_ptr.reset(aPtr);
00137   m_isLoaded = true;
00138   return *this;
00139 }
00140 
00141 template <class T> ora::UniqueRef<T>& ora::UniqueRef<T>::operator=(const UniqueRef<T>& aPtr){
00142   reset();
00143   m_loader = aPtr.m_loader;
00144   m_ptr = aPtr.m_ptr;
00145   m_isLoaded = aPtr.m_isLoaded;
00146   return *this;  
00147 }
00148 
00149 template <class T> 
00150 template <class C> ora::UniqueRef<T>& ora::UniqueRef<T>::operator=(const UniqueRef<C>& aPtr){
00151   C* c = 0; T* t(c); assert(t==0);
00152   reset();
00153   m_loader = aPtr.loader();
00154   m_ptr = aPtr.share();
00155   m_isLoaded = aPtr.isLoaded();
00156   return *this;  
00157 }
00158 
00159 template <class T> template <class C> ora::UniqueRef<T>& ora::UniqueRef<T>::cast(const UniqueRef<C>& aPtr){
00160   reset();
00161   m_loader = aPtr.loader();
00162   m_ptr = boost::dynamic_pointer_cast(aPtr.share());
00163   m_isLoaded = aPtr.isLoaded();
00164   return *this;  
00165 }
00166 
00167 template <class T> T* ora::UniqueRef<T>::operator->() const {
00168   return ptr(true);
00169 }
00170 
00171 template <class T> T& ora::UniqueRef<T>::operator*() const {
00172   return *ptr(true);
00173 }
00174 
00175 template <class T> T* ora::UniqueRef<T>::get() const  {
00176   return ptr(false);  
00177 }
00178 
00179 template <class T>
00180 inline boost::shared_ptr<T>& ora::UniqueRef<T>::share() const {
00181   return m_ptr;
00182 }
00183 
00184 template <class T> void* ora::UniqueRef<T>::address() const  {
00185   return m_ptr.get();  
00186 }
00187 
00188 template <class T> const std::type_info* ora::UniqueRef<T>::typeInfo() const  {
00189   const std::type_info* ret = 0;
00190   if(m_ptr) ret = &typeid(*m_ptr);
00191   return ret;
00192 }
00193 
00194 template <class T> ora::UniqueRef<T>::operator bool() const {
00195   return ptr(false);
00196 }
00197 
00198 template <class T> bool ora::UniqueRef<T>::operator!() const {
00199   return ptr(false)==0;
00200 }
00201 
00202 template <class T> void ora::UniqueRef<T>::reset(){
00203   m_ptr.reset();
00204   m_loader.reset();
00205   m_isLoaded = false;
00206 }
00207 
00208 template <class T> T* ora::UniqueRef<T>::ptr(bool throwFlag) const {
00209   if(!m_ptr.get()){
00210     if(!m_loader.get()){
00211       if(throwFlag) throwException("Loader is not installed.",
00212                                    "UniqueRef::ptr()");
00213     }
00214     if(!m_isLoaded && m_loader.get()){
00215       m_ptr.reset( static_cast<T*>(m_loader->load()));
00216       m_isLoaded = true;
00217     }
00218   }
00219   if(!m_ptr.get()){
00220     if(throwFlag) throwException("Underlying pointer is null.",
00221                                  "UniqueRef::ptr()");    
00222   }
00223   return m_ptr.get();
00224 }
00225 
00226 #endif