Advertisement
expired6978

tArray Manipulation0

Jun 29th, 2016
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.01 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "f4se/GameAPI.h"
  4.  
  5. template<class T>
  6. class BSTArrayFunctor
  7. {
  8. public:
  9.         BSTArrayFunctor(tArray<T> * arr, UInt32 growSize = 10, UInt32 shrinkSize = 10) : m_array(arr)
  10.         {
  11.                 m_growSize = growSize;
  12.                 if(m_growSize == 0)
  13.                         m_growSize = 1;
  14.  
  15.                 m_shrinkSize = shrinkSize;
  16.         }
  17.  
  18.         bool Allocate(UInt32 numEntries)
  19.         {
  20.                 if(!m_array)
  21.                         return false;
  22.  
  23.                 if(m_array->entries)
  24.                         Heap_Free(m_array->entries);
  25.  
  26.                 m_array->entries = (T *)Heap_Allocate(sizeof(T) * numEntries);
  27.                 if(!m_array->entries) return false;
  28.  
  29.                 for(UInt32 i = 0; i < numEntries; i++)
  30.                         new (&m_array->entries[i]) T;
  31.  
  32.                 m_array->capacity = numEntries;
  33.                 m_array->count = numEntries;
  34.                 return true;
  35.         };
  36.  
  37.         void Set(T * entries, UInt32 count)
  38.         {
  39.                 // Not enough space to hold the remaining items, free the old list and allocate
  40.                 if (count > m_array->capacity) {
  41.                         // Free the existing array
  42.                         if (m_array->entries)
  43.                                 Heap_Free(m_array->entries);
  44.  
  45.                         UInt32 newCapacity = count;
  46.                         if (count % m_growSize > 0) // Amount we are allocating to is less the growth size
  47.                                 newCapacity = count + (count % m_growSize);
  48.  
  49.                         m_array->entries = (T *)Heap_Allocate(sizeof(T) * newCapacity);
  50.                         memcpy_s(m_array->entries, sizeof(T) * count, entries, sizeof(T) * count);
  51.  
  52.                         if (newCapacity > count) {
  53.                                 for (UInt32 i = count; i < newCapacity; i++) // Allocate the remaining capacity
  54.                                         new (&m_array->entries[i]) T;
  55.                         }
  56.  
  57.                         m_array->capacity = newCapacity;
  58.                         m_array->count = count;
  59.                 }
  60.                 else
  61.                 {
  62.                         memcpy_s(m_array->entries, sizeof(T) * count, entries, sizeof(T) * count);
  63.  
  64.                         if (m_array->capacity > count) {
  65.                                 for (UInt32 i = count; i < m_array->capacity; i++) // Allocate the remaining empty capacity
  66.                                         new (&m_array->entries[i]) T;
  67.                         }
  68.  
  69.                         m_array->count = count;
  70.                 }
  71.         }
  72.  
  73.         bool Push(const T & entry)
  74.         {
  75.                 if(!m_array) return false;
  76.  
  77.                 if(m_array->count + 1 > m_array->capacity) {
  78.                         if(!Grow(m_growSize))
  79.                                 return false;
  80.                 }
  81.  
  82.                 m_array->entries[m_array->count] = entry;
  83.                 m_array->count++;
  84.                 return true;
  85.         };
  86.  
  87.         bool Insert(UInt32 index, const T & entry)
  88.         {
  89.                 if(!m_array->entries || index < m_array->count)
  90.                         return false;
  91.  
  92.                 m_array->entries[index] = entry;
  93.                 return true;
  94.         };
  95.  
  96.         bool Remove(UInt32 index)
  97.         {
  98.                 if(!m_array->entries || index < m_array->count)
  99.                         return false;
  100.  
  101.                 m_array->entries[index] = NULL;
  102.                 if(index + 1 < m_array->count) {
  103.                         UInt32 remaining = m_array->count - index;
  104.                         memmove_s(&m_array->entries[index + 1], sizeof(T) * remaining, &m_array->entries[index], sizeof(T) * remaining); // Move the rest up
  105.                 }
  106.                 m_array->count--;
  107.  
  108.                 if(m_array->capacity > m_array->count + m_shrinkSize)
  109.                         Shrink();
  110.  
  111.                 return true;
  112.         };
  113.  
  114.         bool Shrink()
  115.         {
  116.                 if(!m_array || m_array->count == m_array->capacity) return false;
  117.  
  118.                 try {
  119.                         UInt32 newSize = m_array->count;
  120.                         T * oldArray = m_array->entries;
  121.                         T * newArray = (T *)Heap_Allocate(sizeof(T) * newSize); // Allocate new block
  122.                         memmove_s(newArray, sizeof(T) * newSize, m_array->entries, sizeof(T) * newSize); // Move the old block
  123.                         m_array->entries = newArray;
  124.                         m_array->capacity = m_array->count;
  125.                         Heap_Free(oldArray); // Free the old block
  126.                         return true;
  127.                 }
  128.                 catch(...) {
  129.                         return false;
  130.                 }
  131.  
  132.                 return false;
  133.         }
  134.  
  135.         bool Grow(UInt32 entries)
  136.         {
  137.                 if(!m_array) return false;
  138.  
  139.                 try {
  140.                         UInt32 oldSize = m_array->capacity;
  141.                         UInt32 newSize = oldSize + entries;
  142.                         T * oldArray = m_array->entries;
  143.                         T * newArray = (T *)Heap_Allocate(sizeof(T) * newSize); // Allocate new block
  144.                         if(oldArray)
  145.                             memmove_s(newArray, sizeof(T) * newSize, m_array->entries, sizeof(T) * m_array->capacity); // Move the old block
  146.                         m_array->entries = newArray;
  147.                         m_array->capacity = newSize;
  148.  
  149.                         if(oldArray)
  150.                             Heap_Free(oldArray); // Free the old block
  151.  
  152.                         for(UInt32 i = oldSize; i < newSize; i++) // Allocate the rest of the free blocks
  153.                                 new (&m_array->entries[i]) T;
  154.                        
  155.                         return true;
  156.                 }
  157.                 catch(...) {
  158.                         return false;
  159.                 }
  160.  
  161.                 return false;
  162.         };
  163.  
  164. private:
  165.         tArray<T> * m_array;
  166.         UInt32  m_growSize;
  167.         UInt32  m_shrinkSize;
  168. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement