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
00018 UniqueRef();
00019
00020
00021 explicit UniqueRef(T* anObject);
00022
00023
00024 UniqueRef(const UniqueRef<T>&);
00025
00026
00027 template <class C> UniqueRef(const UniqueRef<C>&);
00028
00029
00030 virtual ~UniqueRef();
00031
00032
00033 UniqueRef<T>& operator=(T*);
00034
00035
00036 UniqueRef<T>& operator=(const UniqueRef<T>&);
00037
00038
00039 template <class C> UniqueRef<T>& operator=(const UniqueRef<C>&);
00040
00041
00042 template <class C> UniqueRef<T>& cast(const UniqueRef<C>&);
00043
00044
00045 T* operator->() const;
00046
00047
00048 T& operator*() const;
00049
00050
00051 operator bool () const;
00052
00053
00054 T* get() const;
00055
00056
00057 boost::shared_ptr<T>& share() const;
00058
00059
00060 void* address() const;
00061
00062
00063 const std::type_info* typeInfo() const;
00064
00065
00066 bool operator!() const;
00067
00068
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
00081 void reset();
00082
00083
00084 boost::shared_ptr<IPtrLoader>& loader() const {
00085 return m_loader;
00086 }
00087
00088
00089 bool isLoaded() const {
00090 return m_isLoaded;
00091 }
00092
00093 private:
00094
00095
00096 T* ptr(bool throw_flag) const;
00097
00098 private:
00099
00100
00101 mutable boost::shared_ptr<T> m_ptr;
00102
00103
00104 mutable boost::shared_ptr<IPtrLoader> m_loader;
00105
00106
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
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