OW_Reference.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *
00007  *  - Redistributions of source code must retain the above copyright notice,
00008  *    this list of conditions and the following disclaimer.
00009  *
00010  *  - Redistributions in binary form must reproduce the above copyright notice,
00011  *    this list of conditions and the following disclaimer in the documentation
00012  *    and/or other materials provided with the distribution.
00013  *
00014  *  - Neither the name of Vintela, Inc. nor the names of its
00015  *    contributors may be used to endorse or promote products derived from this
00016  *    software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028  * POSSIBILITY OF SUCH DAMAGE.
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 // because of a gcc 2.95 ICE
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       /* construct out of a reference to a derived type.  U should be
00061       derived from T */
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; // in 3.1.0
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       /* This is so the templated constructor will work */
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    // we don't catch(...) here because nothing we do will throw, and any 
00120    // class we wrap should have a non-throwing destructor.
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 // Comparisons
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 // Resolve the ambiguity between our op!= and the one in rel_ops
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 } // end namespace OW_NAMESPACE
00240 
00241 #endif   // OW_REFERENCE_HPP_

Generated on Thu Feb 9 08:48:10 2006 for openwbem by  doxygen 1.4.6