Skip to content
This repository has been archived by the owner on Apr 6, 2024. It is now read-only.

collections/vector: implement dynamic table described in CLRS #2

Merged
merged 17 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/bazel-*
.idea
89 changes: 51 additions & 38 deletions src/collections/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@
#include <algorithm>
#include <optional>

template <typename T>
class Vec {
public:
template <typename T> class Vec {
public:
Vec();
virtual ~Vec();

private:
T* buf;
private:
T *buf;
size_t len;
size_t _capacity;
void reallocate();

public:
public:
// Get the length of the vector
size_t size();

// Get the size of underneath array
size_t capacity();

// Set the size of underneath array to at least len + additional
// Do nothing if capacity already greater than len + additional
void reserve(size_t additional);

// Examine if the vector is empty.
bool is_empty();

Expand All @@ -31,57 +39,62 @@ class Vec {
T operator[](size_t index);
};

template <typename T>
inline Vec<T>::Vec()
{
template <typename T> inline Vec<T>::Vec() {
this->buf = nullptr;
len = 0;
iosmanthus marked this conversation as resolved.
Show resolved Hide resolved
_capacity = 0;
}

template <typename T>
inline size_t Vec<T>::size()
{
return this->len;
template <typename T> void Vec<T>::reallocate() {
T *new_buf = new T[this->_capacity];
std::copy(this->buf, this->buf + this->len, new_buf);
delete[] buf;
buf = new_buf;
}

template <typename T>
inline Vec<T>::~Vec()
{
if (this->len == 0)
delete[] this->buf;
template <typename T> inline size_t Vec<T>::size() { return this->len; }

template <typename T> inline size_t Vec<T>::capacity() {
return this->_capacity;
}

template <typename T>
inline bool Vec<T>::is_empty()
{
return this->len == 0;
template <typename T> void Vec<T>::reserve(size_t additional) {
size_t new_capacity = this->len + additional;
if (this->_capacity < new_capacity) {
this->_capacity = new_capacity;
reallocate();
}
}

template <typename T>
void Vec<T>::push(T data)
{
T* new_buf = new T[this->len + 1];
std::copy(this->buf, this->buf + this->len, new_buf);
new_buf[this->len] = data;
template <typename T> inline Vec<T>::~Vec() {
if (this->len == 0)
delete[] this->buf;
}

delete[] this->buf;
template <typename T> inline bool Vec<T>::is_empty() { return this->len == 0; }

this->buf = new_buf;
this->len++;
template <typename T> void Vec<T>::push(T data) {
size_t total = this->len + 1;
if (total > this->_capacity) {
size_t new_capacity = total * 3 / 2 + 1;
iosmanthus marked this conversation as resolved.
Show resolved Hide resolved
this->_capacity = new_capacity;
reallocate();
}
buf[this->len++] = data;
}

template <typename T>
std::optional<T> Vec<T>::pop()
{
if (this->len > 0)
template <typename T> std::optional<T> Vec<T>::pop() {
if (this->len > 0) {
fengkx marked this conversation as resolved.
Show resolved Hide resolved
if ((this->_capacity / this->len) > 2) {
reserve((this->len - 1) / 2);
}
return this->buf[this->len-- - 1];
}

return {};
}

template <typename T>
T Vec<T>::operator[](size_t idx)
{
template <typename T> T Vec<T>::operator[](size_t idx) {
if (idx < this->len)
return this->buf[idx];
else
Expand Down
19 changes: 19 additions & 0 deletions tests/test-vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,22 @@ TEST(TestVec, TestPop)
EXPECT_EQ(233, vec.pop().value());
EXPECT_EQ(std::nullopt, vec.pop());
}

TEST(TestVec, TestCapacity)
{
Vec<int> vec;
EXPECT_EQ(0, vec.capacity());
vec.push(123);
EXPECT_EQ(1 * 3/2 +1, vec.capacity());
iosmanthus marked this conversation as resolved.
Show resolved Hide resolved

}

TEST(TestVec, TestReserve)
{
Vec<int> vec;
vec.push(1);
vec.push(11);
int additional = 5;
vec.reserve(additional);
EXPECT_GE(vec.capacity(), vec.size() + additional);
}