/** * @file XTPSmartPtrInternalT.h * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ /** @cond */ #if !defined(_XtpSmartPtrInternal_H__) # define _XtpSmartPtrInternal_H__ # if _MSC_VER > 1000 # pragma once # endif // _MSC_VER > 1000 /** @endcond */ # include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" ///////////////////////////////////////////////////////////////////////////// // template: CXTPSmartPtrInternalT // macro: XTP_DEFINE_SMART_PTR_INTERNAL(_TClassName) // XTP_DEFINE_SMART_PTR_ARRAY_INTERNAL(_TClassName) ///////////////////////////////////////////////////////////////////////////// /** * @brief * Define smart pointer for the specified class as ClassNamePtr. * CXTPSmartPtrInternalT is used for this purpose. For example * XTP_DEFINE_SMART_PTR_INTERNAL(CXTPCmdTarget) will be replaced with * typedef CXTPSmartPtrInternalT\ CCmdTargetPtr; * @param ClassName Name of the class used to define the smart pointer. */ # define XTP_DEFINE_SMART_PTR_INTERNAL(ClassName) \ typedef CXTPSmartPtrInternalT ClassName##Ptr; /** * @brief * Define smart pointers array for the specified class as ClassNamePtrArray. * CXTPInternalCollectionT is used for this purpose. * Also define smart pointer for array as ClassNamePtrArrayPtr. * @param ClassName Name of the class used to define the array of smart pointers. */ # define XTP_DEFINE_SMART_PTR_ARRAY_INTERNAL(ClassName) \ typedef CXTPInternalCollectionT ClassName##PtrArray; \ typedef CXTPSmartPtrInternalT ClassName##PtrArrayPtr; /** * @details * This internal class is used for semi-automatic incrementing * and decrementing reference to any object derived from CXTPCmdTarget * or other class, which has InternalAddRef(), InternalRelease() * methods. * @see * macro XTP_DEFINE_SMART_PTR_INTERNAL(_TClassName) */ template class CXTPSmartPtrInternalT { protected: /** * @details * This class type definition */ typedef CXTPSmartPtrInternalT<_TObject> Tthis; _TObject* m_pObject; /**< A pointer to a handled object */ public: /** * @brief * Default class constructor. * @param pObject Pointer to the handled object. * @param bCallInternalAddRef If this parameter is TRUE * pObject->InternalAddRef() will be * called in constructor. * By default this parameter is FALSE. * @see * ~CXTPSmartPtrInternalT() */ CXTPSmartPtrInternalT(_TObject* pObject = NULL, BOOL bCallInternalAddRef = FALSE) { m_pObject = pObject; if (bCallInternalAddRef && m_pObject) { ((CCmdTarget*)m_pObject)->InternalAddRef(); } }; /** * @brief * Copy class constructor. * @param rSrc The source object reference. * @see * CXTPSmartPtrInternalT(_TObject* pObject, BOOL bCallInternalAddRef) */ CXTPSmartPtrInternalT(const Tthis& rSrc) { m_pObject = (_TObject*)rSrc; if (m_pObject) { ((CCmdTarget*)m_pObject)->InternalAddRef(); } }; /** * @brief * Default class destructor. * @details * Call InternalRelease() for the not NULL handled object. * @see * CXTPSmartPtrInternalT constructors */ virtual ~CXTPSmartPtrInternalT() { if (m_pObject) { ((CCmdTarget*)m_pObject)->InternalRelease(); } }; /** * @brief * Set new handled object. * @param pObject Pointer to the new handled object. * @param bCallInternalAddRef If this parameter is TRUE * pObject->InternalAddRef() will be * called in constructor. * By default this parameter is FALSE. * @details * InternalRelease() for the previous not NULL handled object * will be called. InternalAddRef() for the new not NULL handled * object will be called. * @see * operator= */ void SetPtr(_TObject* pObject, BOOL bCallInternalAddRef = FALSE) { _TObject* pObjOld = m_pObject; if (bCallInternalAddRef && pObject) { ((CCmdTarget*)pObject)->InternalAddRef(); } m_pObject = pObject; if (pObjOld) { ((CCmdTarget*)pObjOld)->InternalRelease(); } }; /** * @brief * Get a handled object and set internal object member to NULL * without call InternalRelease(). * @return * Pointer to the handled object. */ _TObject* Detach() { _TObject* pObj = m_pObject; m_pObject = NULL; return pObj; }; /** * @brief * Get a handled object and set internal object member to NULL * without call InternalRelease(). * @param bWithAddRef [in] If TRUE InternalAddRef() is called before * @return * Pointer to the handled object. */ _TObject* GetInterface(BOOL bWithAddRef = TRUE) { if (bWithAddRef && m_pObject) { ((CCmdTarget*)m_pObject)->InternalAddRef(); } return m_pObject; }; /** * @brief * Set new handled object. * @param pNewObj Pointer to the new handled object. * @details * InternalRelease() for the previous not NULL handled object * will be called. * @return * Pointer to the new handled object. */ _TObject* operator=(_TObject* pNewObj) { _TObject* pObjOld = m_pObject; m_pObject = pNewObj; if (pObjOld) { ((CCmdTarget*)pObjOld)->InternalRelease(); } return pNewObj; }; /** * @brief * Set new handled object. * @param rSrc Reference to the new handled object. * @details * InternalRelease() for the previous not NULL handled object * will be called. InternalAddRef() for the new not NULL handled * object will be called. * @return * Reference to this class instance. */ const Tthis& operator=(const Tthis& rSrc) { _TObject* pObjOld = m_pObject; m_pObject = rSrc; if (m_pObject) { ((CCmdTarget*)m_pObject)->InternalAddRef(); } if (pObjOld) { ((CCmdTarget*)pObjOld)->InternalRelease(); } return rSrc; }; /** * @brief * Get a handled object. * @return * Pointer to the handled object. */ _TObject* operator->() const { _ASSERTE(m_pObject); return m_pObject; }; /** * @brief * Get a handled object. * @return * Reference to the handled object. */ _TObject& operator*() const { _ASSERTE(m_pObject); return *m_pObject; }; /** * @brief * Get a handled object. * @return * Pointer to the handled object. */ operator _TObject*() const { return m_pObject; } operator const _TObject*() const { return m_pObject; } /** * @brief * Checks is handled object equal NULL. * @return * TRUE if handled object equal NULL, otherwise FALSE. */ bool operator!() const { return (m_pObject == NULL); } /** * @brief * Checks is handled object equal or not equal to NULL. * @return * true if handled object not equal NULL, otherwise false. */ operator bool() const { return (m_pObject != NULL); } /** * @brief * Equal-to operator. * @param ptr2 [in] Pointer to the other object. * @details * This operator compare internal stored pointer and specified * pointer. * @return * TRUE if pointer are equal, otherwise FALSE. */ bool operator==(const Tthis& ptr2) const { return m_pObject == (_TObject*)ptr2; } bool operator==(const _TObject* pObj) const { return pObj == m_pObject; } /** * @brief * Not-equal-to operator. * @param ptr2 [in] Smart pointer to the other object. * @details * This operator compare internal stored pointer and specified * pointer. * @return * TRUE if pointer are not equal, otherwise FALSE. */ bool operator!=(const Tthis& ptr2) const { return m_pObject != (_TObject*)ptr2; } bool operator!=(const _TObject* pObj) const { return pObj != m_pObject; } }; /** @cond */ template AFX_INLINE bool operator==(const CXTPSmartPtrInternalT<_TObject>& ptr1, const _TObject* ptr2) { return ptr1 == ptr2; } template AFX_INLINE bool operator==(const _TObject* ptr1, const CXTPSmartPtrInternalT<_TObject>& ptr2) { return ptr2 == ptr1; } template AFX_INLINE bool operator!=(const CXTPSmartPtrInternalT<_TObject>& ptr1, const _TObject* ptr2) { return ptr1 != ptr2; } template AFX_INLINE bool operator!=(const _TObject* ptr1, const CXTPSmartPtrInternalT<_TObject>& ptr2) { return ptr2 != ptr1; } /** @endcond */ /** * @details * This internal class is used as collection for pointers of objects, * derived from CCmdTarget or other class, which has InternalAddRef(), * InternalRelease() methods. InternalAddRef() is called for stored * object. InternalRelease() is called when object is removed. * Also this collection object derived from IXTPInternalUnknown. * @see * CXTPSmartPtrInternalT, CXTPInternalUnknown */ template class CXTPInternalCollectionT : public CArray, const CXTPSmartPtrInternalT<_TObject>&> { public: /** * @brief * Stored objects type definition. */ typedef _TObject TObject; /** * @brief * Stored objects smart-pointer type definition. */ typedef CXTPSmartPtrInternalT<_TObject> TObjectPtr; /** * @brief * Default object constructor. */ CXTPInternalCollectionT(){}; /** * @brief * Default object destructor. */ virtual ~CXTPInternalCollectionT(){}; /** @cond */ /** * @brief * Get pointer to this object. * @param bWithAddRef [in] If TRUE InternalAddRef() is called before * returning pointer. It is TRUE by default. * @return * Pointer to this object. * @details * This function gets pointer to this object and calls * InternalAddRef() if specified. * @see * IXTPInternalUnknown. */ /* CXTPInternalCollectionT<_TObject>* GetInterface(BOOL bWithAddRef = TRUE) { if(bWithAddRef) { InternalAddRef(); } return this; }; */ /** @endcond */ /** * @brief * Get one of stored objects by index. * @param nIndex [in] Zero-based index of the stored object. * @param bWithAddRef [in] If TRUE, InternalAddRef() will be called before * returning the pointer. * By default, this parameter is TRUE. * @return * Pointer to one of stored objects by index. * @details * This function gets pointer to one of stored objects by index * and calls InternalAddRef() if specified. * @see * CArray::GetAt, IXTPInternalUnknown. */ virtual _TObject* GetAt(int nIndex, BOOL bWithAddRef = TRUE) { TObjectPtr& rPtr = CXTPInternalCollectionT::ElementAt(nIndex); _TObject* pObj = rPtr.GetInterface(bWithAddRef); return pObj; } /** * @brief * Add object pointer to the array. * @param pObj [in] Pointer to the storing object. * @param bCallAddRef [in] If TRUE InternalAddRef() is called before * adding pointer. It is TRUE by default. * @return * Added object index. * @details * This method add a new element to the collection * and calls InternalAddRef() if specified. * @see * CArray::Add, IXTPInternalUnknown. */ virtual int AddPtr(_TObject* pObj, BOOL bCallAddRef = FALSE) { TObjectPtr ptrObj(pObj, bCallAddRef); return static_cast(CXTPInternalCollectionT::Add(ptrObj)); } }; /** * @brief * This class represents a simple array of typed elements. * It repeats CArray methods names and parameters as far as CArray behavior. * @details * This class derived from CXTPCmdTarget. This allow to use it as base class * for collection which has features for ActiveX support. * @see * CArray, CXTPCmdTarget. */ template class CXTPArrayT : public CXTPCmdTarget { public: /** * @brief * Default object constructor. */ CXTPArrayT(); /** * @brief * Default object destructor. */ virtual ~CXTPArrayT(); /** * @brief * This member function is used to obtain the number of elements * in the collection. * @details * Call this method to retrieve the number of elements in the array. * Because indexes are zero-based, the size is 1 greater than * the largest index. * @return * The number of items in the collection. */ virtual int GetSize() const; /** * @brief * This member function is used to change the array size. * @param nNewSize An int that contains the new array size. * @param nGrowBy An int that contains a number of elements to grow * internal data storage if need. * @details * Argument nNewSize contains the new array size (number of elements). * Must be greater than or equal to 0. */ virtual void SetSize(int nNewSize, int nGrowBy = -1); /** * @brief * This member function returns an element at the specified * numeric index. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetSIze. * @details * Returns the array element at the specified index. * @return * The element currently at this index. */ virtual TYPE GetAt(int nIndex) const; /** * @brief * This member function is used to set a new element to the position * specified in the nIndex parameter. * @param nIndex An integer index that is greater than or equal * to 0 and less than the value returned by * GetCount. * @param newElement A new value for the specified index. * @details * Use this method to set the specified element to the * position specified in nIndex parameter. * @see * GetAt, Add, InsertAt */ virtual void SetAt(int nIndex, ARG_TYPE newElement); /** * @brief * This member function returns a reference to element at the * specified numeric index. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetSIze. * @return * The array element reference at the specified index. */ virtual TYPE& ElementAt(int nIndex); /** * @brief * This member function is used to Direct Access to the element data. * May return NULL. * @return * The pointer to allocated array data or NULL. */ virtual const TYPE* GetData() const; /** * @brief * This member function is used to Direct Access to the element data. * May return NULL. * @return * The pointer to allocated array data or NULL. */ virtual TYPE* GetData(); /** * @brief * This member function is used to set a new element to the position * specified in the nIndex parameter. * Potentially growing the array. * @param nIndex An integer index that is greater than or equal * to 0 and less than the value returned by * GetCount. * @param newElement A new value for the specified index. * @details * Use this method to set the specified element to the * position specified in nIndex parameter. * @see * SetAt, Add, InsertAt */ virtual void SetAtGrow(int nIndex, ARG_TYPE newElement); /** * @brief * This member function adds a new element to the end of the array. * @param newElement A new value for the specified index. * @return * The index of the added element. */ virtual int Add(ARG_TYPE newElement); /** * @brief * This member function adds the elements from a specified array * to the end of this array. * @param src A reference to an array of TYPE objects to add to this array. * @return * The index of the first appended element. * @see * GetAt, Add, InsertAt, SetAt */ virtual int Append(const CXTPArrayT& src); /** * @brief * This member function overwrites the contents of this array with * the contents of a specified array. * @param src A reference to an array of TYPE objects to overwrite this array. * @see * GetAt, Add, InsertAt, SetAt */ virtual void Copy(const CXTPArrayT& src); /** * @brief * This operator returns the array element at * a specified numeric index. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetSize. * @return * The array element at the specified index. */ TYPE operator[](int nIndex) const; /** * @brief * This operator returns a reference to the array element at * a specified numeric index. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetSize. * @return * A reference to the array element at the specified index. */ TYPE& operator[](int nIndex); /** * @brief * This member function is used to insert a number of copies of an element, * specified by the nCount parameter, to the array starting at * the position specified by the nIndex parameter. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetCount(). * @param newElement A new value for the specified index. * @param nCount The number of copies of the element to be inserted. * By default, this parameter is 1. */ virtual void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1); /** * @brief * This member function is used to remove a number of array elements, * specified by the nCount parameter, from the array starting at * the position specified by the nIndex parameter. * @param nIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetCount(). * @param nCount The number of elements to be removed. * By default, this parameter is 1. */ virtual void RemoveAt(int nIndex, int nCount = 1); /** * @brief * This member function is used to remove all array elements * from the array. * @see * RemoveAt */ virtual void RemoveAll(); /** * @brief * This member function is used to insert an array of elements to the array * starting at the position specified by the nStartIndex parameter. * @param nStartIndex An integer index that is greater than or equal to 0 * and less than the value returned by GetCount(). * @param pNewArray A pointer to the array which contains the elements * to be inserted. */ virtual void InsertAt(int nStartIndex, CXTPArrayT* pNewArray); /** * @brief * Call this member function to find an element in the collection. * @param nElement Element to find. * @return * The zero-based index of the element in the collection, * or a value of -1 if the element is not found. */ virtual int FindElement(ARG_TYPE nElement) const; /** * @brief * Call this member function to add a specified element to the collection * if it is not present already. * @param newElement An element to add. * @details * If the specified element is already present in the collection, * then this function does nothing. * @see * CArray::Add */ virtual void AddIfNeed(ARG_TYPE newElement); /** * @brief * Call this member function to remove all elements with a specified * value from the collection. * @param nElement The element with the specified value to be removed. * @return * TRUE if the specified element is found and removed, otherwise FALSE. * @see * CArray::RemoveAt, CArray::RemoveAll */ virtual BOOL RemoveElement(ARG_TYPE nElement); protected: CArray m_arElements; /**< Elements storage. */ protected: // OLE collection implementation helpers for macros DECLARE_ENUM_VARIANT_EX(derived-class, // long); /** @cond */ virtual long OleGetItemCount(); virtual OLE_TYPE OleGetItem(long nIndex); virtual void OleSetItem(long nIndex, OLE_TYPE oleValue); virtual void OleAdd(OLE_TYPE otElement); virtual void OleRemove(long nIndex); virtual void OleRemoveAll(); /** @endcond */ }; ///////////////////////////////////////////////////////////////////////////// /** @cond */ template AFX_INLINE CXTPArrayT::CXTPArrayT() { } template AFX_INLINE CXTPArrayT::~CXTPArrayT() { } template AFX_INLINE int CXTPArrayT::GetSize() const { return (int)m_arElements.GetSize(); } template AFX_INLINE void CXTPArrayT::SetSize(int nNewSize, int nGrowBy) { m_arElements.SetSize(nNewSize, nGrowBy); } template AFX_INLINE void CXTPArrayT::RemoveAll() { m_arElements.RemoveAll(); } template AFX_INLINE TYPE CXTPArrayT::GetAt(int nIndex) const { return m_arElements.GetAt(nIndex); } template AFX_INLINE void CXTPArrayT::SetAt(int nIndex, ARG_TYPE newElement) { m_arElements.SetAt(nIndex, newElement); } template AFX_INLINE TYPE& CXTPArrayT::ElementAt(int nIndex) { return m_arElements.ElementAt(nIndex); } template AFX_INLINE const TYPE* CXTPArrayT::GetData() const { return m_arElements.GetData(); } template AFX_INLINE TYPE* CXTPArrayT::GetData() { return m_arElements.GetData(); } template AFX_INLINE void CXTPArrayT::SetAtGrow(int nIndex, ARG_TYPE newElement) { m_arElements.SetAtGrow(nIndex, newElement); } template AFX_INLINE int CXTPArrayT::Add(ARG_TYPE newElement) { return (int)m_arElements.Add(newElement); } template AFX_INLINE int CXTPArrayT::Append(const CXTPArrayT& src) { return (int)m_arElements.Append(src.m_arElements); } template AFX_INLINE void CXTPArrayT::Copy(const CXTPArrayT& src) { m_arElements.Copy(src.m_arElements); } template AFX_INLINE TYPE CXTPArrayT::operator[](int nIndex) const { return m_arElements[nIndex]; } template AFX_INLINE TYPE& CXTPArrayT::operator[](int nIndex) { return m_arElements[nIndex]; } template AFX_INLINE void CXTPArrayT::InsertAt(int nIndex, ARG_TYPE newElement, int nCount) { m_arElements.InsertAt(nIndex, newElement, nCount); } template AFX_INLINE void CXTPArrayT::RemoveAt(int nIndex, int nCount) { m_arElements.RemoveAt(nIndex, nCount); } template AFX_INLINE void CXTPArrayT::InsertAt(int nStartIndex, CXTPArrayT* pNewArray) { _ASSERTE(pNewArray); if (pNewArray) m_arElements.InsertAt(nStartIndex, &(pNewArray->m_arElements)); } template AFX_INLINE int CXTPArrayT::FindElement(ARG_TYPE nElement) const { int nCount = GetSize(); for (int i = 0; i < nCount; i++) { if (GetAt(i) == nElement) return i; } return -1; } template AFX_INLINE BOOL CXTPArrayT::RemoveElement(ARG_TYPE nElement) { BOOL bResult = FALSE; int nCount = GetSize(); for (int i = nCount - 1; i >= 0; i--) { if (GetAt(i) == nElement) { RemoveAt(i); bResult = TRUE; } } return bResult; } template AFX_INLINE void CXTPArrayT::AddIfNeed(ARG_TYPE newElement) { if (FindElement(newElement) < 0) { Add(newElement); } } template AFX_INLINE OLE_TYPE CXTPArrayT::OleGetItem(long nIndex) { if (nIndex < 0 || nIndex >= (long)GetSize()) AfxThrowOleException(DISP_E_BADINDEX); return (OLE_TYPE)GetAt(nIndex); } template AFX_INLINE void CXTPArrayT::OleSetItem(long nIndex, OLE_TYPE oleValue) { if (nIndex < 0 || nIndex >= (long)GetSize()) AfxThrowOleException(DISP_E_BADINDEX); SetAt(nIndex, (ARG_TYPE)oleValue); } template AFX_INLINE long CXTPArrayT::OleGetItemCount() { return (long)m_arElements.GetSize(); } template AFX_INLINE void CXTPArrayT::OleAdd(OLE_TYPE otElement) { Add((TYPE)otElement); } template AFX_INLINE void CXTPArrayT::OleRemove(long nIndex) { if (nIndex < 0 || nIndex >= (long)GetSize()) AfxThrowOleException(DISP_E_BADINDEX); RemoveAt(nIndex); } template AFX_INLINE void CXTPArrayT::OleRemoveAll() { RemoveAll(); } /** @endcond */ # include "Common/Base/Diagnostic/XTPEnableNoisyWarnings.h" /** @cond */ #endif // !defined(_XtpSmartPtrInternal_H__) /** @endcond */