summaryrefslogtreecommitdiff
path: root/src/vec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vec.cpp')
-rw-r--r--src/vec.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/vec.cpp b/src/vec.cpp
new file mode 100644
index 0000000..ad6b172
--- /dev/null
+++ b/src/vec.cpp
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#include "vec.h"
+
+#include <cassert>
+#include <cstdlib>
+
+template <typename T>
+void Vec<T>::expand(Vec<T>::size_type by)
+{
+ if (_size + by <= _capacity) {
+ return;
+ }
+ const size_type new_capacity = (_size + by) * 1.5f;
+ T *d{static_cast<T *>(calloc(new_capacity, sizeof (T)))};
+ assert(d);
+ if (_d) {
+ for (size_type i = 0; i < _size; i++) {
+ d[i] = static_cast<T &&>(_d[i]);
+ }
+ free(_d);
+ }
+ _d = d;
+ _capacity = new_capacity;
+}
+
+template <typename T>
+Vec<T>::Vec(const Vec& other)
+ : _size(other._size)
+ , _capacity(other._size)
+ , _d(static_cast<T *>(calloc(_capacity, sizeof (T))))
+{
+ assert(_d);
+ for (size_type i = 0; i < _size; i++) {
+ _d[i] = other._d[i];
+ }
+}
+
+template <typename T>
+Vec<T>::Vec(const T *data, size_type nmemb)
+ : _size(nmemb)
+ , _capacity(nmemb)
+ , _d(static_cast<T *>(calloc(_capacity, sizeof (T))))
+{
+ assert(_d);
+ for (size_type i = 0; i < _size; i++) {
+ _d[i] = static_cast<const T *>(data)[i];
+ }
+}
+
+template <typename T>
+Vec<T>::Vec(const void *data, size_type size)
+ : _size(size / sizeof (T))
+ , _capacity(size / sizeof (T))
+ , _d(static_cast<T *>(calloc(_capacity, sizeof (T))))
+{
+ assert(_d);
+ for (size_type i = 0; i < _size; i++) {
+ _d[i] = static_cast<const T *>(data)[i];
+ }
+}
+
+template <typename T>
+Vec<T>::~Vec()
+{
+ if (_d == nullptr) {
+ return;
+ }
+ for (size_type i = 0; i < _size; i++) {
+ _d[i].~T();
+ }
+ free(_d);
+ _d = nullptr;
+ _capacity = _size = 0;
+}
+
+template <typename T>
+Vec<T> &Vec<T>::operator=(const Vec &other)
+{
+ this->~Vec();
+ _size = _capacity = 0;
+ _d = nullptr;
+ expand(other._size);
+ for (size_type i = 0; i < other._size; i++) {
+ _d[i] = other._d[i];
+ }
+ _size = other._size;
+ return *this;
+}
+
+template <typename T>
+bool Vec<T>::operator==(const Vec& other) const
+{
+ if (_size != other._size) {
+ return false;
+ }
+ for (size_type i = 0; i < _size; i++) {
+ if (_d[i] != other._d[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+template class Vec<char>; // Used in vecutil.cpp
+template class Vec<int>; // Used in vec_tests.cpp
+template class Vec<Vec<int>>; // Used in vec_tests.cpp
+
+#include "tracetab.h"
+
+template class Vec<DataType>; // Used in tracetab.cpp
+template class Vec<TraceNode>; // Used in tracetab.cpp