Skip to content

Commit

Permalink
adding part of tests for advanced vector
Browse files Browse the repository at this point in the history
  • Loading branch information
s0mewha7 committed May 30, 2024
1 parent ed31866 commit fc8b725
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 38 deletions.
181 changes: 181 additions & 0 deletions advanced_vector_hw/adv_vector_testing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#include <iostream>
#include <algorithm>
#include <gtest/gtest.h>
#include <stdexcept>
#include <string>
#include <vector>

#include "advanced_vector.h"

struct nocopyconstructed {
explicit nocopyconstructed(size_t value_) : value(value_) {}
nocopyconstructed() = delete;
~nocopyconstructed() = default;
nocopyconstructed(nocopyconstructed &other) = delete; /// Copy constructor is not allowed

/// move constructor is default
nocopyconstructed &operator=(const nocopyconstructed &other) = default;
nocopyconstructed &operator=(nocopyconstructed &&other) = default;

friend bool operator==(nocopyconstructed right, nocopyconstructed left) {
return left.value == right.value;
}
[[nodiscard]] size_t getvalue() const noexcept {
return value;
}
size_t value;
};

struct nomoveconstructed {
explicit nomoveconstructed(size_t value_) : value(value_) {}
nomoveconstructed() = delete;
~nomoveconstructed() = default;

nomoveconstructed(nomoveconstructed &other) = default; /// copy constructor in allowed
nomoveconstructed &operator=(const nomoveconstructed &other) = delete;
nomoveconstructed &operator=(nomoveconstructed &&other) = delete;

friend bool operator==(nomoveconstructed right, nomoveconstructed left) {
return left.value == right.value;
}

[[nodiscard]] size_t getvalue() const noexcept {
return value;
}

size_t value;
};

template <typename Type>
void element_checking(bmstu::advanced_vector<Type> &curr, const Type &value = Type{}) {
for (size_t index = 0; index < curr.size(); ++index) {
ASSERT_EQ(curr[index], value);
}
}

// Without any Default Constructor
struct nodefaultconstructed {
size_t value;
explicit nodefaultconstructed(size_t value) : value(value) {}

nodefaultconstructed() = delete;

friend bool operator==(nodefaultconstructed left, nodefaultconstructed right) {
return left.value == right.value;
}

~nodefaultconstructed() = default;
[[nodiscard]] size_t getvalue() const noexcept {
return value;
}

};

TEST(DefaultConstructor, WithoutDefaultConstruct) {
bmstu::advanced_vector<nodefaultconstructed> vec;
ASSERT_TRUE(vec.empty());
ASSERT_EQ(vec.capacity(), 0);
}

TEST(DefaultConstructor, WSTRINGS) {
bmstu::advanced_vector<std::wstring> vec;
ASSERT_TRUE(vec.empty());
ASSERT_EQ(vec.capacity(), 0);
}

TEST(ParamConstuctor, WithoutDefaultConstruct) {
bmstu::advanced_vector<nodefaultconstructed> vec(10);
ASSERT_EQ(vec.size(), 10);

}

TEST(ParamConstructor, INTEGER) {
bmstu::advanced_vector<int> vec(10);
ASSERT_EQ(vec.size(), 10);
element_checking(vec, 0);
}

TEST(ParamConstructor, WSTRING) {
bmstu::advanced_vector<std::wstring> vec(10);
ASSERT_EQ(vec.size(), 10);
for (size_t index = 0; index < vec.size(); ++index) {
ASSERT_EQ(vec[index], L"");
}
}

TEST(InitializerListConstruct, INTEGER) {
bmstu::advanced_vector<int> ilist{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> expected{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (size_t index = 0; index < ilist.size(); ++index) {
ASSERT_EQ(ilist[index], index + 1);
}
}

TEST(InitializerListConstruct, WSTRINGS) {
using namespace std::literals;
bmstu::advanced_vector<std::wstring> juggernaut{L"Сундук для рун"s, L"рундук!"s};
ASSERT_EQ(juggernaut[0], L"Сундук для рун"s);
ASSERT_EQ(juggernaut[1], L"рундук!"s);
}

TEST(CopyConstruct, INTEGER) {
bmstu::advanced_vector<int> vec{2, 2, 8, 8, 8};
bmstu::advanced_vector<int> copied(vec);
ASSERT_TRUE(vec == copied);
}

TEST(CopyConstruct, WSTRING) {
bmstu::advanced_vector<std::wstring> naga_siren{L"Мои ноги!", L"Я не чувствую своих ног."};
bmstu::advanced_vector<std::wstring> copied_replica = naga_siren;
ASSERT_TRUE(naga_siren == copied_replica);
}

TEST(MoveConstructor, Integer) {
bmstu::advanced_vector<int> vec{1, 1, 1, 1, 1};
bmstu::advanced_vector<int> moved(std::move(vec));
ASSERT_EQ(moved.size(), 5);
element_checking(moved, 1);
}

TEST(MoveConstructor, string) {
bmstu::advanced_vector<std::wstring> runduk{L"Рундук", L"Рундук", L"Рундук",
L"Рундук", L"Рундук"};
bmstu::advanced_vector<std::wstring> moved(std::move(runduk));
std::wstring runduk_str = L"Рундук";
ASSERT_EQ(runduk_str, runduk_str);
element_checking(moved, runduk_str);
}

TEST(CopyAssignment, INTEGER) {
bmstu::advanced_vector<int> numbers{1, 2, 3, 4, 5};
bmstu::advanced_vector<int> copied = numbers;
ASSERT_TRUE(numbers == copied);
}

TEST(CopyAssignment, WSTRING) {
bmstu::advanced_vector<std::wstring> naga_siren{L"Мои ноги!", L"Я не чувствую своих ног."};
bmstu::advanced_vector<std::wstring> copied = naga_siren;
ASSERT_TRUE(naga_siren == copied);
}

TEST(MoveAssignment, INTEGER) {
bmstu::advanced_vector<int> vec{1, 1, 1, 1, 1};
bmstu::advanced_vector<int> move = std::move(vec);
ASSERT_EQ(move.size(), 5);
element_checking(move, 1);
}

TEST(MoveAssignment, WSTRING) {
bmstu::advanced_vector<std::wstring> runduk{L"Рундук", L"Рундук", L"Рундук",
L"Рундук", L"Рундук"};
bmstu::advanced_vector<std::wstring> moved = std::move(runduk);
ASSERT_EQ(moved.size(), 5);
for (size_t i = 0; i < moved.size(); ++i) {
ASSERT_EQ(moved[i], L"Рундук");
}
}

TEST(Reserve, INTEGER) {
bmstu::advanced_vector<std::wstring> naga_siren{L"Мои ноги!", L"Я не чувствую своих ног."};
naga_siren.reserve(10);
}
78 changes: 42 additions & 36 deletions advanced_vector_hw/advanced_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,29 @@ class advanced_vector {
pointer m_ptr;
};
using const_iterator = const iterator;

advanced_vector() noexcept = default;
explicit advanced_vector(size_t size) : size_(size), data_(size) {
std::uninitialized_value_construct_n(data_.get_address(), size);
explicit advanced_vector(size_t size) : size_(size), data_(size) { // WTF?? WHY IT DOESNT WORKS WITHOUT CONSTEXPR!?!!?
if constexpr (std::is_default_constructible_v<Type>) {
std::uninitialized_value_construct_n(data_.get_address(), size);
}
}

// Destructor
~advanced_vector() {
std::destroy_n(data_.GetAddress(), size_);
if (size_ != 0) {
std::destroy_n(data_.get_address(), size_);
}
}

advanced_vector(const advanced_vector &other) : data_(other.size_), size_(other.size_) {
std::uninitialized_copy_n(other.data_.get_address(), other.size_, data_.get_address());
std::uninitialized_copy_n(other.data_.get_address(), other.size_, this->data_.get_address());
}

advanced_vector(advanced_vector &&other) noexcept :
data_(std::move(other.data_)),
size_(std::move(other.size_)) {
other.size_ = 0;
advanced_vector(advanced_vector &&dying) noexcept :
data_(std::move(dying.data_)),
size_(std::move(dying.size_)) {
dying.size_ = 0;
}

[[nodiscard]] size_t size() const noexcept {
Expand All @@ -113,7 +118,11 @@ class advanced_vector {
}

advanced_vector(std::initializer_list<Type> ilist) : data_(ilist.size()), size_(ilist.size()) {
std::copy(ilist.begin(), ilist.end(), begin());
if constexpr (std::is_nothrow_move_constructible_v<Type> || !std::is_copy_constructible_v<Type>) {
std::uninitialized_move_n(ilist.begin(), ilist.size(), data_.get_address());
} else {
std::uninitialized_copy_n(ilist.begin(), ilist.size(), data_.get_address());
}
}

void clear() {
Expand All @@ -124,7 +133,7 @@ class advanced_vector {
if (this != &other) {
if (other.size_ > data_.capacity()) {
advanced_vector other_copy(other);
Swap(other_copy);
this->swapping(other_copy);
} else {
if (other.size_ < size_) {
std::copy_n(other.data_.GetAddress(), other.size_, data_.GetAddress());
Expand All @@ -142,19 +151,20 @@ class advanced_vector {

advanced_vector &operator=(advanced_vector &&other) noexcept {
if (this != &other) {
data_.swap(other.data_);
std::swap(size_, other.size_);
data_ = std::move(other.data_);
size_ = other.size_;
other.size_ = 0;
}
return *this;
}

// Iterators
const_iterator begin() const noexcept {
return const_cast<advanced_vector&>(*this).begin();
return const_iterator(const_cast<advanced_vector&>(*this).begin());
}

const_iterator end() const noexcept {
return const_cast<advanced_vector&>(*this).end();
return const_iterator(const_cast<advanced_vector&>(*this).end());
}

const_iterator cbegin() const noexcept {
Expand All @@ -172,11 +182,11 @@ class advanced_vector {

// Iterators
iterator begin() {
return data_.get_address();
return iterator(data_.get_address());
}

iterator end() {
return data_.get_address() + size_;
return iterator(data_.get_address() + size_);
}

typename iterator::reference operator[](size_t index) noexcept {
Expand Down Expand Up @@ -298,23 +308,16 @@ class advanced_vector {
}

// Bool operators
friend bool operator==(const advanced_vector<Type> &left , const advanced_vector<Type> &right) {
return left == right;
}
friend bool operator!=(const advanced_vector<Type> &left, const advanced_vector<Type> &right) {
return !(left == right);
}
friend bool operator<(const advanced_vector<Type> &left, const advanced_vector<Type> &right) {
return lexicographical_compare_(left, right);
}
friend bool operator>(const advanced_vector<Type> &left, const advanced_vector<Type> &right) {
return !(left <= right);
}
friend bool operator<=(const advanced_vector<Type> &left, const advanced_vector<Type> &right) {
return !(right < left);
}
friend bool operator>=(const advanced_vector<Type> &left, const advanced_vector<Type> &right) {
return !(left < right);
bool operator==(const advanced_vector &other) const {
if (size_ != other.size_) {
return false;
}
for (size_t i = 0; i < size_; ++i) {
if (data_[i] != other.data_[i]) {
return false;
}
}
return true;
}

friend std::ostream &operator<<(std::ostream &os, const advanced_vector<Type> &other) {
Expand Down Expand Up @@ -342,7 +345,6 @@ class advanced_vector {
}
return ((fr != right.end()) && (fl == left.end()));
}

size_t create_new_data() {
size_t new_capacity = size_;
size_ == 0 ? ++new_capacity : new_capacity = size_ * 2;
Expand All @@ -351,9 +353,9 @@ class advanced_vector {

void copy_or_move(const raw_memory<Type>& new_data, size_t from, size_t quantity, size_t dest_from) {
if constexpr (std::is_nothrow_move_constructible_v<Type> || !std::is_copy_constructible_v<Type>) {
std::uninitialized_move_n(data_.GetAddress() + from, quantity, new_data.GetAddress() + dest_from);
std::uninitialized_move_n(data_.get_address() + from, quantity, new_data.get_address() + dest_from);
} else {
std::uninitialized_copy_n(data_.GetAddress() + from, quantity, new_data.GetAddress() + dest_from);
std::uninitialized_copy_n(data_.get_address() + from, quantity, new_data.get_address() + dest_from);
}
}

Expand All @@ -362,6 +364,10 @@ class advanced_vector {
replace_memory(new_data);
}

void swapping(advanced_vector<Type> &other) {
std::swap(*this, other);
}

void replace_memory(const raw_memory<Type> &new_data) {
// Destroy elements of data_
std::destroy_n(data_.get_address(), size_);
Expand Down
5 changes: 3 additions & 2 deletions advanced_vector_hw/raw_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ class raw_memory {
deallocate_(buffer_);
}

raw_memory(const raw_memory&& other) noexcept : capacity_(std::exchange(other.capacity_, 0)),
buffer_(std::exchange(other.buffer_, nullptr)) {}
raw_memory(const raw_memory &&other) noexcept: capacity_(
std::exchange(const_cast<size_t &>(other.capacity_), 0)),
buffer_(std::exchange(const_cast<rtype *&>(other.buffer_),nullptr)) {}

raw_memory& operator=(raw_memory&& other) noexcept {
if (buffer_ != nullptr) {
Expand Down

0 comments on commit fc8b725

Please sign in to comment.