## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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:
    00087     static const size_t allocSize = sizeof (WrappedData);
    00088   private:
    00089     csRef<WrappedData> data;
    00090     inline WrappedData* NewData (const T& other)
    00091     {
    00092       WrappedData* p = (WrappedData*)MemoryAllocator::Alloc (allocSize);
    00093       new (p) WrappedData (other);
    00094       return p;
    00095     }
    00096   public:
    00098     CowWrapper (const CowWrapper& other) : data (other.data) {}
    00100     CowWrapper (const T& other)
    00101     {
    00102       data.AttachNew (NewData (other));
    00103     }
    00104
    00106     const T& operator* () const
    00107     {
    00108       return data->data;
    00109     }
    00115     T& operator* ()
    00116     {
    00117       if (data->GetRefCount() > 1)
    00118       {
    00119         WrappedData* newData = NewData (data->data);
    00120         data.AttachNew (newData);
    00121       }
    00122       return data->data;
    00123     }
    00125     const T* operator -> () const
    00126     { return &(operator*()); }
    00132     T* operator -> ()
    00133     { return &(operator*()); }
    00134   };
    00135
    00136 } // namespace CS
    00137
    00138 #include "csutil/custom_new_enable.h"
    00139
    00140 #endif // __CS_CSUTIL_COWWRAPPER_H__