OW_COWIntrusiveReference.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 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 
00031 //
00032 //  Copyright (c) 2001, 2002 Peter Dimov
00033 //
00034 //  Permission to copy, use, modify, sell and distribute this software
00035 //  is granted provided this copyright notice appears in all copies.
00036 //  This software is provided "as is" without express or implied
00037 //  warranty, and with no claim as to its suitability for any purpose.
00038 //
00039 
00045 #ifndef OW_COW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00046 #define OW_COW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00047 
00048 #include "OW_config.h"
00049 
00050 namespace OW_NAMESPACE
00051 {
00052 
00053 #ifdef OW_CHECK_NULL_REFERENCES
00054 namespace COWIntrusiveReferenceHelpers
00055 {
00056    // these are not part of COWIntrusiveReference to try and avoid template bloat.
00057    OW_COMMON_API void throwNULLException();
00058    inline void checkNull(const void* p)
00059    {
00060       if (p == 0)
00061       {
00062          throwNULLException();
00063       }
00064    }
00065 }
00066 #endif
00067 
00090 template<class T> class COWIntrusiveReference
00091 {
00092 private:
00093    typedef COWIntrusiveReference this_type;
00094 public:
00095    typedef T element_type;
00096 
00097    COWIntrusiveReference(): m_pObj(0)
00098    {
00099    }
00100    COWIntrusiveReference(T * p, bool addRef = true): m_pObj(p)
00101    {
00102       if (m_pObj != 0 && addRef) COWIntrusiveReferenceAddRef(m_pObj);
00103    }
00104    template<class U> COWIntrusiveReference(COWIntrusiveReference<U> const & rhs): m_pObj(rhs.m_pObj)
00105    {
00106       if (m_pObj != 0) COWIntrusiveReferenceAddRef(m_pObj);
00107    }
00108    COWIntrusiveReference(COWIntrusiveReference const & rhs): m_pObj(rhs.m_pObj)
00109    {
00110       if (m_pObj != 0) COWIntrusiveReferenceAddRef(m_pObj);
00111    }
00112    ~COWIntrusiveReference()
00113    {
00114       if (m_pObj != 0) COWIntrusiveReferenceRelease(m_pObj);
00115    }
00116    template<class U> COWIntrusiveReference & operator=(COWIntrusiveReference<U> const & rhs)
00117    {
00118       this_type(rhs).swap(*this);
00119       return *this;
00120    }
00121    COWIntrusiveReference & operator=(COWIntrusiveReference const & rhs)
00122    {
00123       this_type(rhs).swap(*this);
00124       return *this;
00125    }
00126    COWIntrusiveReference & operator=(T * rhs)
00127    {
00128       this_type(rhs).swap(*this);
00129       return *this;
00130    }
00131    const T * getPtr() const
00132    {
00133       return m_pObj;
00134    }
00135    
00136    const T & operator*() const
00137    {
00138 #ifdef OW_CHECK_NULL_REFERENCES
00139       COWIntrusiveReferenceHelpers::checkNull(this);
00140       COWIntrusiveReferenceHelpers::checkNull(m_pObj);
00141 #endif
00142       return *m_pObj;
00143    }
00144    
00145    const T * operator->() const
00146    {
00147 #ifdef OW_CHECK_NULL_REFERENCES
00148       COWIntrusiveReferenceHelpers::checkNull(this);
00149       COWIntrusiveReferenceHelpers::checkNull(m_pObj);
00150 #endif
00151       return m_pObj;
00152    }
00153 
00154    T & operator*()
00155    {
00156 #ifdef OW_CHECK_NULL_REFERENCES
00157       COWIntrusiveReferenceHelpers::checkNull(this);
00158       COWIntrusiveReferenceHelpers::checkNull(m_pObj);
00159 #endif
00160       getWriteLock();
00161       return *m_pObj;
00162    }
00163    
00164    T * operator->()
00165    {
00166 #ifdef OW_CHECK_NULL_REFERENCES
00167       COWIntrusiveReferenceHelpers::checkNull(this);
00168       COWIntrusiveReferenceHelpers::checkNull(m_pObj);
00169 #endif
00170       getWriteLock();
00171       return m_pObj;
00172    }
00173 
00174    typedef T * this_type::*unspecified_bool_type;
00175    operator unspecified_bool_type () const
00176    {
00177       return m_pObj == 0? 0: &this_type::m_pObj;
00178    }
00179 
00180    bool operator! () const
00181    {
00182       return m_pObj == 0;
00183    }
00184    
00185    void swap(COWIntrusiveReference & rhs)
00186    {
00187       T * tmp = m_pObj;
00188       m_pObj = rhs.m_pObj;
00189       rhs.m_pObj = tmp;
00190    }
00191 
00192 #if !defined(__GNUC__) || __GNUC__ > 2 // causes gcc 2.95 to ICE
00193    /* This is so the templated constructor will work */
00194    template <class U> friend class COWIntrusiveReference;
00195 private:
00196 #endif
00197 
00198    void getWriteLock()
00199    {
00200       if ((m_pObj != 0) && !COWIntrusiveReferenceUnique(m_pObj))
00201       {
00202          m_pObj = COWIntrusiveReferenceClone(m_pObj);
00203       }
00204    }
00205 
00206 
00207    T * m_pObj;
00208 };
00209 template<class T, class U> inline bool operator==(COWIntrusiveReference<T> const & a, COWIntrusiveReference<U> const & b)
00210 {
00211    return a.getPtr() == b.getPtr();
00212 }
00213 template<class T, class U> inline bool operator!=(COWIntrusiveReference<T> const & a, COWIntrusiveReference<U> const & b)
00214 {
00215    return a.getPtr() != b.getPtr();
00216 }
00217 template<class T> inline bool operator==(COWIntrusiveReference<T> const & a, const T * b)
00218 {
00219    return a.getPtr() == b;
00220 }
00221 template<class T> inline bool operator!=(COWIntrusiveReference<T> const & a, const T * b)
00222 {
00223    return a.getPtr() != b;
00224 }
00225 template<class T> inline bool operator==(const T * a, COWIntrusiveReference<T> const & b)
00226 {
00227    return a == b.getPtr();
00228 }
00229 template<class T> inline bool operator!=(const T * a, COWIntrusiveReference<T> const & b)
00230 {
00231    return a != b.getPtr();
00232 }
00233 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00234 // Resolve the ambiguity between our op!= and the one in rel_ops
00235 template<class T> inline bool operator!=(COWIntrusiveReference<T> const & a, COWIntrusiveReference<T> const & b)
00236 {
00237    return a.getPtr() != b.getPtr();
00238 }
00239 #endif
00240 template<class T> inline bool operator<(COWIntrusiveReference<T> const & a, COWIntrusiveReference<T> const & b)
00241 {
00242    return a.getPtr() < b.getPtr();
00243 }
00244 template<class T> void swap(COWIntrusiveReference<T> & lhs, COWIntrusiveReference<T> & rhs)
00245 {
00246    lhs.swap(rhs);
00247 }
00248 
00249 } // end namespace OW_NAMESPACE
00250 
00251 #endif
00252 

Generated on Thu Feb 9 08:47:57 2006 for openwbem by  doxygen 1.4.6