summaryrefslogtreecommitdiff
path: root/Runtime/Utilities/vector_utility.h
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Utilities/vector_utility.h')
-rw-r--r--Runtime/Utilities/vector_utility.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/Runtime/Utilities/vector_utility.h b/Runtime/Utilities/vector_utility.h
new file mode 100644
index 0000000..a632413
--- /dev/null
+++ b/Runtime/Utilities/vector_utility.h
@@ -0,0 +1,95 @@
+#ifndef VECTOR_UTILITY_H
+#define VECTOR_UTILITY_H
+
+// stl vector doesnt deallocate memory on itself.
+// push_back and resizing increases memory by a factor of 2, when growing
+// pop_back, resizing and even clear do not deallocate any memory
+// This of course wastes a lot of memory, fortunately there is the swap trick to
+// bring back memory usage to normality
+//#include <algorithm>
+
+template<class T>
+inline void trim_vector (T& v)
+{
+ if (v.capacity () != v.size ())
+ {
+ T temp = v;
+ temp.swap (v);
+ }
+}
+
+// The following functions do the same as their vector member function
+// equivalents, only they allocate exactly the requested amount of memory.
+
+template<class T>
+inline void resize_trimmed (T& v, unsigned int sz)
+{
+ // the vector is growing
+ if (sz > v.size ())
+ {
+ if (sz != v.capacity ())
+ {
+ T temp (v.get_allocator());
+ temp.reserve (sz);
+ temp.assign (v.begin (), v.end ());
+ temp.resize (sz);
+ temp.swap (v);
+ }
+ else
+ v.resize (sz);
+ }
+ // the vector is shrinking
+ else if (sz < v.size ())
+ {
+ T temp (v.begin (), v.begin () + sz, v.get_allocator());
+ temp.swap (v);
+ }
+}
+
+template<class T>
+inline void reserve_trimmed (T& v, unsigned int sz)
+{
+ if (sz != v.capacity ())
+ {
+ T temp;
+ temp.reserve (sz);
+ temp.assign (v.begin (), v.end ());
+ temp.swap (v);
+ }
+}
+
+template<class T>
+inline void clear_trimmed (T& v)
+{
+ T temp;
+ temp.swap (v);
+}
+
+template<class T>
+inline void push_back_trimmed (T& vec, const typename T::value_type& value)
+{
+ if (vec.size () + 1 != vec.capacity ())
+ {
+ T temp;
+ temp.reserve (vec.size () + 1);
+ temp.assign (vec.begin (), vec.end ());
+ temp.push_back (value);
+ temp.swap (vec);
+ }
+ else
+ vec.push_back (value);
+}
+
+template<class T>
+inline void erase_trimmed (T& vec, typename T::iterator i)
+{
+ AssertIf (i == vec.end ());
+
+ T temp;
+ temp.reserve (vec.size () - 1);
+ temp.assign (vec.begin (), i);
+ temp.insert (temp.end (), ++i, vec.end ());
+ vec.swap (temp);
+}
+
+#endif