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
00031
00032
00033
00039 #ifndef BLOCXX_REFERENCE_HPP_
00040 #define BLOCXX_REFERENCE_HPP_
00041 #include "blocxx/BLOCXX_config.h"
00042 #include "blocxx/ReferenceBase.hpp"
00043 #include "blocxx/ReferenceHelpers.hpp"
00044 #include "blocxx/SafeBool.hpp"
00045
00046 namespace BLOCXX_NAMESPACE
00047 {
00048
00050 template<class T>
00051 class Reference :
00052 #if !defined(__GNUC__) || __GNUC__ > 2 // because of a gcc 2.95 ICE
00053 private ReferenceBase
00054 #else
00055 public ReferenceBase
00056 #endif
00057 {
00058 public:
00059 typedef T element_type;
00060
00061 Reference();
00062 explicit Reference(T* ptr);
00063 Reference(const Reference<T>& arg);
00064
00065
00066
00067 template <class U>
00068 Reference(const Reference<U>& arg);
00069 ~Reference();
00070 Reference<T>& operator= (const Reference<T>& arg);
00071 Reference<T>& operator= (T* newObj);
00072 void swap(Reference<T>& arg);
00073 T* operator->() const;
00074 T& operator*() const;
00075 T* getPtr() const;
00076 bool isNull() const BLOCXX_DEPRECATED;
00077
00078 BLOCXX_SAFE_BOOL_IMPL(Reference, T* volatile, Reference::m_pObj, m_pObj)
00079
00080 template <class U>
00081 Reference<U> cast_to() const;
00082 template <class U>
00083 void useRefCountOf(const Reference<U>&);
00084 #if !defined(__GNUC__) || __GNUC__ > 2 // causes gcc 2.95 to ICE
00085
00086 template <class U> friend class Reference;
00087 private:
00088 #endif
00089 void decRef();
00090 T* volatile m_pObj;
00091 };
00093 template<class T>
00094 inline Reference<T>::Reference()
00095 : ReferenceBase(), m_pObj(0)
00096 {
00097 }
00099 template<class T>
00100 inline Reference<T>::Reference(T* ptr)
00101 : ReferenceBase(), m_pObj(ptr)
00102 {
00103 }
00105 template<class T>
00106 inline Reference<T>::Reference(const Reference<T>& arg)
00107 : ReferenceBase(arg), m_pObj(arg.m_pObj)
00108 {
00109 }
00111 template<class T>
00112 template<class U>
00113 inline Reference<T>::Reference(const Reference<U>& arg)
00114 : ReferenceBase(arg),
00115 m_pObj(arg.m_pObj)
00116 {
00117 }
00119 template<class T>
00120 inline Reference<T>::~Reference()
00121 {
00122
00123
00124 decRef();
00125 }
00127 template<class T>
00128 inline void Reference<T>::decRef()
00129 {
00130 typedef char type_must_be_complete[sizeof(T)];
00131 if (ReferenceBase::decRef())
00132 {
00133 delete m_pObj;
00134 }
00135 }
00137 template<class T>
00138 inline Reference<T>& Reference<T>::operator= (const Reference<T>& arg)
00139 {
00140 Reference<T>(arg).swap(*this);
00141 return *this;
00142 }
00144 template<class T>
00145 inline Reference<T>& Reference<T>::operator= (T* newObj)
00146 {
00147 Reference<T>(newObj).swap(*this);
00148 return *this;
00149 }
00151 template <class T>
00152 inline void Reference<T>::swap(Reference<T>& arg)
00153 {
00154 ReferenceBase::swap(arg);
00155 RefSwap(m_pObj, arg.m_pObj);
00156 }
00158 template<class T>
00159 inline T* Reference<T>::operator->() const
00160 {
00161 #ifdef BLOCXX_CHECK_NULL_REFERENCES
00162 ReferenceHelpers::checkNull(this);
00163 ReferenceHelpers::checkNull(m_pObj);
00164 #endif
00165
00166 return m_pObj;
00167 }
00169 template<class T>
00170 inline T& Reference<T>::operator*() const
00171 {
00172 #ifdef BLOCXX_CHECK_NULL_REFERENCES
00173 ReferenceHelpers::checkNull(this);
00174 ReferenceHelpers::checkNull(m_pObj);
00175 #endif
00176
00177 return *(m_pObj);
00178 }
00180 template<class T>
00181 inline T* Reference<T>::getPtr() const
00182 {
00183 return m_pObj;
00184 }
00186 template<class T>
00187 inline bool Reference<T>::isNull() const
00188 {
00189 return (m_pObj == 0);
00190 }
00192 template <class T>
00193 template <class U>
00194 inline Reference<U>
00195 Reference<T>::cast_to() const
00196 {
00197 Reference<U> rval;
00198 rval.m_pObj = dynamic_cast<U*>(m_pObj);
00199 if (rval.m_pObj)
00200 {
00201 rval.useRefCountOf(*this);
00202 }
00203 return rval;
00204 }
00206 template <class T>
00207 template <class U>
00208 inline void
00209 Reference<T>::useRefCountOf(const Reference<U>& arg)
00210 {
00211 ReferenceBase::useRefCountOf(arg);
00212 }
00214
00215 template <class T, class U>
00216 inline bool operator==(const Reference<T>& a, const Reference<U>& b)
00217 {
00218 return a.getPtr() == b.getPtr();
00219 }
00221 template <class T, class U>
00222 inline bool operator!=(const Reference<T>& a, const Reference<U>& b)
00223 {
00224 return a.getPtr() != b.getPtr();
00225 }
00227 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00228
00229 template <class T>
00230 inline bool operator!=(const Reference<T>& a, const Reference<T>& b)
00231 {
00232 return a.getPtr() != b.getPtr();
00233 }
00234 #endif
00235
00236 template <class T, class U>
00237 inline bool operator<(const Reference<T>& a, const Reference<U>& b)
00238 {
00239 return a.getPtr() < b.getPtr();
00240 }
00241
00242 }
00243
00244 #endif // BLOCXX_REFERENCE_HPP_