New directory tree, with preprocessor/ inside interpretor/.
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / architecture / osclib / faust / src / lib / smartpointer.h
diff --git a/interpretor/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h b/interpretor/preprocessor/faust-0.9.47mr3/architecture/osclib/faust/src/lib/smartpointer.h
new file mode 100644 (file)
index 0000000..d0f3122
--- /dev/null
@@ -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 <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