author | alwin <alwin> | 2004-03-11 22:23:49 (UTC) |
---|---|---|
committer | alwin <alwin> | 2004-03-11 22:23:49 (UTC) |
commit | 31fe5681a49cbcf291abf755ee5f2f2fb1e4a582 (patch) (side-by-side diff) | |
tree | 42a95dbbcbbcb520d010aca6cfaccf6a8d33bdaa /libopie2 | |
parent | b982060527a595f52c82ac954fe8c9cc03f09c34 (diff) | |
download | opie-31fe5681a49cbcf291abf755ee5f2f2fb1e4a582.zip opie-31fe5681a49cbcf291abf755ee5f2f2fb1e4a582.tar.gz opie-31fe5681a49cbcf291abf755ee5f2f2fb1e4a582.tar.bz2 |
added a (clean-room) smart-pointer implementation to the OPIE project.
Its an implementation I had made in 1999 for some other GPL projects and is
clean-room, so would be fine someone takes a look on it.
-rw-r--r-- | libopie2/opiecore/opiecore.pro | 1 | ||||
-rw-r--r-- | libopie2/opiecore/osmart_pointer.h | 144 |
2 files changed, 145 insertions, 0 deletions
diff --git a/libopie2/opiecore/opiecore.pro b/libopie2/opiecore/opiecore.pro index b4186b1..a4080a8 100644 --- a/libopie2/opiecore/opiecore.pro +++ b/libopie2/opiecore/opiecore.pro @@ -9,4 +9,5 @@ HEADERS = oapplication.h \ oprocess.h \ oprocctrl.h \ + osmart_pointer.h \ ostorageinfo.h \ xmltree.h diff --git a/libopie2/opiecore/osmart_pointer.h b/libopie2/opiecore/osmart_pointer.h new file mode 100644 index 0000000..a362a60 --- a/dev/null +++ b/libopie2/opiecore/osmart_pointer.h @@ -0,0 +1,144 @@ +// -*- Mode: C++; -*- +/* + This file is part of the Opie Project + Copyright (C) 2004 Rajko Albrecht <alwin@handhelds.org> + Copyright (C) The Opie Team <opie-devel@handhelds.org> + =. + .=l. + .>+-= +_;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software +- . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. 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 +..}^=.= = ; Library General Public License for more +++= -. .` .: details. +: = ...= . :.=- +-. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _osmart_pointer_h +#define _osmart_pointer_h + +/*! + * \file osmart_pointer.h + * \brief smart pointer and reference counter + * \author Rajko Albrecht + * + */ + +namespace Opie { + +//! simple reference counter class +class oref_count { +protected: + //! reference count member + long m_RefCount; +public: + //! first reference must be added after "new" via Pointer() + oref_count() : m_RefCount(0) + {} + virtual ~oref_count() {} + //! add a reference + void Incr() { + ++m_RefCount; + } + //! delete a reference + void Decr() { + --m_RefCount; + } + //! is it referenced + bool Shared() { return (m_RefCount > 0); } +}; + +//! reference counting wrapper class +template<class T> class osmart_pointer { + //! pointer to object + /*! + * this object must contain Incr(), Decr() and Shared() + * methode as public members. The best way is, that it will be a child + * class of RefCount + */ + T *ptr; +public: + //! standart constructor + osmart_pointer() { ptr = NULL; } + //! standart destructor + /*! + * release the reference, if it were the last reference, destroys + * ptr + */ + ~osmart_pointer() + { + if (ptr){ + ptr->Decr(); + if (!ptr->Shared()) + delete ptr; + } + } + //! construction + osmart_pointer(T* t) { if (ptr = t) ptr->Incr(); } + //! Pointer copy + osmart_pointer(const smart_pointer<T>& p) + { if (ptr = p.ptr) ptr->Incr(); } + //! pointer copy by assignment + osmart_pointer<T>& operator= (const smart_pointer<T>& p) + { + // already same: nothing to do + if (ptr == p.ptr) return *this; + // decouple reference + if (ptr) { ptr->Decr(); if (!ptr->Shared()) delete ptr; } + // establish new reference + if (ptr = p.ptr) ptr->Incr(); + return *this; + } + osmart_pointer<T>& operator= (T*p) + { + if (ptr==p)return *this; + if (ptr) { + ptr->Decr(); + if (!ptr->Shared()) delete ptr; + } + if (ptr=p) ptr->Incr(); + return *this; + } + + //! cast to conventional pointer + operator T* () const { return ptr; } + + //! deref: fails for NULL pointer + T& operator* () {return *ptr; } + //! deref: fails for NULL pointer + const T& operator* ()const {return *ptr; } + + //! deref with method call + T* operator-> () {return ptr; } + //! deref with const method call + const T* operator-> ()const {return ptr; } + + //! supports "if (pointer)" + operator bool () const { return (ptr != NULL); } + //! "if (pointer)" as non const + operator bool () { return ptr != NULL;} + + //! support if (!pointer)" + bool operator! () const { return (ptr == NULL); } + //! support if (!pointer)" as non const + bool operator! () { return (ptr == NULL); } +}; + +} + +#endif |