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