diff --git a/octa/utility.h b/octa/utility.h new file mode 100644 index 0000000..f246f17 --- /dev/null +++ b/octa/utility.h @@ -0,0 +1,42 @@ +/* Utilities for OctaSTD. + * + * This file is part of OctaSTD. See COPYING.md for futher information. + */ + +#ifndef OCTA_UTILITY_H +#define OCTA_UTILITY_H + +#include + +/* must be in std namespace otherwise the compiler won't know about it */ +namespace std { + template + class initializer_list { + const T *p_buf; + size_t p_len; + + initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {} + public: + struct type { + typedef T value; + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + typedef const T *const_pointer; + typedef size_t size; + typedef ptrdiff_t difference; + }; + + initializer_list(): p_buf(NULL), p_len(0) {} + + size_t length() const { return p_len; } + + const T *get() const { return p_buf; } + }; +} + +namespace octa { + template using initializer_list = std::initializer_list; +} + +#endif \ No newline at end of file diff --git a/octa/vector.h b/octa/vector.h index 6697613..e22a89f 100644 --- a/octa/vector.h +++ b/octa/vector.h @@ -7,9 +7,11 @@ #define OCTA_VECTOR_H #include +#include #include "octa/new.h" #include "octa/traits.h" +#include "octa/utility.h" namespace octa { template @@ -21,11 +23,13 @@ namespace octa { enum { MIN_SIZE = 8 }; struct type { - typedef T value; - typedef T &reference; - typedef const T &const_reference; - typedef T *pointer; - typedef const T *const_pointer; + typedef T value; + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + typedef const T *const_pointer; + typedef size_t size; + typedef ptrdiff_t difference; }; explicit Vector(): p_buf(NULL), p_len(0), p_cap(0) {} @@ -37,7 +41,7 @@ namespace octa { while (cur != last) new (cur++) T(val); } - Vector(const Vector &v): p_buf(NULL), p_len(0), p_cap(0) { + Vector(const Vector &v): Vector() { *this = v; } @@ -46,6 +50,10 @@ namespace octa { v.p_len = v.p_cap = 0; } + Vector(initializer_list v): Vector() { + insert(0, v.length(), v.get()); + } + ~Vector() { clear(); } @@ -54,6 +62,7 @@ namespace octa { if (p_cap > 0) { if (octa::IsClass::value) { T *cur = p_buf, *last = p_buf + p_len; + while (cur != last) (*cur++).~T(); } delete[] (uchar *)p_buf; p_buf = NULL; @@ -197,6 +206,21 @@ namespace octa { p_len = p_cap = 0; return r; } + + T &insert(size_t idx, const T &v) { + push(); + for (size_t i = p_len - 1; i > idx; --i) p_buf[i] = p_buf[i - 1]; + p_buf[idx] = v; + } + + T *insert(size_t idx, size_t n, const T *v) { + if (p_len + n > p_cap) reserve(p_len + n); + for (size_t i = 0; i < n; ++i) push(); + for (size_t i = p_len - 1; i > idx + n; --i) + p_buf[i] = p_buf[i - n]; + for (size_t i = 0; i < n; ++i) p_buf[idx + i] = v[i]; + return &p_buf[idx]; + } }; }