OWBI1_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 OWBI1_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00047 #define OWBI1_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00048 
00049 #include "OWBI1_config.h"
00050 
00051 namespace OWBI1
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 template<class T> class IntrusiveReference
00069 {
00070 private:
00071    typedef IntrusiveReference this_type;
00072 public:
00073    typedef T element_type;
00074 
00075    IntrusiveReference(): m_pObj(0)
00076    {
00077    }
00078    IntrusiveReference(T * p, bool add_ref = true): m_pObj(p)
00079    {
00080       if (m_pObj != 0 && add_ref) IntrusiveReferenceAddRef(m_pObj);
00081    }
00082    template<class U> IntrusiveReference(IntrusiveReference<U> const & rhs): m_pObj(rhs.getPtr())
00083    {
00084       if (m_pObj != 0) IntrusiveReferenceAddRef(m_pObj);
00085    }
00086    IntrusiveReference(IntrusiveReference const & rhs): m_pObj(rhs.m_pObj)
00087    {
00088       if (m_pObj != 0) IntrusiveReferenceAddRef(m_pObj);
00089    }
00090    ~IntrusiveReference()
00091    {
00092       if (m_pObj != 0) IntrusiveReferenceRelease(m_pObj);
00093    }
00094    template<class U> IntrusiveReference & operator=(IntrusiveReference<U> const & rhs)
00095    {
00096       this_type(rhs).swap(*this);
00097       return *this;
00098    }
00099    IntrusiveReference & operator=(IntrusiveReference const & rhs)
00100    {
00101       this_type(rhs).swap(*this);
00102       return *this;
00103    }
00104    IntrusiveReference & operator=(T * rhs)
00105    {
00106       this_type(rhs).swap(*this);
00107       return *this;
00108    }
00109    T * getPtr() const
00110    {
00111       return m_pObj;
00112    }
00113    T & operator*() const
00114    {
00115       return *m_pObj;
00116    }
00117    T * operator->() const
00118    {
00119       return m_pObj;
00120    }
00121    typedef T * this_type::*safe_bool;
00122    operator safe_bool() const
00123    {
00124       return m_pObj == 0? 0: &this_type::m_pObj;
00125    }
00126    bool operator! () const
00127    {
00128       return m_pObj == 0;
00129    }
00130 
00131    void swap(IntrusiveReference & rhs)
00132    {
00133       T * tmp = m_pObj;
00134       m_pObj = rhs.m_pObj;
00135       rhs.m_pObj = tmp;
00136    }
00137 
00138    template <class U>
00139    IntrusiveReference<U> cast_to() const
00140    {
00141       return IntrusiveReference<U>(dynamic_cast<U*>(m_pObj));
00142    }
00143 
00144 private:
00145    T * m_pObj;
00146 };
00147 template<class T, class U> inline bool operator==(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
00148 {
00149    return a.getPtr() == b.getPtr();
00150 }
00151 template<class T, class U> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
00152 {
00153    return a.getPtr() != b.getPtr();
00154 }
00155 template<class T> inline bool operator==(IntrusiveReference<T> const & a, T * b)
00156 {
00157    return a.getPtr() == b;
00158 }
00159 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, T * b)
00160 {
00161    return a.getPtr() != b;
00162 }
00163 template<class T> inline bool operator==(T * a, IntrusiveReference<T> const & b)
00164 {
00165    return a == b.getPtr();
00166 }
00167 template<class T> inline bool operator!=(T * a, IntrusiveReference<T> const & b)
00168 {
00169    return a != b.getPtr();
00170 }
00171 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00172 // Resolve the ambiguity between our op!= and the one in rel_ops
00173 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00174 {
00175    return a.getPtr() != b.getPtr();
00176 }
00177 #endif
00178 template<class T> inline bool operator<(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00179 {
00180    return a.getPtr() < b.getPtr();
00181 }
00182 template<class T> void swap(IntrusiveReference<T> & lhs, IntrusiveReference<T> & rhs)
00183 {
00184    lhs.swap(rhs);
00185 }
00186 template<class T, class U> IntrusiveReference<T> static_pointer_cast(IntrusiveReference<U> const & p)
00187 {
00188    return static_cast<T *>(p.getPtr());
00189 }
00190 template<class T, class U> IntrusiveReference<T> const_pointer_cast(IntrusiveReference<U> const & p)
00191 {
00192    return const_cast<T *>(p.getPtr());
00193 }
00194 template<class T, class U> IntrusiveReference<T> dynamic_pointer_cast(IntrusiveReference<U> const & p)
00195 {
00196    return dynamic_cast<T *>(p.getPtr());
00197 }
00198 
00199 } // end namespace OWBI1
00200 
00201 #endif

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