summaryrefslogtreecommitdiff
path: root/src/vec.h
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2025-01-03 17:07:00 +0300
committerOxore <oxore@protonmail.com>2025-01-07 14:39:01 +0300
commitcb96278e25140cfcc1afc22df2102bcf3b6ae38c (patch)
tree9e93bd8a5fb4d5fbc177924b6b25ca8cd04e7fd7 /src/vec.h
parent810dc87cd5173f8cfc81c774fd49cf8f928a9ae8 (diff)
Impl extended trace table format parser
Diffstat (limited to 'src/vec.h')
-rw-r--r--src/vec.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/vec.h b/src/vec.h
new file mode 100644
index 0000000..98c760a
--- /dev/null
+++ b/src/vec.h
@@ -0,0 +1,83 @@
+#pragma once
+
+/* SPDX-License-Identifier: Unlicense
+ */
+
+/*! A data vector implementation.
+ *
+ * The sole purpose of this vector implementation is to not use std::vector,
+ * because it greatly increases compilation times even if you just type
+ * `#include <vector>`. And since there is no exceptions enabled in m68k-disasm
+ * project, I consider it to be fine to have an implementation this bold. I also
+ * don't need all the features of original std::vector an this implementation
+ * provide only a small portion of them.
+ * */
+template <typename T>
+class Vec {
+public:
+ using size_type = decltype(sizeof 0);
+private:
+ size_type _size{};
+ size_type _capacity{};
+ T *_d{};
+ void expand(size_type by);
+public:
+ constexpr explicit Vec() {}
+ Vec(const Vec& other);
+ Vec(const T *data, size_type nmemb);
+ Vec(const void *data, size_type size);
+ constexpr Vec(Vec&& other)
+ : _size(other._size), _capacity(other._capacity), _d(other._d)
+ {
+ other._d = nullptr;
+ other._capacity = other._size = 0;
+ }
+ Vec &operator=(const Vec &other);
+ Vec &operator=(Vec &&other)
+ {
+ // In case if `other` points to `this` we have to store it's state on
+ // the stack before calling destructor of `this`.
+ const size_type size = other._size;
+ const size_type capacity = other._capacity;
+ T *const d = other._d;
+ other._d = nullptr;
+ other._capacity = other._size = 0;
+ this->~Vec();
+ _size = size;
+ _capacity = capacity;
+ _d = d;
+ return *this;
+ }
+ ~Vec();
+ Vec<T> &PushBack(const T &value)
+ {
+ expand(1);
+ _d[_size++] = static_cast<const T &>(value);
+ return *this;
+ }
+ Vec<T> &PushBack(T &&value)
+ {
+ expand(1);
+ _d[_size++] = static_cast<T &&>(value);
+ return *this;
+ }
+ T PopBack(void) { return static_cast<T &&>(_d[--_size]); }
+ constexpr T *Extract(void)
+ {
+ T *d = _d;
+ _d = nullptr;
+ _size = _capacity = 0;
+ return d;
+ }
+ constexpr size_type Size(void) const { return _size; }
+ constexpr size_type Capacity(void) const { return _capacity; }
+ constexpr T *begin(void) { return _d; }
+ constexpr T *end(void) { return _d + _size; }
+ constexpr const T& operator[](size_type index) const { return *(_d + index); }
+ constexpr T& operator[](size_type index) { return *(_d + index); }
+ bool operator==(const Vec& other) const;
+ bool operator!=(const Vec& other) const
+ {
+ return !(*this == other);
+ }
+};