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

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