// XDWHolder.tli // #pragma once #ifndef ASSERT #include #define ASSERT assert #endif #include "XDWHolder.tlh" #define Datanullptr nullptr template XDWHolder ::XDWHolder () { Init (); } template XDWHolder ::~XDWHolder () { if (GetData () != Datanullptr) { if (InterlockedDecrement (&GetData ()->nRefs) <= 0) { delete m_pMetaData; delete m_pObject; } } } template void XDWHolder ::Init (void) { m_pObject = nullptr; m_pMetaData = (MetaData *) Datanullptr; } template XDWHolder ::XDWHolder (const XDWHolder & h) { Init (); ShadowCopyFrom (h); } template XDWHolder ::XDWHolder (XDWHolder && h) { m_pObject = h.m_pObject; m_pMetaData = h.m_pMetaData; h.Init (); } template XDWHolder ::XDWHolder (T * object) { Init (); Attach (object); } template void XDWHolder ::Attach (T * object) { Release (); if (object == nullptr) return; m_pObject = object; m_pMetaData = new MetaData; m_pMetaData->nRefs = 1; } template T * XDWHolder ::Detach () { T * over = m_pObject; m_pObject = nullptr; Release (); return over; } template void XDWHolder ::Release () { if (GetData () == Datanullptr) return; ASSERT (GetData ()->nRefs != 0); if (InterlockedDecrement (&GetData ()->nRefs) <= 0) { if (m_pObject) delete (m_pObject); delete m_pMetaData; m_pMetaData = nullptr; } Init (); } template void XDWHolder ::CopyFrom (const XDWHolder & h) { Release (); if (! h.m_pObject) return; T * object = h.NewObject (h.m_pObject); ASSERT (object); Attach (object); } template void XDWHolder ::ShadowCopyFrom (const XDWHolder & h) { if (m_pObject == h.m_pObject) return; if (h.GetData () == Datanullptr) { Release (); return; } if (GetData () != Datanullptr) if (GetData ()->nRefs < 0) { CopyFrom (h); return; } if (h.GetData ()->nRefs < 0) { CopyFrom (h); return; } // else { // can just copy references around Release (); m_pObject = h.m_pObject; m_pMetaData = h.m_pMetaData; InterlockedIncrement (&GetData ()->nRefs); } } template T * XDWHolder ::NewObject (const T * fromObject) const { // T * object = new T (* fromObject); // return object return nullptr; } template XDWHolder & XDWHolder ::operator = (const XDWHolder & h) { ShadowCopyFrom (h); return *this; } template XDWHolder & XDWHolder ::operator = (T * object) { Attach (object); return *this; } template XDWHolder ::operator bool () const { return m_pObject; } template XDWHolder ::operator T * () { return m_pObject; } template XDWHolder ::operator const T * () const { return m_pObject; } template bool XDWHolder ::IsEmpty () const { return (m_pObject == nullptr); }