CrystalSpace

Public API Reference

csutil/cowwrapper.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2006 by Frank Richter
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public
00015     License along with this library; if not, write to the Free
00016     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #ifndef __CS_CSUTIL_COWWRAPPER_H__
00020 #define __CS_CSUTIL_COWWRAPPER_H__
00021 
00022 #include "csutil/custom_new_disable.h"
00023 
00024 #include "csutil/allocator.h"
00025 
00030 namespace CS
00031 {
00032 
00061   template<typename T, class MemoryAllocator = Memory::AllocatorMalloc>
00062   class CowWrapper
00063   {
00065     struct WrappedData
00066     {
00067       int refcount;
00068   
00069       void IncRef () { refcount++; }
00070       void DecRef () 
00071       { 
00072         refcount--; 
00073         if (refcount == 0) 
00074         {
00075           this->~WrappedData();
00076           MemoryAllocator::Free (this);
00077         }
00078       }
00079       int GetRefCount () const { return refcount; }
00080       
00081       T data;
00082     public:
00083       WrappedData (const T& other) : refcount (1), data (other) {}
00084       WrappedData (const WrappedData& other) : refcount (1), data (other.data) {}
00085     };
00086   public:
00092     static const size_t allocSize = sizeof (WrappedData);
00093   private:
00094     csRef<WrappedData> data;
00095     inline WrappedData* NewData (const T& other)
00096     {
00097       WrappedData* p = (WrappedData*)MemoryAllocator::Alloc (allocSize);
00098       new (p) WrappedData (other);
00099       return p;
00100     }
00101   public:
00103     CowWrapper (const CowWrapper& other) : data (other.data) {}
00105     CowWrapper (const T& other)
00106     {
00107       data.AttachNew (NewData (other));
00108     }
00109 
00111     const T& operator* () const
00112     {
00113       return data->data;
00114     }
00120     T& operator* ()
00121     {
00122       if (data->GetRefCount() > 1)
00123       {
00124         WrappedData* newData = NewData (data->data);
00125         data.AttachNew (newData);
00126       }
00127       return data->data;
00128     }
00130     const T* operator -> () const
00131     { return &(operator*()); }
00137     T* operator -> ()
00138     { return &(operator*()); }
00139   };
00140 
00141 } // namespace CS
00142 
00143 #include "csutil/custom_new_enable.h"
00144 
00145 #endif // __CS_CSUTIL_COWWRAPPER_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1