Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

IntrusiveReference.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00033 //
00034 //  Copyright (c) 2001, 2002 Peter Dimov
00035 //
00036 //  Permission to copy, use, modify, sell and distribute this software
00037 //  is granted provided this copyright notice appears in all copies.
00038 //  This software is provided "as is" without express or implied
00039 //  warranty, and with no claim as to its suitability for any purpose.
00040 //
00041 
00048 #ifndef BLOCXX_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00049 #define BLOCXX_INTRUSIVE_REFERENCE_HPP_INCLUDE_GUARD_
00050 
00051 #include "blocxx/BLOCXX_config.h"
00052 
00053 namespace BLOCXX_NAMESPACE
00054 {
00055 
00056 //
00057 //  IntrusiveReference
00058 //
00059 //  A smart pointer that uses intrusive reference counting.
00060 //
00061 //  Relies on unqualified calls to
00062 //  
00063 //      void IntrusiveReferenceAddRef(T * p);
00064 //      void IntrusiveReferenceRelease(T * p);
00065 //
00066 //          (p != 0)
00067 //
00068 //  The object is responsible for destroying itself.
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 
00133    void swap(IntrusiveReference & rhs)
00134    {
00135       T * tmp = m_pObj;
00136       m_pObj = rhs.m_pObj;
00137       rhs.m_pObj = tmp;
00138    }
00139 
00140    template <class U>
00141    IntrusiveReference<U> cast_to() const
00142    {
00143       return IntrusiveReference<U>(dynamic_cast<U*>(m_pObj));
00144    }
00145 
00146 private:
00147    T * m_pObj;
00148 };
00149 template<class T, class U> inline bool operator==(IntrusiveReference<T> const & a, IntrusiveReference<U> const & b)
00150 {
00151    return a.getPtr() == b.getPtr();
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> inline bool operator==(IntrusiveReference<T> const & a, T * b)
00158 {
00159    return a.getPtr() == b;
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==(T * a, IntrusiveReference<T> const & b)
00166 {
00167    return a == b.getPtr();
00168 }
00169 template<class T> inline bool operator!=(T * a, IntrusiveReference<T> const & b)
00170 {
00171    return a != b.getPtr();
00172 }
00173 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00174 // Resolve the ambiguity between our op!= and the one in rel_ops
00175 template<class T> inline bool operator!=(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00176 {
00177    return a.getPtr() != b.getPtr();
00178 }
00179 #endif
00180 template<class T> inline bool operator<(IntrusiveReference<T> const & a, IntrusiveReference<T> const & b)
00181 {
00182    return a.getPtr() < b.getPtr();
00183 }
00184 template<class T> void swap(IntrusiveReference<T> & lhs, IntrusiveReference<T> & rhs)
00185 {
00186    lhs.swap(rhs);
00187 }
00188 template<class T, class U> IntrusiveReference<T> static_pointer_cast(IntrusiveReference<U> const & p)
00189 {
00190    return static_cast<T *>(p.getPtr());
00191 }
00192 template<class T, class U> IntrusiveReference<T> const_pointer_cast(IntrusiveReference<U> const & p)
00193 {
00194    return const_cast<T *>(p.getPtr());
00195 }
00196 template<class T, class U> IntrusiveReference<T> dynamic_pointer_cast(IntrusiveReference<U> const & p)
00197 {
00198    return dynamic_cast<T *>(p.getPtr());
00199 }
00200 
00201 } // end namespace BLOCXX_NAMESPACE
00202 
00203 #endif

Generated on Mon Sep 12 23:56:34 2005 for blocxx by  doxygen 1.4.4