+++ /dev/null
-/*
-
- Copyright (C) 2011 Grame
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
- Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
- research@grame.fr
-
-*/
-
-#ifndef __smartpointer__
-#define __smartpointer__
-
-#include <cassert>
-
-namespace oscfaust
-{
-
-/*!
-\brief the base class for smart pointers implementation
-
- Any object that want to support smart pointers should
- inherit from the smartable class which provides reference counting
- and automatic delete when the reference count drops to zero.
-*/
-class smartable {
- private:
- unsigned refCount;
- public:
- //! gives the reference count of the object
- unsigned refs() const { return refCount; }
- //! addReference increments the ref count and checks for refCount overflow
- void addReference() { refCount++; assert(refCount != 0); }
- //! removeReference delete the object when refCount is zero
- void removeReference() { if (--refCount == 0) delete this; }
-
- protected:
- smartable() : refCount(0) {}
- smartable(const smartable&): refCount(0) {}
- //! destructor checks for non-zero refCount
- virtual ~smartable() { assert (refCount == 0); }
- smartable& operator=(const smartable&) { return *this; }
-};
-
-/*!
-\brief the smart pointer implementation
-
- A smart pointer is in charge of maintaining the objects reference count
- by the way of pointers operators overloading. It supports class
- inheritance and conversion whenever possible.
-\n Instances of the SMARTP class are supposed to use \e smartable types (or at least
- objects that implements the \e addReference and \e removeReference
- methods in a consistent way).
-*/
-template<class T> class SMARTP {
- private:
- //! the actual pointer to the class
- T* fSmartPtr;
-
- public:
- //! an empty constructor - points to null
- SMARTP() : fSmartPtr(0) {}
- //! build a smart pointer from a class pointer
- SMARTP(T* rawptr) : fSmartPtr(rawptr) { if (fSmartPtr) fSmartPtr->addReference(); }
- //! build a smart pointer from an convertible class reference
- template<class T2>
- SMARTP(const SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
- //! build a smart pointer from another smart pointer reference
- SMARTP(const SMARTP& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
-
- //! the smart pointer destructor: simply removes one reference count
- ~SMARTP() { if (fSmartPtr) fSmartPtr->removeReference(); }
-
- //! cast operator to retrieve the actual class pointer
- operator T*() const { return fSmartPtr; }
-
- //! '*' operator to access the actual class pointer
- T& operator*() const {
- // checks for null dereference
- assert (fSmartPtr != 0);
- return *fSmartPtr;
- }
-
- //! operator -> overloading to access the actual class pointer
- T* operator->() const {
- // checks for null dereference
- assert (fSmartPtr != 0);
- return fSmartPtr;
- }
-
- //! operator = that moves the actual class pointer
- template <class T2>
- SMARTP& operator=(T2 p1_) { *this=(T*)p1_; return *this; }
-
- //! operator = that moves the actual class pointer
- SMARTP& operator=(T* p_) {
- // check first that pointers differ
- if (fSmartPtr != p_) {
- // increments the ref count of the new pointer if not null
- if (p_ != 0) p_->addReference();
- // decrements the ref count of the old pointer if not null
- if (fSmartPtr != 0) fSmartPtr->removeReference();
- // and finally stores the new actual pointer
- fSmartPtr = p_;
- }
- return *this;
- }
- //! operator < to support SMARTP map with Visual C++
- bool operator<(const SMARTP<T>& p_) const { return fSmartPtr < ((T *) p_); }
- //! operator = to support inherited class reference
- SMARTP& operator=(const SMARTP<T>& p_) { return operator=((T *) p_); }
- //! dynamic cast support
- template<class T2> SMARTP& cast(T2* p_) { return operator=(dynamic_cast<T*>(p_)); }
- //! dynamic cast support
- template<class T2> SMARTP& cast(const SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); }
-};
-
-}
-
-#endif