gwnavruntime/database/smallptrtrackedcollection.h Source File

smallptrtrackedcollection.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
10 
11 namespace Kaim
12 {
13 
14 // small container that optimize the case of only 1 element
15 // designed to store T*, default constructor and destructor of template class object are not called
16 // no deep copy is made
17 template <class T>
18 class SmallPtrTrackedCollection
19 {
20  KY_DEFINE_NEW_DELETE_OPERATORS(MemStat_NavData)
21 public:
22  SmallPtrTrackedCollection() : m_count(0), m_capacity(1) { m_values.m_multipleValues = nullptr; }
23  ~SmallPtrTrackedCollection() { KY_LOG_ERROR_IF(m_count != 0, ("memory leak !")); }
24 
25  KY_INLINE bool IsEmpty() const { return GetCount() == 0; }
26  KY_INLINE KyUInt32 GetCount() const { return m_count; }
27 
28  KY_INLINE T** GetValues() { return m_capacity == 1 ? &m_values.m_oneValue : m_values.m_multipleValues; }
29 
30  void PushBack(MemoryHeap* heap, T* newValue)
31  {
32  if (m_capacity == 1)
33  {
34  if (IsEmpty())
35  {
36  m_count = 1;
37  newValue->SetIndexInCollection(0);
38  m_values.m_oneValue = newValue;
39  return;
40  }
41 
42  T* firstValue = m_values.m_oneValue;
43 
44  // no buffer allocated yet. create 1 of size 4
45  m_values.m_multipleValues = (T**)KY_HEAP_ALLOC(heap, KyUInt32(4 * sizeof(T*)), MemStat_NavData);
46 
47  m_count = 2;
48  m_capacity = 4;
49 
50  m_values.m_multipleValues[0] = firstValue;
51  m_values.m_multipleValues[1] = newValue;
52 
53  newValue->SetIndexInCollection(1);
54  return;
55  }
56 
57  if (m_count == m_capacity)
58  Reserve(heap, 2 * m_capacity);
59 
60  m_values.m_multipleValues[m_count] = newValue;
61  newValue->SetIndexInCollection(m_count);
62  ++m_count;
63 
64  return;
65  }
66 
67  void Reserve(MemoryHeap* heap, KyUInt32 newcapacity)
68  {
69  KY_DEBUG_ASSERTN(newcapacity > m_count, ("no shrinking !"));
70 
71  T** values = (T**)KY_HEAP_ALLOC(heap, newcapacity * (KyUInt32)sizeof(T*), MemStat_NavData);
72 
73  memcpy(values, m_values.m_multipleValues, m_count * sizeof(T*));
74 
75  KY_FREE(m_values.m_multipleValues);
76 
77  m_capacity = (KyUInt16)newcapacity;
78  m_values.m_multipleValues = values;
79  }
80 
81  void ForceClear()
82  {
83  if (m_capacity > 1)
84  {
85  for(KyUInt32 i = 0; i < m_count; ++i)
86  m_values.m_multipleValues[i]->SetIndexInCollection(KyUInt32MAXVAL);
87 
88  KY_FREE(m_values.m_multipleValues);
89  }
90  else
91  {
92  if (m_count != 0)
93  m_values.m_oneValue->SetIndexInCollection(KyUInt32MAXVAL);
94  }
95 
96  m_count = 0;
97  m_capacity = 1;
98  m_values.m_oneValue = nullptr;
99  }
100 
101  void SwapWithLastAndPopBack(T* valueToRemove)
102  {
103  const KyUInt32 index = valueToRemove->GetIndexInCollection();
104  const KyUInt32 lastIndex = (KyUInt32)m_count - 1;
105 
106  KY_DEBUG_ASSERTN(index < m_count, ("error"));
107  if (m_capacity > 1)
108  {
109  m_values.m_multipleValues[index]->SetIndexInCollection(KyUInt32MAXVAL);
110 
111  if (index != lastIndex)
112  {
113  // not the last element, swap with effective last
114  m_values.m_multipleValues[lastIndex]->SetIndexInCollection(index);
115  m_values.m_multipleValues[index] = m_values.m_multipleValues[lastIndex];
116  }
117 
118  --m_count;
119  }
120  else
121  {
122  m_values.m_oneValue->SetIndexInCollection(KyUInt32MAXVAL);
123  m_values.m_oneValue = nullptr;
124  m_count = 0;
125  }
126  }
127 
128  void GetOwnershipOfData(SmallPtrTrackedCollection& other)
129  {
130  ForceClear();
131 
132  m_values = other.m_values;
133  m_count = other.m_count;
134  m_capacity = other.m_capacity;
135 
136  other.m_values.m_oneValue = nullptr;
137  other.m_count = 0;
138  other.m_capacity = 0;
139  }
140 
141 private:
142  union Values
143  {
144  T* m_oneValue;
145  T** m_multipleValues;
146  };
147 
148  Values m_values;
149  KyUInt16 m_count;
150  KyUInt16 m_capacity;
151 };
152 
153 }
154 
155 
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
std::uint16_t KyUInt16
uint16_t
Definition: types.h:28
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68