aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common/Array.h
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-06-06 16:48:21 +0200
committerShauren <shauren.trinity@gmail.com>2019-06-08 17:09:24 +0200
commitfc330fd8ff0115804d9c4b53a1f810c00dd63de9 (patch)
treecfa10998fed66779834bf0b7a9b8b799d33d91d4 /dep/CascLib/src/common/Array.h
parent82c7b6c5688495d90c4ee5995a4ff74039348296 (diff)
Dep/CascLib: Update to ladislav-zezula/CascLib@a1197edf0b3bd4d52c3f39be7fa7b44bb0b98012
Diffstat (limited to 'dep/CascLib/src/common/Array.h')
-rw-r--r--dep/CascLib/src/common/Array.h208
1 files changed, 208 insertions, 0 deletions
diff --git a/dep/CascLib/src/common/Array.h b/dep/CascLib/src/common/Array.h
new file mode 100644
index 00000000000..1dc96b7be8e
--- /dev/null
+++ b/dep/CascLib/src/common/Array.h
@@ -0,0 +1,208 @@
+/*****************************************************************************/
+/* Array.h Copyright (c) Ladislav Zezula 2015 */
+/*---------------------------------------------------------------------------*/
+/* Common array implementation */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 30.10.15 1.00 Lad The first version of DynamicArray.h */
+/* 10.08.18 1.00 Lad CLASS-ified, renamed to Array.h */
+/*****************************************************************************/
+
+#ifndef __CASC_ARRAY_H__
+#define __CASC_ARRAY_H__
+
+//-----------------------------------------------------------------------------
+// Structures
+
+class CASC_ARRAY
+{
+ public:
+
+ CASC_ARRAY()
+ {
+ m_pItemArray = NULL;
+ m_ItemCountMax = 0;
+ m_ItemCount = 0;
+ m_ItemSize = 0;
+ }
+
+ ~CASC_ARRAY()
+ {
+ Free();
+ }
+
+ // Creates an array with a custom element type
+ template<typename TYPE>
+ int Create(size_t ItemCountMax)
+ {
+ return Create(sizeof(TYPE), ItemCountMax);
+ }
+
+ // Creates an array with a custom element size
+ int Create(size_t ItemSize, size_t ItemCountMax)
+ {
+ // Create the array
+ if ((m_pItemArray = CASC_ALLOC(BYTE, ItemSize * ItemCountMax)) == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ m_ItemCountMax = ItemCountMax;
+ m_ItemCount = 0;
+ m_ItemSize = ItemSize;
+ return ERROR_SUCCESS;
+ }
+
+ // Inserts one or more items; returns pointer to the first inserted item
+ void * Insert(size_t NewItemCount)
+ {
+ void * pNewItems;
+
+ // Try to enlarge the buffer, if needed
+ if (!EnlargeArray(m_ItemCount + NewItemCount))
+ return NULL;
+ pNewItems = m_pItemArray + (m_ItemCount * m_ItemSize);
+
+ // Increment the size of the array
+ m_ItemCount += NewItemCount;
+
+ // Return pointer to the new item
+ return pNewItems;
+ }
+
+ // Inserts one or more items; returns pointer to the first inserted item
+ void * Insert(const void * NewItems, size_t NewItemCount)
+ {
+ void * pNewItem = Insert(NewItemCount);
+
+ // Copy the item(s) to the array, if any
+ if (pNewItem && NewItems)
+ memcpy(pNewItem, NewItems, (NewItemCount * m_ItemSize));
+ return pNewItem;
+ }
+
+ // Returns an item at a given index
+ void * ItemAt(size_t ItemIndex)
+ {
+ return (ItemIndex < m_ItemCount) ? (m_pItemArray + (ItemIndex * m_ItemSize)) : NULL;
+ }
+
+ void * LastItem()
+ {
+ return m_pItemArray + (m_ItemCount * m_ItemSize);
+ }
+
+ // Inserts an item at a given index. If there is not enough items in the array,
+ // the array will be enlarged. Should any gaps to be created, the function will zero them
+ void * InsertAt(size_t ItemIndex)
+ {
+ LPBYTE pbLastItem;
+ LPBYTE pbNewItem;
+
+ // Make sure we have array large enough
+ if(!EnlargeArray(ItemIndex + 1))
+ return NULL;
+
+ // Get the items range
+ pbLastItem = m_pItemArray + (m_ItemCount * m_ItemSize);
+ pbNewItem = m_pItemArray + (ItemIndex * m_ItemSize);
+ m_ItemCount = CASCLIB_MAX(m_ItemCount, ItemIndex+1);
+
+ // If we inserted an item past the current end, we need to clear the items in-between
+ if (pbNewItem > pbLastItem)
+ {
+ memset(pbLastItem, 0, (pbNewItem - pbLastItem));
+ m_ItemCount = ItemIndex + 1;
+ }
+
+ return pbNewItem;
+ }
+
+ // Returns index of an item
+ size_t IndexOf(const void * pItem)
+ {
+ LPBYTE pbItem = (LPBYTE)pItem;
+
+ assert((m_pItemArray <= pbItem) && (pbItem <= m_pItemArray + (m_ItemCount * m_ItemSize)));
+ assert(((pbItem - m_pItemArray) % m_ItemSize) == 0);
+
+ return ((pbItem - m_pItemArray) / m_ItemSize);
+ }
+
+ void * ItemArray()
+ {
+ return m_pItemArray;
+ }
+
+ size_t ItemCount()
+ {
+ return m_ItemCount;
+ }
+
+ size_t ItemCountMax()
+ {
+ return m_ItemCountMax;
+ }
+
+ size_t ItemSize()
+ {
+ return m_ItemSize;
+ }
+
+ bool IsInitialized()
+ {
+ return (m_pItemArray && m_ItemCountMax);
+ }
+
+ // Invalidates the entire array, but keeps memory allocated
+ void Reset()
+ {
+ memset(m_pItemArray, 0, m_ItemCountMax * m_ItemSize);
+ m_ItemCount = 0;
+ }
+
+ // Frees the array
+ void Free()
+ {
+ CASC_FREE(m_pItemArray);
+ m_ItemCountMax = m_ItemCount = m_ItemSize = 0;
+ }
+
+ protected:
+
+ bool EnlargeArray(size_t NewItemCount)
+ {
+ LPBYTE NewItemArray;
+ size_t ItemCountMax;
+
+ // We expect the array to be already allocated
+ assert(m_pItemArray != NULL);
+ assert(m_ItemCountMax != 0);
+
+ // Shall we enlarge the table?
+ if (NewItemCount > m_ItemCountMax)
+ {
+ // Calculate new table size
+ ItemCountMax = m_ItemCountMax;
+ while (ItemCountMax < NewItemCount)
+ ItemCountMax = ItemCountMax << 1;
+
+ // Allocate new table
+ NewItemArray = CASC_REALLOC(BYTE, m_pItemArray, (ItemCountMax * m_ItemSize));
+ if (NewItemArray == NULL)
+ return false;
+
+ // Set the new table size
+ m_ItemCountMax = ItemCountMax;
+ m_pItemArray = NewItemArray;
+ }
+
+ return true;
+ }
+
+ LPBYTE m_pItemArray; // Pointer to item array
+ size_t m_ItemCountMax; // Maximum item count
+ size_t m_ItemCount; // Current item count
+ size_t m_ItemSize; // Size of an item
+};
+
+#endif // __CASC_ARRAY__