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_