CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/CondCore/ORA/interface/Ptr.h

Go to the documentation of this file.
00001 #ifndef INCLUDE_ORA_PTR_H
00002 #define INCLUDE_ORA_PTR_H
00003 
00004 #include "Exception.h"
00005 //
00006 #include <assert.h>
00007 #include <typeinfo>
00008 #include <boost/shared_ptr.hpp>
00009 
00010 namespace ora {
00011 
00018   class IPtrLoader {
00019     
00020     public:
00021     // destructor
00022     virtual ~IPtrLoader(){}
00023 
00024     public:
00025     // triggers the data loading
00026     virtual void* load() const=0;
00027 
00028     // notify the underlying storage system that the embedded object has been destructed.
00029     // maybe not required.
00030     //virtual void notify() const=0;
00031 
00032     // invalidates the current loader. Called by the underlying service at his destruction time.
00033     virtual void invalidate()=0;
00034 
00035     // queries the validity of the current relation with the underlying storage system
00036     virtual bool isValid() const=0;
00037 
00038   };
00039   
00047   template <typename T> class Ptr {
00048 
00049     public:
00050     
00051     // default constructor
00052     Ptr();
00053     
00054     // from a real pointer
00055     explicit Ptr(T* anObject);
00056     
00057     // copy constructor
00058     Ptr(const Ptr<T>&); 
00059 
00060     // extended copy constructor
00061     template <class C> Ptr(const Ptr<C>&);  
00062 
00063     // destructor
00064     virtual ~Ptr();
00065 
00066     // Assignment operator with real pointer 
00067     Ptr<T>& operator=(T*);
00068 
00069     // assignment operator
00070     Ptr<T>& operator=(const Ptr<T>&);
00071 
00072     // extended assignment operator 
00073     template <class C> Ptr<T>& operator=(const Ptr<C>&);
00074 
00075     // copy operator for up/down casting 
00076     template <class C> Ptr<T>& cast(const Ptr<C>&);
00077 
00078     // dereference operator
00079     T* operator->() const;
00080 
00081     // dereference operator
00082     T& operator*() const;
00083 
00084     // implicit bool conversion
00085     operator bool () const;
00086 
00087     // return the real pointer
00088     T* get() const;
00089 
00090     // return the shared ptr
00091     boost::shared_ptr<T>& share() const;
00092     
00093     // return the naked pointer, without to trigger the loading.
00094     void* address() const;
00095 
00096     // 'not' operator for consistency with pointers common use
00097     bool operator!() const;
00098 
00099     // equality operator 
00100     template <class C>
00101     bool operator==(const Ptr<C>& aPtr) const {
00102       return m_ptr == static_cast<C*>(aPtr.address());
00103     }
00104     template <class C>
00105     bool operator!=(const Ptr<C>& aPtr) const {
00106       return !(this->operator==(aPtr));     
00107     }
00108     
00109     public:
00110 
00111     // clear the embedded pointer and invalidates the loader,if any.
00112     void reset();
00113 
00114     // returns the current loader
00115     boost::shared_ptr<IPtrLoader>& loader() const {
00116       return m_loader;
00117     }
00118 
00119     // triggers the loading if the loader is installed
00120     void load() const;
00121 
00122     // returns true if the emebedded object data have been loaded.
00123     bool isLoaded() const {
00124       return m_isLoaded;
00125     }
00126     
00127     private:
00128     
00129     // pointer with throw exception clause
00130     T* ptr(bool throw_flag) const;
00131 
00132   private:
00133 
00134     // embedded object pointer
00135     mutable boost::shared_ptr<T> m_ptr;
00136 
00137     // data loader, istalled by the storage system
00138     mutable boost::shared_ptr<IPtrLoader> m_loader;
00139 
00140     // object loaded flag
00141     mutable bool m_isLoaded;
00142     
00143   };
00144   
00145 }
00146 
00147 template <class T>
00148 inline ora::Ptr<T>::Ptr() :
00149   m_ptr(),m_loader(),m_isLoaded(false) {}
00150 
00151 template <class T>
00152 inline ora::Ptr<T>::Ptr(T* anObject) :
00153   m_ptr(anObject),m_loader(),m_isLoaded(true) {}
00154 
00155 template <class T>
00156 inline ora::Ptr<T>::Ptr(const Ptr<T>& aPtr) :
00157   m_ptr(aPtr.m_ptr),m_loader(aPtr.m_loader),m_isLoaded(false){
00158 }
00159 
00160 template <class T>
00161 template <class C>
00162 inline ora::Ptr<T>::Ptr(const Ptr<C>& aPtr) :
00163   m_ptr(aPtr.share()),m_loader(aPtr.loader()),m_isLoaded(aPtr.isLoaded()) {
00164   // compile-time type checking
00165   C* c = 0; T* t(c); assert(t==0);
00166 }
00167 
00168 template <class T>
00169 inline ora::Ptr<T>::~Ptr() {
00170 }
00171 
00172 template <class T>
00173 inline ora::Ptr<T>& ora::Ptr<T>::operator=(T* aPtr) {
00174   m_ptr.reset(aPtr);
00175   m_isLoaded = true;
00176   return *this;
00177 }
00178 
00179 template <class T>
00180 inline ora::Ptr<T>& ora::Ptr<T>::operator=(const Ptr<T>& aPtr){
00181   m_loader = aPtr.m_loader;
00182   m_isLoaded = aPtr.m_isLoaded;
00183   m_ptr = aPtr.m_ptr;
00184   return *this;  
00185 }
00186 
00187 template <class T> 
00188 template <class C>
00189 inline ora::Ptr<T>& ora::Ptr<T>::operator=(const Ptr<C>& aPtr){
00190   C* c = 0; T* t(c); assert(t==0);
00191   m_loader = aPtr.loader();
00192   m_isLoaded = aPtr.isLoaded();
00193   m_ptr = aPtr.share();
00194   return *this;
00195 }
00196 
00197 template <class T>
00198 template <class C>
00199 inline ora::Ptr<T>& ora::Ptr<T>::cast(const Ptr<C>& aPtr){
00200   m_loader = aPtr.loader();
00201   m_ptr = boost::dynamic_pointer_cast( aPtr.share());
00202   m_isLoaded = aPtr.isLoaded();
00203   return *this;  
00204 }
00205 
00206 template <class T>
00207 inline T* ora::Ptr<T>::operator->() const {
00208   return ptr(true);
00209 }
00210 
00211 template <class T>
00212 inline T& ora::Ptr<T>::operator*() const {
00213   return *ptr(true);
00214 }
00215 
00216 template <class T>
00217 inline T* ora::Ptr<T>::get() const  {
00218   return ptr(false);  
00219 }
00220 
00221 template <class T>
00222 inline boost::shared_ptr<T>& ora::Ptr<T>::share() const {
00223   return m_ptr;
00224 }
00225 
00226 template <class T>
00227 inline void* ora::Ptr<T>::address() const  {
00228   return m_ptr.get();  
00229 }
00230 
00231 template <class T>
00232 inline ora::Ptr<T>::operator bool() const {
00233   return ptr(false);
00234 }
00235 
00236 template <class T>
00237 inline bool ora::Ptr<T>::operator!() const {
00238   return ptr(false)==0;
00239 }
00240 
00241 template <class T>
00242 inline void ora::Ptr<T>::reset(){
00243   m_ptr.reset();
00244   m_loader.reset();
00245   m_isLoaded = false;
00246 }
00247 
00248 template <class T>
00249 inline void ora::Ptr<T>::load() const {
00250   ptr( false );
00251 }
00252 
00253 template <class T>
00254 inline T* ora::Ptr<T>::ptr(bool throwFlag) const {
00255   if(!m_ptr.get()){
00256     if(!m_loader.get()){
00257       if(throwFlag) throwException("Loader is not installed.","Ptr::ptr()");
00258     }
00259     if(!m_isLoaded && m_loader.get()){
00260       m_ptr.reset( static_cast<T*>(m_loader->load()));
00261       m_isLoaded = true;
00262     }
00263   }
00264   if(!m_ptr.get()){
00265     if(throwFlag) throwException("Underlying pointer is null.","Ptr::ptr()");    
00266   }
00267   return m_ptr.get();
00268 }
00269 
00270 #endif