diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6d8ad95
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+bazel-*
\ No newline at end of file
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..b8d56be
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,10 @@
+cc_library(
+ name = "build_header",
+ hdrs = [
+ "ali_vector.h"
+ ],
+ copts = [
+ "-std=c++2a",
+ ],
+ visibility = ["//visibility:public"]
+)
diff --git a/README.md b/README.md
index 6fcb573..2524557 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,10 @@
# vector
+
My implementation of std::vector
+
+## How to test?
+
+
+
$ bazel test tests:ali_vector_test --repo_env=CC=c++
+
+
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..b54973d
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,7 @@
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+ name = "googletest",
+ remote = "https://github.com/google/googletest",
+ tag = "release-1.10.0",
+)
diff --git a/ali_vector.h b/ali_vector.h
new file mode 100644
index 0000000..583eba7
--- /dev/null
+++ b/ali_vector.h
@@ -0,0 +1,205 @@
+//
+// Created by Ali Moameri on 4/10/22.
+//
+
+#ifndef ALI_VECTOR_H
+#define ALI_VECTOR_H
+
+#include
+#include
+#include
+#include
+
+namespace ali {
+ template class vector {
+ public:
+ vector()
+ : m_size{0}, m_capacity{0}, ptr{nullptr} {}
+
+ explicit vector(const std::size_t& _size)
+ : m_size{_size}, m_capacity{_size * 2} {
+ ptr = m_alloc.allocate(m_capacity);
+ }
+
+ explicit vector(const std::size_t& _size, const T& value)
+ : m_size{_size}, m_capacity{_size * 2} {
+ ptr = m_alloc.allocate(m_capacity);
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.construct(ptr + i, value);
+ }
+
+ vector(const std::initializer_list& ls)
+ : m_size{ls.size()}, m_capacity{ls.size() * 2} {
+ ptr = m_alloc.allocate(m_capacity);
+ for(std::size_t i{0}; i < ls.size(); ++i)
+ m_alloc.construct(ptr + i, *(ls.begin() + i));
+ }
+
+ vector(const ali::vector& rhs)
+ :m_size{rhs.size()}, m_capacity{rhs.capacity()} {
+ ptr = m_alloc.allocate(m_capacity);
+ for(std::size_t i{0}; i < rhs.size(); ++i)
+ m_alloc.construct(ptr + i, rhs[i]);
+ }
+
+ vector(ali::vector&& rhs) noexcept
+ :m_size{rhs.size()}, m_capacity{rhs.capacity()} {
+ ptr = m_alloc.allocate(m_capacity);
+ for(std::size_t i{0}; i < rhs.size(); ++i)
+ m_alloc.construct(ptr + i, rhs[i]);
+ rhs.clear();
+ m_capacity = 0;
+ }
+
+ ~vector() { m_alloc.deallocate(ptr, m_capacity); }
+
+ [[nodiscard]] constexpr std::size_t size() const noexcept { return m_size; }
+ [[nodiscard]] constexpr std::size_t capacity() const noexcept { return m_capacity; }
+
+ void clear() noexcept {
+ delete[] ptr;
+ ptr = nullptr;
+ m_size = 0;
+ }
+
+ void push_back(const T& value) {
+ if(m_capacity == 0)
+ reserve(8);
+ else if(m_size == m_capacity)
+ reserve(m_size * 2);
+ ptr[m_size++] = value;
+ }
+
+
+ void pop_back() {
+ m_size = m_size > 0 ? m_size - 1 : m_size;
+ }
+
+ T& at(std::size_t index) {
+ if (index < m_size)
+ return ptr[index];
+ else
+ throw std::out_of_range("index out of range");
+ }
+
+ const T& at(std::size_t index) const {
+ if (index < m_size)
+ return ptr[index];
+ else
+ throw std::out_of_range("index out of range");
+ }
+
+ void shrink_to_fit() {
+ if (m_size < m_capacity) {
+ T* new_ptr{m_alloc.allocate(m_size)};
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.construct(new_ptr + i, ptr[i]);
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.destroy(ptr + i);
+ m_alloc.deallocate(ptr, m_capacity);
+ ptr = new_ptr;
+ m_capacity = m_size;
+ }
+ }
+
+ void reserve(std::size_t space) {
+ if (space > m_capacity) {
+ T* new_ptr{m_alloc.allocate(space)};
+
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.construct(new_ptr + i, ptr[i]);
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.destroy(ptr + i);
+
+ m_alloc.deallocate(ptr, m_capacity);
+ ptr = new_ptr;
+ m_capacity = space;
+ }
+ }
+
+ [[nodiscard]] bool empty() const { return size() == 0; }
+
+ void swap(ali::vector& rhs) {
+ std::swap(m_size, rhs.m_size);
+ std::swap(m_capacity, rhs.m_capacity);
+ std::swap(m_alloc, rhs.m_alloc);
+ std::swap(ptr, rhs.ptr);
+ }
+
+ T& operator[](const std::size_t& index) {
+ if(index >= size())
+ throw std::out_of_range("out of range index");
+ else
+ return ptr[index];
+ }
+
+ const T& operator[](const std::size_t& index) const {
+ if(index >= size())
+ throw std::out_of_range("out of range index");
+ else
+ return ptr[index];
+ }
+
+ ali::vector& operator=(const ali::vector& rhs) noexcept {
+ if(this == &rhs)
+ return *this;
+
+ if(rhs.size() <= m_capacity) {
+ std::copy(rhs.ptr, rhs.ptr + rhs.size(), ptr);
+ m_size = rhs.size();
+ return *this;
+ }
+
+ T* new_ptr{m_alloc.allocate(rhs.size())};
+ for(std::size_t i{0}; i < rhs.size(); ++i)
+ m_alloc.construct(new_ptr + i, rhs[i]);
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.destroy(ptr + i);
+ m_alloc.deallocate(ptr, m_capacity);
+ ptr = new_ptr;
+ m_capacity = m_size = rhs.size();
+ return *this;
+ }
+
+ ali::vector& operator=(ali::vector&& rhs) noexcept {
+ if(this == &rhs)
+ return *this;
+
+ if(rhs.size() <= m_capacity) {
+ std::copy(rhs.ptr, rhs.ptr + rhs.size(), ptr);
+ m_size = rhs.size();
+ } else {
+ T* new_ptr{m_alloc.allocate(rhs.size())};
+ for(std::size_t i{0}; i < rhs.size(); ++i)
+ m_alloc.construct(new_ptr + i, rhs[i]);
+ for(std::size_t i{0}; i < m_size; ++i)
+ m_alloc.destroy(ptr + i);
+ m_alloc.deallocate(ptr, m_capacity);
+ ptr = new_ptr;
+ m_capacity = m_size = rhs.size();
+ }
+
+ rhs.clear();
+ rhs.m_capacity = 0;
+ return *this;
+ }
+
+ bool operator==(const vector &rhs) const {
+ if (size() != rhs.size())
+ return false;
+ for (std::size_t i{0}; i < size(); ++i) {
+ if (ptr[i] != rhs[i])
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ std::size_t m_size{0};
+ std::size_t m_capacity{0};
+ std::allocator m_alloc;
+ T* ptr{nullptr};
+ };
+}
+
+#endif //ALI_VECTOR_H
diff --git a/tests/BUILD b/tests/BUILD
new file mode 100644
index 0000000..be95c33
--- /dev/null
+++ b/tests/BUILD
@@ -0,0 +1,11 @@
+cc_test(
+ name = "ali_vector_test",
+ srcs = glob(["**/*.cc"]),
+ copts = [
+ "-std=c++2a",
+ ],
+ deps = [
+ "//:build_header",
+ "@googletest//:gtest_main",
+ ],
+)
diff --git a/tests/ali_vector_ptr_test.cc b/tests/ali_vector_ptr_test.cc
new file mode 100644
index 0000000..9e8f43c
--- /dev/null
+++ b/tests/ali_vector_ptr_test.cc
@@ -0,0 +1,99 @@
+#include "ali_vector.h"
+#include
+#include
+
+struct T {
+ int x;
+
+ T(const int input) : x(input)
+ {}
+};
+
+constexpr std::size_t size {10};
+constexpr std::size_t capacity {size*2};
+
+TEST(VectorTest, DefaultConstructor) {
+ ali::vector v;
+ EXPECT_EQ(v.size(), 0);
+ EXPECT_EQ(v.capacity(), 0);
+}
+
+TEST(VectorTest, Constructors) {
+ ali::vector v(size);
+ EXPECT_EQ(v.size(), size);
+ EXPECT_EQ(v.capacity(), capacity);
+
+ ali::vector v2(size, 6);
+ EXPECT_EQ(v2.size(), size);
+ EXPECT_EQ(v2.capacity(), capacity);
+ EXPECT_EQ(v2[5].x, 6);
+
+ ali::vector v3{1, 2 ,3 ,4};
+ EXPECT_EQ(v3.size(), 4);
+ EXPECT_EQ(v3[1].x, 2);
+}
+
+TEST(VectorTest, CopyConstructor) {
+ ali::vector v{1, 2, 3};
+ ali::vector v2{v};
+ EXPECT_EQ(v == v2, true);
+}
+
+TEST(VectorTest, MoveConstructor) {
+ ali::vector v{1, 2, 3};
+ ali::vector v2{std::move(v)};
+ EXPECT_EQ(v.empty(), true);
+ EXPECT_EQ(v2[1].x, 2);
+}
+
+TEST(VectorTest, Clear) {
+ ali::vector v{1, 2, 3};
+ v.clear();
+ EXPECT_EQ(v.size(), 0);
+}
+
+TEST(VectorTest, PushBack) {
+ ali::vector v{1, 2, 3};
+ v.push_back(T{4});
+ EXPECT_EQ(v.size(), 4);
+ EXPECT_EQ(v[3].x, 4);
+}
+
+TEST(VectorTest, PopBack) {
+ ali::vector v{1, 2, 3};
+ v.pop_back();
+ EXPECT_EQ(v.size(), 2);
+}
+
+TEST(VectorTest, Empty) {
+ ali::vector v{1, 2, 3};
+ ali::vector v2;
+ EXPECT_EQ(v.empty(), false);
+ EXPECT_EQ(v2.empty(), true);
+}
+
+TEST(VectorTest, Assigment) {
+ ali::vector v{1, 2, 3};
+ ali::vector v2;
+ v2 = v;
+ for(std::size_t i{0}; i < v.size(); ++i)
+ EXPECT_EQ(v[i].x, v2[i].x);
+}
+
+TEST(VectorTest, MoveAssigment) {
+ ali::vector v{1, 2, 3};
+ ali::vector v2{v};
+ ali::vector v3;
+ v3 = std::move(v);
+
+ for(std::size_t i{0}; i < v3.size(); ++i)
+ EXPECT_EQ(v3[i].x, v2[i].x);
+
+ EXPECT_EQ(v.empty(), true);
+}
+
+TEST(VectorTest, ConstDerefence) {
+ const ali::vector v{1, 2, 3};
+ EXPECT_EQ(v[2].x, 3);
+}
+