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
00022 virtual ~IPtrLoader(){}
00023
00024 public:
00025
00026 virtual void* load() const=0;
00027
00028
00029
00030
00031
00032
00033 virtual void invalidate()=0;
00034
00035
00036 virtual bool isValid() const=0;
00037
00038 };
00039
00047 template <typename T> class Ptr {
00048
00049 public:
00050
00051
00052 Ptr();
00053
00054
00055 explicit Ptr(T* anObject);
00056
00057
00058 Ptr(const Ptr<T>&);
00059
00060
00061 template <class C> Ptr(const Ptr<C>&);
00062
00063
00064 virtual ~Ptr();
00065
00066
00067 Ptr<T>& operator=(T*);
00068
00069
00070 Ptr<T>& operator=(const Ptr<T>&);
00071
00072
00073 template <class C> Ptr<T>& operator=(const Ptr<C>&);
00074
00075
00076 template <class C> Ptr<T>& cast(const Ptr<C>&);
00077
00078
00079 T* operator->() const;
00080
00081
00082 T& operator*() const;
00083
00084
00085 operator bool () const;
00086
00087
00088 T* get() const;
00089
00090
00091 boost::shared_ptr<T>& share() const;
00092
00093
00094 void* address() const;
00095
00096
00097 bool operator!() const;
00098
00099
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
00112 void reset();
00113
00114
00115 boost::shared_ptr<IPtrLoader>& loader() const {
00116 return m_loader;
00117 }
00118
00119
00120 void load() const;
00121
00122
00123 bool isLoaded() const {
00124 return m_isLoaded;
00125 }
00126
00127 private:
00128
00129
00130 T* ptr(bool throw_flag) const;
00131
00132 private:
00133
00134
00135 mutable boost::shared_ptr<T> m_ptr;
00136
00137
00138 mutable boost::shared_ptr<IPtrLoader> m_loader;
00139
00140
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
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