00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #ifndef OW_REFERENCE_HPP_
00037 #define OW_REFERENCE_HPP_
00038 #include "OW_config.h"
00039 #include "OW_ReferenceBase.hpp"
00040
00041 namespace OW_NAMESPACE
00042 {
00043
00045 template<class T>
00046 class Reference :
00047 #if !defined(__GNUC__) || __GNUC__ > 2
00048 private ReferenceBase
00049 #else
00050 public ReferenceBase
00051 #endif
00052 {
00053 public:
00054 typedef T element_type;
00055
00056 Reference();
00057 explicit Reference(T* ptr);
00058 Reference(const Reference<T>& arg);
00059
00060
00061
00062 template <class U>
00063 Reference(const Reference<U>& arg);
00064 ~Reference();
00065 Reference<T>& operator= (const Reference<T>& arg);
00066 Reference<T>& operator= (T* newObj);
00067 void swap(Reference<T>& arg);
00068 T* operator->() const;
00069 T& operator*() const;
00070 T* getPtr() const;
00071 bool isNull() const OW_DEPRECATED;
00072 typedef T* volatile Reference::*safe_bool;
00073 operator safe_bool () const
00074 { return (m_pObj ? &Reference::m_pObj : 0); }
00075 bool operator!() const
00076 { return !m_pObj; }
00077 template <class U>
00078 Reference<U> cast_to() const;
00079 template <class U>
00080 void useRefCountOf(const Reference<U>&);
00081 #if !defined(__GNUC__) || __GNUC__ > 2 // causes gcc 2.95 to ICE
00082
00083 template <class U> friend class Reference;
00084 private:
00085 #endif
00086 void decRef();
00087 T* volatile m_pObj;
00088 };
00090 template<class T>
00091 inline Reference<T>::Reference()
00092 : ReferenceBase(), m_pObj(0)
00093 {
00094 }
00096 template<class T>
00097 inline Reference<T>::Reference(T* ptr)
00098 : ReferenceBase(), m_pObj(ptr)
00099 {
00100 }
00102 template<class T>
00103 inline Reference<T>::Reference(const Reference<T>& arg)
00104 : ReferenceBase(arg), m_pObj(arg.m_pObj)
00105 {
00106 }
00108 template<class T>
00109 template<class U>
00110 inline Reference<T>::Reference(const Reference<U>& arg)
00111 : ReferenceBase(arg),
00112 m_pObj(arg.m_pObj)
00113 {
00114 }
00116 template<class T>
00117 inline Reference<T>::~Reference()
00118 {
00119
00120
00121 decRef();
00122 }
00124 template<class T>
00125 inline void Reference<T>::decRef()
00126 {
00127 typedef char type_must_be_complete[sizeof(T)];
00128 if (ReferenceBase::decRef())
00129 {
00130 delete m_pObj;
00131 }
00132 }
00134 template<class T>
00135 inline Reference<T>& Reference<T>::operator= (const Reference<T>& arg)
00136 {
00137 Reference<T>(arg).swap(*this);
00138 return *this;
00139 }
00141 template<class T>
00142 inline Reference<T>& Reference<T>::operator= (T* newObj)
00143 {
00144 Reference<T>(newObj).swap(*this);
00145 return *this;
00146 }
00148 template <class T>
00149 inline void Reference<T>::swap(Reference<T>& arg)
00150 {
00151 ReferenceBase::swap(arg);
00152 RefSwap(m_pObj, arg.m_pObj);
00153 }
00155 template<class T>
00156 inline T* Reference<T>::operator->() const
00157 {
00158 #ifdef OW_CHECK_NULL_REFERENCES
00159 checkNull(this);
00160 checkNull(m_pObj);
00161 #endif
00162
00163 return m_pObj;
00164 }
00166 template<class T>
00167 inline T& Reference<T>::operator*() const
00168 {
00169 #ifdef OW_CHECK_NULL_REFERENCES
00170 checkNull(this);
00171 checkNull(m_pObj);
00172 #endif
00173
00174 return *(m_pObj);
00175 }
00177 template<class T>
00178 inline T* Reference<T>::getPtr() const
00179 {
00180 return m_pObj;
00181 }
00183 template<class T>
00184 inline bool Reference<T>::isNull() const
00185 {
00186 return (m_pObj == 0);
00187 }
00189 template <class T>
00190 template <class U>
00191 inline Reference<U>
00192 Reference<T>::cast_to() const
00193 {
00194 Reference<U> rval;
00195 rval.m_pObj = dynamic_cast<U*>(m_pObj);
00196 if (rval.m_pObj)
00197 {
00198 rval.useRefCountOf(*this);
00199 }
00200 return rval;
00201 }
00203 template <class T>
00204 template <class U>
00205 inline void
00206 Reference<T>::useRefCountOf(const Reference<U>& arg)
00207 {
00208 ReferenceBase::useRefCountOf(arg);
00209 }
00211
00212 template <class T, class U>
00213 inline bool operator==(const Reference<T>& a, const Reference<U>& b)
00214 {
00215 return a.getPtr() == b.getPtr();
00216 }
00218 template <class T, class U>
00219 inline bool operator!=(const Reference<T>& a, const Reference<U>& b)
00220 {
00221 return a.getPtr() != b.getPtr();
00222 }
00224 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00225
00226 template <class T>
00227 inline bool operator!=(const Reference<T>& a, const Reference<T>& b)
00228 {
00229 return a.getPtr() != b.getPtr();
00230 }
00231 #endif
00232
00233 template <class T, class U>
00234 inline bool operator<(const Reference<T>& a, const Reference<U>& b)
00235 {
00236 return a.getPtr() < b.getPtr();
00237 }
00238
00239 }
00240
00241 #endif // OW_REFERENCE_HPP_