Skip to content
This repository has been archived by the owner on Feb 24, 2019. It is now read-only.

Commit

Permalink
Master of life & death working.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZetaTwo committed Jan 13, 2015
1 parent 5dd9a35 commit eb02e16
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 25 deletions.
19 changes: 15 additions & 4 deletions 1lab/0.7_the_template_vector/counter_class.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
#pragma once

struct CounterClass {
CounterClass(int id) : id(id) { ++object_count; }
CounterClass() : id(0) { ++object_count; }
CounterClass(CounterClass const& o) : id(o.id) { ++object_count; }
~CounterClass() { --object_count; }
CounterClass(int id) : id(id) { inc(); }
CounterClass() : id(0) { inc(); }
CounterClass(CounterClass const& o) : id(o.id) { inc(); }
~CounterClass() { dec(); }

operator int() const {
return id;
}

static void inc() {
++object_count;
}
static void dec() {
--object_count;
}

static unsigned int object_count;
int id;
Expand Down
49 changes: 28 additions & 21 deletions 1lab/0.7_the_template_vector/kth_cprog_template_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,33 @@ class Vector {

size_t count; //Actual number of elements in the vector
size_t max_size; //Allocated memory for elements. Will be 2^n for some n
std::unique_ptr<T[]> data; //A pointer to the vector data

static void deleter(T*) {};
typedef std::unique_ptr<T[], void(*)(T*)> data_ptr;
data_ptr data; //A pointer to the vector data
std::allocator<T> allocator;

void increase_memory(size_t num_elements, bool copy = true); //Increases memory to fit at least num_elements number of elements
void release(std::unique_ptr<T[]>& data, size_t count, size_t max_size);
void release(data_ptr& data, size_t count, size_t max_size);
};

template<typename T>
std::ostream& operator<<(std::ostream& os, const Vector<T>& vector);

//Member implementations
template<typename T>
Vector<T>::Vector() : count(0), max_size(DEFAULT_SIZE), data(allocator.allocate(max_size)) {
Vector<T>::Vector() : count(0), max_size(DEFAULT_SIZE), data(allocator.allocate(max_size), deleter) {
}

template<typename T>
Vector<T>::Vector(const Vector<T>& other) : count(other.count), max_size(other.max_size), data(allocator.allocate(max_size)) {
Vector<T>::Vector(const Vector<T>& other) : count(other.count), max_size(other.max_size), data(allocator.allocate(max_size), deleter) {
for(size_t i = 0; i < count; ++i) {
allocator.construct(&data[i], other.data[i]);
}
}

template<typename T>
Vector<T>::Vector(const std::initializer_list<T>& list) : count(list.size()), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size)) {
Vector<T>::Vector(const std::initializer_list<T>& list) : count(list.size()), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size), deleter) {
size_t i;
typename std::initializer_list<T>::iterator item;
for(i = 0, item = list.begin(); item != list.end(); ++i, ++item) {
Expand All @@ -100,23 +103,19 @@ Vector<T>::Vector(const std::initializer_list<T>& list) : count(list.size()), ma

template<typename T>
Vector<T>::Vector(Vector<T>&& other) : data(std::move(other.data)), count(other.count), max_size(other.max_size) {
/*for (size_t i = 0; i < count; ++i) {
allocator.destroy(&other.data[i]);
}*/

other.count = 0;
other.max_size = 0;
}

template<typename T>
Vector<T>::Vector(size_t size) : count(size), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size)) {
Vector<T>::Vector(size_t size) : count(size), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size), deleter) {
for(size_t i = 0; i < count; ++i) {
allocator.construct(&data[i], T{});
}
}

template<typename T>
Vector<T>::Vector(size_t size, const T& element) : count(size), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size)) {
Vector<T>::Vector(size_t size, const T& element) : count(size), max_size(1 << static_cast<int>(ceil(log2(count)))), data(allocator.allocate(max_size), deleter) {
for(size_t i = 0; i < count; ++i) {
allocator.construct(&data[i], element);
}
Expand All @@ -130,7 +129,7 @@ Vector<T>::~Vector() {
}

template<typename T>
void Vector<T>::release(std::unique_ptr<T[]>& data, size_t count, size_t max_size) {
void Vector<T>::release(data_ptr& data, size_t count, size_t max_size) {
for (size_t i = 0; i < count; ++i) {
allocator.destroy(&data[i]);
}
Expand Down Expand Up @@ -162,12 +161,17 @@ Vector<T>& Vector<T>::operator=(const Vector<T>& other) {
return *this;
}

//Make sure we have enough room
if(other.count > max_size) {
increase_memory(other.count, false);
}
else {
clear();
}

//Create new copies
count = other.size();
for(size_t i = 0; i < other.count; ++i) {
for (size_t i = 0; i < count; ++i) {
allocator.construct(&data[i], other[i]);
}

Expand All @@ -177,6 +181,7 @@ Vector<T>& Vector<T>::operator=(const Vector<T>& other) {
template<typename T>
Vector<T>& Vector<T>::operator=(Vector<T>&& other) {
if (this != &other) {
release(data, count, max_size);
data = std::move(other.data);
count = other.count;
max_size = other.max_size;
Expand All @@ -191,10 +196,15 @@ Vector<T>& Vector<T>::operator=(Vector<T>&& other) {

template<typename T>
Vector<T>& Vector<T>::operator=(const std::initializer_list<T>& list) {
//Make sure we have enough room
if(list.size() > max_size) {
increase_memory(list.size(), false);
}
else {
clear();
}

//Construct new copies
count = list.size();
size_t i;
typename std::initializer_list<T>::iterator item;
Expand All @@ -221,23 +231,20 @@ Vector<T>& Vector<T>::insert(size_t index, const T& element) {
increase_memory(count + 1);
}

allocator.construct(&data[count]);

size_t i;
try {
for (i = count; i > index; i--) {
allocator.construct(&data[i], std::move_if_noexcept(data[i - 1]));
data[i] = std::move_if_noexcept(data[i - 1]);
}
}
catch (...) {
count = i;
throw;
}

if (index == count) {
allocator.construct(&data[index], element);
}
else {
data[index] = element;
}
data[index] = element;
++count;

return *this;
Expand Down Expand Up @@ -333,7 +340,7 @@ void Vector<T>::increase_memory(size_t num_elements, bool copy) {
throw std::invalid_argument("Vector already large enough");
}

std::unique_ptr<T[]> new_data(allocator.allocate(new_max_size));
data_ptr new_data(allocator.allocate(new_max_size), deleter);

if(copy) {
for(size_t i = 0; i < count; i++) {
Expand Down
45 changes: 45 additions & 0 deletions 1lab/0.7_the_template_vector/vector_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,49 @@ TEST(Vector, Kattis3) {
Vector<CounterClass> a(10, 42);
a.erase(0);
EXPECT_EQ(9, CounterClass::object_count);
}

TEST(Vector, Kattis4) {
Vector<CounterClass> a;
a.insert(0, 42);
a.insert(0, -43);
a.insert(1, 44);
a.insert(3, 45);
a.insert(0, 42);
EXPECT_EQ(5, CounterClass::object_count);
}

TEST(Vector, Kattis5) {
Vector<CounterClass> a{ 1, 2, 3, 4, 5 };
Vector<CounterClass> b(10);
//EXPECT_EQ(10, a.size());
Vector<CounterClass> c(0);

c = a;
a = b;
Vector<CounterClass> d(c);

/*EXPECT_EQ(10, a.size());
EXPECT_EQ(10, b.size());
EXPECT_EQ(10, c.size());*/

a[1] = 10;
b[2] = 11;
b.erase(0);
c[3] = 12;
c.erase(1);

/*EXPECT_EQ(10, a[1]);
EXPECT_NE(11, b[2]);
EXPECT_NE(12, c[3]);*/

//a.clear();
a.reset();
//EXPECT_EQ(0, a.size());
c = std::move(a);

a.clear();
c[3] = 25;
a = std::move(c);
b = a;
}

0 comments on commit eb02e16

Please sign in to comment.