Skip to content

Commit

Permalink
vector (#56)
Browse files Browse the repository at this point in the history
Implementation of vector
  • Loading branch information
ivanallen authored May 15, 2019
1 parent d1ca0d0 commit 221ff0f
Show file tree
Hide file tree
Showing 21 changed files with 183 additions and 504 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ set(GTEST_URL_MD5 "16877098823401d1bf2ed7891d7dce36")

#add_library(dsa SHARED ${DSA_SRC_FILES})

add_subdirectory(examples/tree)
add_subdirectory(examples)

if (DSA_BUILD_TESTS)
ExternalProject_Add(googletest_ep
Expand Down
116 changes: 116 additions & 0 deletions dsa/include/vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2019 DSA authors.
* All rights reserved.
* Authors: Allen
*/

// 动态数组
//

#pragma once

#include <new>
#include <type_traits>
#include <string.h>

namespace dsa {

template <typename T>
class Vector {
public:
typedef T* Iterator;

Vector() {}

Vector(size_t n) {
_start = new Storage[n];
_finish = _start;
_end_of_storage = _start + n;
}

// TODO:
Vector(int size, const T& a);

// TODO:
Vector(const Vector<T>& a);

// TODO:
Vector(Iterator first, Iterator last);

~Vector() {
if (_start == nullptr) return;
for (auto it = _start; it != _finish; ++it) {
reinterpret_cast<T*>(it)->~T();
}
delete[] _start;
}

size_t size() const {
return _finish - _start;
}

size_t capacity() const {
return _end_of_storage - _start;
}

// about std::launder: https://stackoverflow.com/questions/39382501/what-is-the-purpose-of-stdlaunder
template <typename U>
void push_back(U&& val) {
if (_finish == _end_of_storage) {
size_t old_size = size();
size_t len = old_size == 0 ? 1 : 2 * old_size;
auto new_start = new Storage[len];
if (_start) {
memmove(new_start, _start, _finish - _start);
for (auto it = _start; it != _finish; ++it) {
std::launder(reinterpret_cast<T*>(it))->~T();
}
delete[] _start;
_start = new_start;
_finish = _start + old_size;
_end_of_storage = _start + len;
} else {
_start = new_start;
_finish = _start;
_end_of_storage = _start + len;
}
}
new (_finish) T(std::forward<U>(val));
++_finish;
}

// TODO:
void pop_back();

const T& operator[](int index) const {
// TODO: throw exception if index invalid
return *std::launder(reinterpret_cast<const T*>(&_start[index]));
}

T& operator[](int index) {
// TODO: throw exception if index invalid
return *std::launder(reinterpret_cast<T*>(&_start[index]));
}

// TODO:
Vector<T>& operator=(const Vector<T>& a);
Vector<T>& operator=(Vector<T>&& a);

bool empty() const {
return _start == _finish;
}

Iterator begin() const {
return std::launder(reinterpret_cast<T*>(_start));
}
Iterator end() const {
return std::launder(reinterpret_cast<T*>(_finish));
}
private:
using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
Storage* _start = nullptr;
Storage* _finish = nullptr;
Storage* _end_of_storage = nullptr;
};

} // namespace dsa
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory(tree)
add_subdirectory(linear)
1 change: 1 addition & 0 deletions examples/linear/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_executable(vector_examples vector_example.cpp)
45 changes: 45 additions & 0 deletions examples/linear/vector_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <iostream>
#include "vector.h"

using namespace dsa;

class Foo {
friend std::ostream& operator<<(std::ostream& out, const Foo& foo);
public:
Foo(int n, int data) : n(n), data(data) {
std::cout << "Foo():" << data << std::endl;
};
~Foo() {
std::cout << "~Foo():" << data << std::endl;
}

Foo(Foo&& foo) : n(foo.n) {
std::cout << "Foo(Foo&&)" << std::endl;
data = foo.data;
}
const int n;
int data = 0;
};

std::ostream& operator<<(std::ostream& out, const Foo& foo) {
return out << foo.data;
}

int main() {
Vector<Foo> v(50);

for (int i = 0; i < 10; ++i) {
v.push_back(Foo(i, i*2));
}

for (auto& e : v) {
std::cout << e << " ";
}
std::cout << std::endl;

for (int i = 0; i < v.size(); ++i) {
std::cout << v[i].n << " ";
}
std::cout << std::endl;
return 0;
}
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ function(dsa_test test_name)
endfunction()

dsa_test(binary_tree_test)
dsa_test(vector_test)
120 changes: 0 additions & 120 deletions test/binary_search_tree_test.cpp

This file was deleted.

4 changes: 2 additions & 2 deletions test/binary_tree_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "binary_tree.h"

namespace dsa {
namespace test {
namespace {

using Tree = BinaryTree<int>;

Expand Down Expand Up @@ -201,5 +201,5 @@ TEST(BinaryTreeTest, Rotate) {
EXPECT_EQ(dump, expect);
}

} // namespace test
}
} // namespace dsa
46 changes: 0 additions & 46 deletions test/btree_test.cpp

This file was deleted.

28 changes: 0 additions & 28 deletions test/demo_test.cpp

This file was deleted.

Loading

0 comments on commit 221ff0f

Please sign in to comment.