X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h diff --git a/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h b/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h new file mode 100644 index 0000000..d0f3122 --- /dev/null +++ b/interpreter/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h @@ -0,0 +1,133 @@ +/* + + 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 + +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 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 + SMARTP(const SMARTP& 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 + 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& p_) const { return fSmartPtr < ((T *) p_); } + //! operator = to support inherited class reference + SMARTP& operator=(const SMARTP& p_) { return operator=((T *) p_); } + //! dynamic cast support + template SMARTP& cast(T2* p_) { return operator=(dynamic_cast(p_)); } + //! dynamic cast support + template SMARTP& cast(const SMARTP& p_) { return operator=(dynamic_cast(p_)); } +}; + +} + +#endif