OW_IntrusiveReference.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2003-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 
00046 #ifndef OW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00047 #define OW_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00048 
00049 #include "OW_config.h"
00050 
00051 namespace OW_NAMESPACE
00052 {
00053 
00054 //
00055 //  IntrusiveReference
00056 //
00057 //  A smart pointer that uses intrusive reference counting.
00058 //
00059 //  Relies on unqualified calls to
00060 //  
00061 //      void IntrusiveReferenceAddRef(T * p);
00062 //      void IntrusiveReferenceRelease(T * p);
00063 //
00064 //          (p != 0)
00065 //
00066 //  The object is responsible for destroying itself.
00067 //
00068 
00069 
00070 template<class T> class IntrusiveReference
00071 {
00072 private:
00073    typedef IntrusiveReference this_type;
00074 public:
00075    typedef T element_type;
00076 
00077    IntrusiveReference(): m_pObj(0)
00078    {
00079    }
00080    IntrusiveReference(T * p, bool add_ref = true): m_pObj(p)
00081    {
00082       if (m_pObj != 0 && add_ref) IntrusiveReferenceAddRef(m_pObj);
00083    }
00084    template<class U> IntrusiveReference(IntrusiveReference<U> const & rhs): m_pObj(rhs.getPtr())
00085    {
00086       if (m_pObj != 0) IntrusiveReferenceAddRef(m_pObj);
00087    }
00088    IntrusiveReference(IntrusiveReference const & rhs): m_pObj(rhs.m_pObj)
00089    {
00090       if (m_pObj != 0) IntrusiveReferenceAddRef(m_pObj);
00091    }
00092    ~IntrusiveReference()
00093    {
00094       if (m_pObj != 0) IntrusiveReferenceRelease(m_pObj);
00095    }
00096    template<class U> IntrusiveReference & operator=(IntrusiveReference<U> const & rhs)
00097    {
00098       this_type(rhs).swap(*this);
00099       return *this;
00100    }
00101    IntrusiveReference & operator=(IntrusiveReference const & rhs)
00102    {
00103       this_type(rhs).swap(*this);
00104       return *this;
00105    }
00106    IntrusiveReference & operator=(T * rhs)
00107    {
00108       this_type(rhs).swap(*this);
00109       return *this;
00110    }
00111    T * getPtr() const
00112    {
00113       return m_pObj;
00114    }
00115    T & operator*() const
00116    {
00117       return *m_pObj;
00118    }
00119    T * operator->() const
00120    {
00121       return m_pObj;
00122    }
00123    typedef T * this_type::*safe_bool;
00124    operator safe_bool() const
00125    {
00126       return m_pObj == 0? 0: &this_type::m_pObj;
00127    }
00128    bool operator! () const
00129    {
00130       return m_pObj == 0;
00131    }
00132    OW_DEPRECATED bool isNull() const // in 3.1.0
00133    {
00134        return m_pObj == 0;
00135    }
00136 
00137    void swap(IntrusiveReference & rhs)
00138    {
00139       T * tmp = m_pObj;
00140       m_pObj = rhs.m_pObj;
00141       rhs.m_pObj = tmp;
00142    }
00143 
00144    template <class U>
00145    IntrusiveReference<U> cast_to() const
00146    {
00147       return IntrusiveReference<U>(dynamic_cast<U*>(m_pObj));
00148    }
00149 
00150 private:
00151    T * m_pObj;
00152 };
00153 template<class T, class U> inline bool operator==(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
00154 {
00155    return a.getPtr() == b.getPtr();
00156 }
00157 template<class T, class U> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
00158 {
00159    return a.getPtr() != b.getPtr();
00160 }
00161 template<class T> inline bool operator==(IntrusiveReference<T> const & a, T * b)
00162 {
00163    return a.getPtr() == b;
00164 }
00165 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, T * b)
00166 {
00167    return a.getPtr() != b;
00168 }
00169 template<class T> inline bool operator==(T * a, IntrusiveReference<T> const & b)
00170 {
00171    return a == b.getPtr();
00172 }
00173 template<class T> inline bool operator!=(T * a, IntrusiveReference<T> const & b)
00174 {
00175    return a != b.getPtr();
00176 }
00177 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00178 // Resolve the ambiguity between our op!= and the one in rel_ops
00179 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00180 {
00181    return a.getPtr() != b.getPtr();
00182 }
00183 #endif
00184 template<class T> inline bool operator<(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00185 {
00186    return a.getPtr() < b.getPtr();
00187 }
00188 template<class T> void swap(IntrusiveReference<T> & lhs, IntrusiveReference<T> & rhs)
00189 {
00190    lhs.swap(rhs);
00191 }
00192 template<class T, class U> IntrusiveReference<T> static_pointer_cast(IntrusiveReference<U> const & p)
00193 {
00194    return static_cast<T *>(p.getPtr());
00195 }
00196 template<class T, class U> IntrusiveReference<T> const_pointer_cast(IntrusiveReference<U> const & p)
00197 {
00198    return const_cast<T *>(p.getPtr());
00199 }
00200 template<class T, class U> IntrusiveReference<T> dynamic_pointer_cast(IntrusiveReference<U> const & p)
00201 {
00202    return dynamic_cast<T *>(p.getPtr());
00203 }
00204 
00205 } // end namespace OW_NAMESPACE
00206 
00207 #endif

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