diff options
Diffstat (limited to 'kig/misc/boost_intrusive_pointer.hpp')
-rw-r--r-- | kig/misc/boost_intrusive_pointer.hpp | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/kig/misc/boost_intrusive_pointer.hpp b/kig/misc/boost_intrusive_pointer.hpp new file mode 100644 index 00000000..a278e736 --- /dev/null +++ b/kig/misc/boost_intrusive_pointer.hpp @@ -0,0 +1,256 @@ +// Copyright (C) 2003 Dominique Devriese <devriese@kde.org> + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + + + +// This code comes from the boost::intrusive_ptr. I adapted it to +// suit my needs ( no dependencies on other boost libs, change the +// namespace to avoid conflicts, + +#ifndef MYBOOST_INTRUSIVE_PTR_HPP_INCLUDED +#define MYBOOST_INTRUSIVE_PTR_HPP_INCLUDED + +// +// intrusive_ptr.hpp +// +// Copyright (c) 2001, 2002 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation. +// + +#include <functional> // for std::less +#include <iosfwd> // for std::basic_ostream + + +namespace myboost +{ + +// +// intrusive_ptr +// +// A smart pointer that uses intrusive reference counting. +// +// Relies on unqualified calls to +// +// void intrusive_ptr_add_ref(T * p); +// void intrusive_ptr_release(T * p); +// +// (p != 0) +// +// The object is responsible for destroying itself. +// + +template<class T> class intrusive_ptr +{ +private: + + typedef intrusive_ptr this_type; + +public: + + typedef T element_type; + + intrusive_ptr(): p_(0) + { + } + + intrusive_ptr(T * p, bool add_ref = true): p_(p) + { + if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get()) + { + if(p_ != 0) intrusive_ptr_add_ref(p_); + } + +#endif + + intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_) + { + if(p_ != 0) intrusive_ptr_add_ref(p_); + } + + ~intrusive_ptr() + { + if(p_ != 0) intrusive_ptr_release(p_); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + +#endif + + intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + intrusive_ptr & operator=(T * rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + T * get() const + { + return p_; + } + + T & operator*() const + { + return *p_; + } + + T * operator->() const + { + return p_; + } + + typedef T * (intrusive_ptr::*unspecified_bool_type) () const; + + operator unspecified_bool_type () const + { + return p_ == 0? 0: &intrusive_ptr::get; + } + + // operator! is a Borland-specific workaround + bool operator! () const + { + return p_ == 0; + } + + void swap(intrusive_ptr & rhs) + { + T * tmp = p_; + p_ = rhs.p_; + rhs.p_ = tmp; + } + +private: + + T * p_; +}; + +template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) +{ + return a.get() == b.get(); +} + +template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) +{ + return a.get() != b.get(); +} + +template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b) +{ + return a.get() == b; +} + +template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b) +{ + return a.get() != b; +} + +template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b) +{ + return a == b.get(); +} + +template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b) +{ + return a != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) +{ + return a.get() != b.get(); +} + +#endif + +template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) +{ + return std::less<T *>()(a.get(), b.get()); +} + +template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) +{ + lhs.swap(rhs); +} + +// mem_fn support + +template<class T> T * get_pointer(intrusive_ptr<T> const & p) +{ + return p.get(); +} + +template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p) +{ + return static_cast<T *>(p.get()); +} + +template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p) +{ + return dynamic_cast<T *>(p.get()); +} + +// operator<< + +#if defined(__GNUC__) && (__GNUC__ < 3) + +template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p) +{ + os << p.get(); + return os; +} + +#else + +template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p) +{ + os << p.get(); + return os; +} + +#endif + +} // namespace myboost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef MYBOOST_INTRUSIVE_PTR_HPP_INCLUDED |