diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/memutil/CMakeLists.txt | 3 | ||||
-rw-r--r-- | intern/memutil/MEM_NonCopyable.h | 58 | ||||
-rw-r--r-- | intern/memutil/MEM_RefCountPtr.h | 290 | ||||
-rw-r--r-- | intern/memutil/MEM_SmartPtr.h | 237 |
4 files changed, 588 insertions, 0 deletions
diff --git a/intern/memutil/CMakeLists.txt b/intern/memutil/CMakeLists.txt index c1ec58d8f3e..aecd3d5b6c9 100644 --- a/intern/memutil/CMakeLists.txt +++ b/intern/memutil/CMakeLists.txt @@ -36,8 +36,11 @@ set(SRC MEM_Allocator.h MEM_CacheLimiter.h MEM_CacheLimiterC-Api.h + MEM_NonCopyable.h + MEM_RefCountPtr.h MEM_RefCounted.h MEM_RefCountedC-Api.h + MEM_SmartPtr.h ) blender_add_lib(bf_intern_memutil "${SRC}" "${INC}") diff --git a/intern/memutil/MEM_NonCopyable.h b/intern/memutil/MEM_NonCopyable.h new file mode 100644 index 00000000000..92b1ded4d64 --- /dev/null +++ b/intern/memutil/MEM_NonCopyable.h @@ -0,0 +1,58 @@ +/** + * $Id$ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** + * @file MEM_NonCopyable.h + * Declaration of MEM_NonCopyable class. + */ + +#ifndef NAN_INCLUDED_NonCopyable_h +#define NAN_INCLUDED_NonCopyable_h + +/** + * Simple class that makes sure sub classes cannot + * generate standard copy constructors. + * If you want to make sure that your class does + * not have any of these cheesy hidden constructors + * inherit from this class. + */ + +class MEM_NonCopyable { +protected : + + MEM_NonCopyable( + ) { + }; + +private : + + MEM_NonCopyable (const MEM_NonCopyable *); + MEM_NonCopyable (const MEM_NonCopyable &); +}; + +#endif + diff --git a/intern/memutil/MEM_RefCountPtr.h b/intern/memutil/MEM_RefCountPtr.h new file mode 100644 index 00000000000..05a8e7d9941 --- /dev/null +++ b/intern/memutil/MEM_RefCountPtr.h @@ -0,0 +1,290 @@ +/** + * $Id$ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** + * @file MEM_RefCountPtr.h + * Declaration of MEM_RefCounted and MEM_RefCountable classes. + * @author Laurence + */ + +#ifndef NAN_INCLUDED_MEM_RefCountPtr_h +#define NAN_INCLUDED_MEM_RefCountPtr_h + +#include <stdlib.h> // for NULL ! + +/** + * @section MEM_RefCountable + * This is a base class for reference countable objects. + * If you want an object to be shared using a reference + * counted system derrivce from this class. All subclasses + * should insist that they are created on the heap, this + * can be done by makeing all constructors private and + * defining a static New() method that returns a ref counted + * ptr to a new()ly allocated instance. + * + * @section Example subclass + * + * + * class MySharedObject : public MEM_RefCountable { + * + * private : + * MySharedObject() : MEM_RefCountable() { //class specific initialization}; + * MySharedObject(const MySharedObject &other) // not implemented + * public : + * static + * MEM_RefCountPtr<MySharedObject> + * New( + * ) { + * return MEM_RefCountPtr<MySharedObject>( new MySharedObject()); + * } + * + * // other member functions + * }; + * + * Alternitively you may first wish to define a fully functional + * class and then define a reference counting wrapper for this class. + * This is useful when the base type can be used without reference + * counting. + * + * E.g. + * class UsefullClass { + * private : + * ... + * public : + * + * UsefullClass() + * UsefullMethod(...) + * AnotherUsefullMethod(...) + * }; + * + * class RcUsefullClass : public UsefullClass, public MEM_RefCountable + * { + * private : + * // Override base class public constructor --- forces + * // use of New(...) + * RcUsefullClass(...) + * public : + * + * // Override each public constructor of UsefullClass with + * // an equivalent static New method returning a MEM_RefCountPtr + * + * static + * MEM_RefCountPtr<RcUsefullClass> + * New(...){ + * return MEM_RefCountPtr<RcUsefullClass> output( + * new UsefullClass(...) + * ); + * } + * + * // warning never call destructor directly allow ref counting + * // mechanism to handle object lifetime. + * ~RcUsefullClass(); + * }; + * + * + */ + +class MEM_RefCountable { +private : + + /** + * The reference count! + * We use mutable here because we would like to + * share references of const objects! + * Maybe should think about having decRef() + * another value because we should not be deleting + * non-const objects + */ + + mutable int m_count; + +protected : + + /** + * Protected constructors + * This class is not for direct instanciation. Sub classes + * should only be allocated on the heap. + */ + + MEM_RefCountable ( + ) : + m_count (0) + { + }; + + MEM_RefCountable ( + const MEM_RefCountable & + ) : + m_count (0) + { + } + +public : + + void + IncRef( + ) const { + m_count++; + } + + int + DecRef( + ) { + return (--m_count); + } + + ~MEM_RefCountable( + ) { + //nothing to do + } +}; + +/** + * @section MEM_RefCountPtr + */ + +template + < class T > +class MEM_RefCountPtr { + +public : + + /** + * Construction from reference - share ownership with + * the right hand side. + */ + + MEM_RefCountPtr( + const MEM_RefCountPtr &rhs + ) : m_val (NULL) { + ShareOwnership(rhs.m_val); + } + + /** + * Construction from ptr - this class shares + * ownership of object val. + */ + + MEM_RefCountPtr( + const T* val + ) : + m_val (NULL) + { + ShareOwnership(val); + } + + /** + * Default constructor + */ + + MEM_RefCountPtr( + ) : + m_val (NULL) + { + } + + /** + * Type conversion from this class to the type + * of a pointer to the template parameter. + * This means you can pass an instance of this class + * to a function expecting a ptr of type T. + */ + + operator T * () const { + return m_val; + } + + + MEM_RefCountPtr & operator=( + const MEM_RefCountPtr &rhs + ) { + if (this->m_val != rhs.m_val) { + ReleaseOwnership(); + ShareOwnership(rhs.m_val); + } + return *this; + } + + /** + * Overload the operator -> so that it's possible to access + * all the normal methods of the internal ptr. + */ + + T * operator->() const { + return m_val; + } + + /** + * Returrn a reference to the shared object. + */ + + T& + Ref( + ) { + return *m_val; + } + + + /** + * Destructor - deletes object if it's ref count is zero. + */ + + ~MEM_RefCountPtr( + ) { + ReleaseOwnership(); + } + +private : + + /// The ptr owned by this class. + T * m_val; + + void + ShareOwnership( + const T * val + ) { + if (val != NULL) { + val->IncRef(); + } + m_val = const_cast<T *>(val); + } + + void + ReleaseOwnership( + ) { + if (m_val) { + if (m_val->DecRef() == 0) { + delete(m_val); + m_val = NULL; + } + } + } + +}; + +#endif + diff --git a/intern/memutil/MEM_SmartPtr.h b/intern/memutil/MEM_SmartPtr.h new file mode 100644 index 00000000000..4d7ce1add00 --- /dev/null +++ b/intern/memutil/MEM_SmartPtr.h @@ -0,0 +1,237 @@ +/** + * $Id$ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +/** + * @file MEM_SmartPtr.h + * Declaration of MEM_RefCounted and MEM_RefCountable classes. + * @author Laurence + */ + +#ifndef NAN_INCLUDED_MEM_SmartPtr_h +#define NAN_INCLUDED_MEM_SmartPtr_h + + +#include <stdlib.h> // for NULL ! + + +/** + * @section MEM_SmartPtr + * This class defines a smart pointer similar to that defined in + * the Standard Template Library but without the painful get() + * semantics to access the internal c style pointer. + * + * It is often useful to explicitely decalre ownership of memory + * allocated on the heap within class or function scope. This + * class helps you to encapsulate this ownership within a value + * type. When an instance of this class goes out of scope it + * makes sure that any memory associated with it's internal pointer + * is deleted. It can help to inform users of an aggregate class + * that it owns instances of it's members and these instances + * should not be shared. This is not reliably enforcable in C++ + * but this class attempts to make the 1-1 relationship clear. + * + * @section Example usage + * + * class foo { + * ...constructors accessors etc. + * int x[1000]; + * } + * + * class bar { + * public : + * static + * bar * + * New( + * ) { + * MEM_SmartPtr<foo> afoo = new foo(); + * MEM_SmartPtr<bar> that = new bar(); + * + * if (foo == NULL || that == NULL) return NULL; + * + * that->m_foo = afoo.Release(); + * return that.Release(); + * } + * + * ~bar() { + * // smart ptr takes care of deletion + * } + * private : + * MEM_SmartPtr<foo> m_foo; + * } + * + * You may also safely construct vectors of MEM_SmartPtrs and + * have the vector own stuff you put into it. + * + * e.g. + * { + * std::vector<MEM_SmartPtr<foo> > foo_vector; + * foo_vector.push_back( new foo()); + * foo_vector.push_back( new foo()); + * + * foo_vector[0]->bla(); + * } // foo_vector out of scope => heap memory freed for both foos + * + * @warning this class should only be used for objects created + * on the heap via the new function. It will not behave correctly + * if you pass ptrs to objects created with new[] nor with + * objects declared on the stack. Doing this is likely to crash + * the program or lead to memory leaks. + */ + +template + < class T > +class MEM_SmartPtr { + +public : + + /** + * Construction from reference - this class + * always assumes ownership from the rhs. + */ + + MEM_SmartPtr( + const MEM_SmartPtr &rhs + ){ + m_val = rhs.Release(); + } + + /** + * Construction from ptr - this class always + * assumes that it now owns the memory associated with the + * ptr. + */ + + MEM_SmartPtr( + T* val + ) : + m_val (val) + { + } + + /** + * Defalut constructor + */ + + MEM_SmartPtr( + ) : + m_val (NULL) + { + } + + /** + * Type conversion from this class to the type + * of a pointer to the template parameter. + * This means you can pass an instance of this class + * to a function expecting a ptr of type T. + */ + + operator T * () const { + return m_val; + } + + /** + * Return a reference to the internal ptr class. + * Use with care when you now that the internal ptr + * is not NULL! + */ + + T & + Ref( + ) const { + return *m_val; + } + + /** + * Assignment operator - ownership is transfered from rhs to lhs. + * There is an intenional side-effect of function of transferring + * ownership from the const parameter rhs. This is to insure + * the 1-1 relationship. + * The object associated with this instance is deleted if it + * is not the same as that contained in the rhs. + */ + + MEM_SmartPtr & operator=( + const MEM_SmartPtr &rhs + ) { + if (this->m_val != rhs.m_val) { + delete this->m_val; + } + + this->m_val = rhs.Release(); + return *this; + } + + /** + * Overload the operator -> so that it's possible to access + * all the normal methods of the internal ptr. + */ + + T * operator->() const { + return m_val; + } + + /** + * Caller takes ownership of the object - the object will not + * be deleted when the ptr goes out of scope. + */ + + T * + Release( + ) const { + T* temp = m_val; + (const_cast<MEM_SmartPtr *>(this))->m_val = NULL; + return temp; + } + + /** + * Force destruction of the internal object. + */ + + void + Delete( + ) { + delete (m_val); + m_val = NULL; + } + + /** + * Destructor - deletes object if it exists + */ + + ~MEM_SmartPtr( + ) { + delete (m_val); + } + +private : + + /// The ptr owned by this class. + T * m_val; +}; + +#endif + |