autoptr.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 1998-2006 Autodesk, Inc.
00003 // All rights reserved.
00004 // 
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //**************************************************************************/
00011 // DESCRIPTION: Automatic pointer supporting resource-acquisition is 
00012 //    initialization technique.
00013 // AUTHOR: Nicolas Desjardins
00014 // DATE: 2006/03/20 
00015 //***************************************************************************/
00016 
00017 #pragma once
00018 
00019 #ifndef NULL
00020 #define NULL 0
00021 #endif
00022 
00023 namespace MaxSDK
00024 {
00025 
00059 template<typename OtherType> struct AutoPtrRef
00060 {
00061     OtherType *mPtr;
00062     AutoPtrRef(OtherType *p)  : mPtr(p) {}      
00063 };
00064 
00065 
00069 template <typename Type> class SinglePointerDestructor
00070 {
00071 public:
00072     static void Delete(Type *ptr) 
00073     { 
00074         delete ptr; 
00075     }
00076 };
00077 
00161 template <typename Type, typename DestructorPolicy = SinglePointerDestructor<Type> >
00162 class AutoPtr
00163 {
00164 private:
00172     void * operator new(size_t size);   
00173     
00182     void * operator new(size_t size, void * placement);
00183     
00187     Type *mPtr;
00188 
00189 public:
00193     typedef Type element_type;
00194 
00198     typedef DestructorPolicy destructor;
00199 
00206     explicit AutoPtr(Type *p = NULL)  : mPtr(p) {}
00207 
00211     ~AutoPtr()  { DestructorPolicy::Delete(mPtr); }
00212 
00221     AutoPtr(AutoPtr &a)  : mPtr(a.Release()) {}
00222 
00232     template <typename OtherType> AutoPtr(AutoPtr<OtherType, DestructorPolicy> &a) : 
00233         mPtr(a.Release()) 
00234     {}
00235 
00245     AutoPtr& operator=(AutoPtr &a) 
00246     {
00247         if(Get() != a.Get())
00248         {
00249             DestructorPolicy::Delete(mPtr);
00250             mPtr = a.Release();
00251         }
00252         return *this;
00253     }
00254 
00265     template<typename OtherType> AutoPtr& operator=(AutoPtr<OtherType, DestructorPolicy> &a) 
00266     {
00267         if(Get() != a.Get())
00268         {
00269             DestructorPolicy::Delete(mPtr);
00270             mPtr = a.Release();
00271         }
00272         return *this;
00273     }
00274 
00281     Type& operator*() const  { return *mPtr; }
00282 
00289     Type* operator->() const  { return mPtr; }
00290 
00299     Type* Get() const { return mPtr; }
00300 
00310     Type* Release() 
00311     {
00312         Type *temp = mPtr;
00313         mPtr = NULL;
00314         return temp;
00315     }
00316 
00323     void Reset(Type *p = NULL) 
00324     {
00325         if(p != mPtr)
00326         {
00327             DestructorPolicy::Delete(mPtr);
00328             mPtr = p;
00329         }
00330     }
00331 
00337     bool IsNull() const  { return (NULL == mPtr); }
00338 
00346     AutoPtr(const AutoPtrRef<Type> &ref) : mPtr(ref.mPtr) {}
00347 
00351     template<typename OtherType> operator AutoPtrRef<OtherType>() 
00352     {
00353         return AutoPtrRef<OtherType>(this->Release());
00354     }
00355 
00359     template<typename OtherType> operator AutoPtr<OtherType, DestructorPolicy>() 
00360     {
00361         return AutoPtr<OtherType, DestructorPolicy>(this->Release());
00362     }
00363 };
00364 
00368 template <typename Type> class ArrayPointerDestructor
00369 {
00370 public:
00371     static void Delete(Type *ptr) 
00372     { 
00373         delete [] ptr; 
00374     }
00375 };
00376 
00387 template <typename Type> class ArrayAutoPtr : public AutoPtr<Type, ArrayPointerDestructor<Type> > 
00388 {
00389 public:
00396     explicit ArrayAutoPtr(Type *p = NULL) : 
00397         AutoPtr<Type, ArrayPointerDestructor<Type> >(p)
00398     { };
00399 
00407     ArrayAutoPtr(const AutoPtrRef<Type> &ref) :
00408         AutoPtr<Type, ArrayPointerDestructor<Type> >(ref.mPtr)
00409     { }
00410 
00414     template<typename OtherType> operator ArrayAutoPtr<OtherType>() 
00415     {
00416         return ArrayAutoPtr<OtherType>(this->Release());
00417     }
00418 
00431     Type& operator[](int index) const
00432     { 
00433         return Get()[index];
00434     }
00435 };
00436 
00441 class DeleteThisDestructor
00442 {
00443 public:
00444     template <typename Type> static void Delete(Type *ptr)
00445     { 
00446         if(NULL != ptr)
00447         {
00448             ptr->DeleteThis(); 
00449         }
00450     }
00451 };
00452 
00453 
00461 template <typename Type> class DeleteThisAutoPtr : public AutoPtr<Type, DeleteThisDestructor > 
00462 {
00463 public:
00470     explicit DeleteThisAutoPtr(Type *p = NULL) : 
00471         AutoPtr<Type, DeleteThisDestructor >(p)
00472     { };
00473 
00481     DeleteThisAutoPtr(const AutoPtrRef<Type> &ref) :
00482         AutoPtr<Type, DeleteThisDestructor >(ref.mPtr)
00483     { }
00484 };
00485 
00486 namespace Util
00487 {
00488 
00496 template<typename Type> class AutoPtr : public MaxSDK::AutoPtr<Type>
00497 {
00498 public:
00505     explicit AutoPtr(Type *p = NULL) : 
00506         MaxSDK::AutoPtr<Type>(p)
00507     { };
00508 
00516     AutoPtr(const AutoPtrRef<Type> &ref) :
00517         MaxSDK::AutoPtr<Type>(ref.mPtr)
00518     { }
00519 
00523     template<typename OtherType> operator AutoPtr<OtherType>() 
00524     {
00525         return AutoPtr<OtherType>(this->Release());
00526     }
00527 };
00528 
00529 }
00530 
00531 }
00532