libostd/octa/vector.h

72 lines
1.9 KiB
C
Raw Normal View History

2015-04-06 01:05:21 +02:00
/* Self-expanding dynamic array implementation for OctaSTD.
*
2015-04-12 22:41:02 +02:00
* This file is part of OctaSTD. See COPYING.md for futher information.
2015-04-06 01:05:21 +02:00
*/
2015-04-11 22:00:10 +02:00
#ifndef OCTA_VECTOR_H
#define OCTA_VECTOR_H
2015-04-06 01:05:21 +02:00
2015-04-13 23:25:31 +02:00
#include "octa/new.h"
#include "octa/traits.h"
2015-04-06 01:05:21 +02:00
2015-04-11 22:00:10 +02:00
namespace octa {
2015-04-06 01:05:21 +02:00
template<typename T>
2015-04-12 22:41:02 +02:00
class Vector {
2015-04-06 01:05:21 +02:00
T *buf;
size_t length, capacity;
public:
explicit vector(): buf(NULL), length(0), capacity(0) {}
vector(const vector &v): buf(NULL), length(0), capacity(0) {
*this = v;
}
~vector() {
2015-04-12 22:41:02 +02:00
resize(0);
if (buf) delete[] (unsigned char *)buf;
2015-04-06 01:05:21 +02:00
}
vector<T> &operator=(const vector<T> &v) {
2015-04-12 22:41:02 +02:00
resize(0);
if (v.length() > capacity) resize(v.length());
for (size_t i = 0; i < v.length(); ++i) push(v[i]);
2015-04-06 01:05:21 +02:00
return *this;
}
2015-04-12 22:41:02 +02:00
T &push(const T &v) {
if (length == capacity) resize(length + 1);
new (&buf[length]) T(v);
return buf[length++];
}
T &push() {
if (length == capacity) resize(length + 1);
new (&buf[length]) T;
return buf[length++];
}
void resize(size_t n) {
if (n <= length) {
if (n == length) return;
while (length > n) pop();
return;
}
int old = capacity;
if (!old)
capacity = max(n, 8);
else
while (capacity < n) capacity += (capacity / 2);
if (capacity <= old)
return;
unsigned char *nbuf = new unsigned char[capacity * sizeof(T)];
if (old > 0) {
if (length > 0) memcpy(nbuf, (void *)buf, length * sizeof(T));
delete[] (unsigned char *)buf;
}
buf = (T *)buf;
}
2015-04-06 01:05:21 +02:00
};
}
#endif