From 287c7ab01287bbba339fb82172b24a7677ea4730 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Fri, 5 Feb 2021 23:18:16 +0300 Subject: [PATCH 1/4] added linear allocator and list realization --- module-1/homework/Allocator/CMakeLists.txt | 2 + .../Allocator/src/allocator/allocator.h | 134 ++++- module-1/homework/Allocator/src/list/list.h | 546 +++++++++++++++++- module-1/homework/Allocator/tests.cpp | 39 +- 4 files changed, 659 insertions(+), 62 deletions(-) diff --git a/module-1/homework/Allocator/CMakeLists.txt b/module-1/homework/Allocator/CMakeLists.txt index 34c00966..182a2d5d 100644 --- a/module-1/homework/Allocator/CMakeLists.txt +++ b/module-1/homework/Allocator/CMakeLists.txt @@ -4,6 +4,8 @@ include(GoogleTest) project("runner") +set(CMAKE_CXX_STANDARD 14) + configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . diff --git a/module-1/homework/Allocator/src/allocator/allocator.h b/module-1/homework/Allocator/src/allocator/allocator.h index 827256c5..5fe3c73b 100644 --- a/module-1/homework/Allocator/src/allocator/allocator.h +++ b/module-1/homework/Allocator/src/allocator/allocator.h @@ -1,41 +1,119 @@ #include #include +#include template class CustomAllocator { - public: - - using value_type = T; - // Your code goes here - - CustomAllocator(); - CustomAllocator(const CustomAllocator& other) noexcept; - ~CustomAllocator(); - - template - CustomAllocator(const CustomAllocator& other) noexcept; - - T* allocate(std::size_t n); - void deallocate(T* p, std::size_t n); - template - void construct(pointer p, Args&&... args); - void destroy(pointer p); - - template - friend bool operator==(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept; - template - friend bool operator!=(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept; - - private: - // Your code goes here +public: + + template + struct rebind { + using other = CustomAllocator; + }; + + using value_type = T; + using reference = T&; + using const_reference = const T&; + using pointer = T*; + using const_pointer = const T*; + using size_type = std::size_t; + using pointer_difference = std::ptrdiff_t; + using propagate_on_container_copy_assignment = std::false_type; + using propagate_on_container_move_assignment = std::false_type; + using propogate_on_container_swap = std::false_type; + using is_always_equal = std::false_type; + + + CustomAllocator(); + CustomAllocator(const CustomAllocator& other) noexcept; + ~CustomAllocator(); + + template + explicit CustomAllocator(const CustomAllocator& other) noexcept; + + T* allocate(std::size_t n); + void deallocate(T* p, std::size_t n); + template + void construct(pointer p, Args&&... args); + void destroy(pointer p); + + template + friend bool operator==(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept; + template + friend bool operator!=(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept; + +private: + void* arena_; + int* arena_offset; + int* curr_arena_ref_count; }; template bool operator==(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept { - // Your code goes here + return lhs.arena_ == rhs.arena_; } template bool operator!=(const CustomAllocator& lhs, const CustomAllocator& rhs) noexcept { - // Your code goes here -} \ No newline at end of file + return !(lhs == rhs); +} + +template +CustomAllocator::CustomAllocator() { + arena_ = ::operator new(40000 * sizeof(T)); + arena_offset = new int(0); + curr_arena_ref_count = new int(1); +} + +template +CustomAllocator::CustomAllocator(const CustomAllocator& other) noexcept : + arena_(other.arena_), + curr_arena_ref_count(other.curr_arena_ref_count), + arena_offset(other.arena_offset) +{ + (*curr_arena_ref_count)++; +} + +template +template +CustomAllocator::CustomAllocator(const CustomAllocator& other) noexcept : + arena_(other.arena_), + curr_arena_ref_count(other.curr_arena_ref_count), + arena_offset(other.arena_offset) +{ + (*curr_arena_ref_count)++; +} + +template +CustomAllocator::~CustomAllocator() { + (*curr_arena_ref_count)--; + if (*curr_arena_ref_count == 0) { + ::operator delete(arena_); + delete curr_arena_ref_count; + delete arena_offset; + } +} + +template +T* CustomAllocator::allocate(std::size_t n) { + int offset = *arena_offset; + + *arena_offset += n; + return static_cast(arena_) + offset; +} + +template +void CustomAllocator::deallocate(T* p, std::size_t n) {} + +template +template +void CustomAllocator::construct(CustomAllocator::pointer p, Args&& ... args) { + ::new((void*)p) T(std::forward(args)...); +} + +template +void CustomAllocator::destroy(CustomAllocator::pointer p) { + p->~T(); +} + + diff --git a/module-1/homework/Allocator/src/list/list.h b/module-1/homework/Allocator/src/list/list.h index a0affdef..8f3c11e1 100644 --- a/module-1/homework/Allocator/src/list/list.h +++ b/module-1/homework/Allocator/src/list/list.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -8,21 +7,31 @@ namespace task { template> class list { - public: - + class iterator; +public: + using value_type = T; + using allocator_type = Allocator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using iterator = iterator; + using const_iterator = const iterator; + // Your code goes here // Special member functions list(); - list(const list& other) { - // Your code goes here - } + list(const list& other); + list(const list& other, const Allocator& alloc); - - list(list&& other) : lst(std::move(other.lst)); + + list(list&& other) noexcept; list(list&& other, const Allocator& alloc); ~list(); @@ -38,16 +47,16 @@ class list { const_reference back() const; // Iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; + iterator begin() noexcept { return iterator(NIL->getNext()); } + const_iterator begin() const noexcept { return iterator(NIL->getNext()); } - iterator end() noexcept; - const_iterator end() const noexcept; + iterator end() noexcept { return iterator(NIL); } + const_iterator end() const noexcept { return iterator(NIL); } // Capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + bool empty() const noexcept { return size_ == 0; } + size_type size() const noexcept { return size_; } +// size_type max_size() const noexcept; // Modifiers void clear(); @@ -71,10 +80,511 @@ class list { void unique(); void sort(); - allocator_type get_allocator() const noexcept; + allocator_type get_allocator() const noexcept { + return allocator_type(alloc); + } private: - // Your code goes here + class Node { + public: + + Node(): value(), next(nullptr), prev(nullptr) {} + + explicit Node(value_type value, Node* next = nullptr, Node* prev = nullptr) { + this->value = value; + this->next = next; + this->prev = prev; + } + + value_type getValue() const { return value; } + + reference getValueRef() { return value; } + + const_reference getValueRef() const { return value;} + + const Node* getPrev() const { return prev; } + + Node* getPrev() { return prev; } + + const Node* getNext() const { return next; } + + Node* getNext() { return next; } + + void setNext(Node* newNext) { this->next = newNext; } + + void setPrev(Node* newPrev) { this->prev = newPrev; } + + ~Node() { + this->next = nullptr; + this->prev = nullptr; + } + + private: + value_type value; + Node* prev; + Node* next; + }; +public: + class iterator { + friend class std::iterator_traits; + public: + typedef T value_type; + typedef iterator self_type; + typedef std::bidirectional_iterator_tag iterator_category; + typedef T* pointer; + typedef T& reference; + typedef std::ptrdiff_t difference_type; + + explicit iterator(Node* ptr): ptr(ptr) {} + + iterator& operator++() { + ptr = ptr->getNext(); + return *this; + } + + iterator operator++(int) { + iterator copy(*this); + operator++(); + return copy; + } + + iterator& operator--() { + ptr = ptr->getPrev(); + return *this; + } + + iterator operator--(int) { + iterator copy(*this); + operator--(); + return copy; + } + + bool operator==(const iterator& rhs) { return ptr == rhs.ptr; } + bool operator!=(const iterator& rhs) { return ptr != rhs.ptr; } + + reference operator*() { return ptr->getValueRef(); } + T* operator->() { return &ptr->getValueRef(); } + private: + Node* ptr = nullptr; + }; + +private: + typedef typename std::allocator_traits::template rebind_alloc node_allocator; + typedef typename std::allocator_traits node_alloc_traits; + + + node_allocator alloc; + + Node* NIL; + + size_t size_ = 0; + + static list merge(const list& left, const list& right);//begin2 == end1 + static std::pair bisect(const list& source); + static list sorted(const list& source); + + void copyValues(iterator beg, iterator end); }; -} \ No newline at end of file +} + +template +task::list::list(): NIL(alloc.allocate(1)) { + size_ = 0; + alloc.construct(NIL); + NIL->setNext(NIL); + NIL->setPrev(NIL); +} + +template +task::list::list(const task::list& other): + alloc(node_alloc_traits::select_on_container_copy_construction(other.alloc)), + NIL(alloc.allocate(1)) +{ + size_ = 0; + alloc.construct(NIL); + NIL->setNext(NIL); + NIL->setPrev(NIL); + + this->copyValues(other.begin(), other.end()); +} + +template +task::list::list(const task::list& other, const Allocator& alloc): alloc(alloc), NIL(alloc.allocate(1)) { + alloc.construct(NIL); + NIL->setPrev(NIL); + NIL->setNext(NIL); + size_ = 0; + + this->copyValues(other.begin(), other.end()); +} + +template +task::list::~list() { + if (NIL == nullptr) { + return; + } + Node* curr = NIL->getNext(); + while (curr && curr->getNext() != NIL) { + Node* to_delete = curr; + curr = curr->getNext(); + alloc.destroy(to_delete); + alloc.deallocate(to_delete, 1); + } + alloc.destroy(NIL); + alloc.deallocate(NIL, 1); +} + +template +task::list& task::list::operator=(const task::list& other) { + if (this != &other) { + if (node_alloc_traits::propagate_on_container_copy_assignment::value) { + if (alloc != other.alloc) { + clear(); + } + alloc = other.alloc; + + } + clear(); + Node* other_head = other.NIL->getNext(); + for (int i = 0; i < other.size(); ++i) { + this->push_back(other_head->getValue()); + other_head = other_head->getNext(); + } + size_ = other.size(); + } + return *this; +} + +template +void task::list::copyValues(iterator beg, iterator end) { + for (auto it = beg; it != end; it++) { + push_back(*it); + } +} + +template +void task::list::clear() { + while (size()) { + pop_back(); + } +} + +template +void task::list::push_back(const T& value) { + Node* curr_last = NIL->getPrev(); + Node* begin = NIL; + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, value); + + new_node->setNext(begin); + new_node->setPrev(curr_last); + begin->setPrev(new_node); + curr_last->setNext(new_node); + ++size_; +} + +template +void task::list::pop_back() { + Node* last = NIL->getPrev(); + if (last == NIL) { + throw std::runtime_error("Pop back in empty list"); + } + + Node* prevLast = last->getPrev(); + prevLast->setNext(NIL); + NIL->setPrev(prevLast); + alloc.destroy(last); + alloc.deallocate(last, 1); + --size_; +} + +template +void task::list::push_front(const T& value) { + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, value); + Node* curr_front = NIL->getNext(); + NIL->setNext(new_node); + new_node->setPrev(NIL); + + new_node->setNext(curr_front); + curr_front->setPrev(new_node); + size_++; +} + +template +void task::list::pop_front() { + if (NIL->getNext() == NIL) { + //throw std::runtime_error("Pop front in empty list"); + return; + } + Node* curr_front = NIL->getNext(); + Node* second = curr_front->getNext(); + NIL->setNext(second); + second->setPrev(NIL); + alloc.destroy(curr_front); + alloc.deallocate(curr_front, 1); + size_--; +} + +template +void task::list::resize(size_t count) { + while (size_ > count) { + pop_back(); + } + while (size_ < count) { + push_back({}); + } + size_ = count; +} + +template +void task::list::remove(const T& value) { + Node* curr = NIL->getNext(); + std::vector to_delete; + while (curr != NIL) { + if (curr->getValue() == value) { + to_delete.push_back(curr); + Node* prev = curr->getPrev(); + prev->setNext(curr->getNext()); + curr->getNext()->setPrev(prev); + curr = curr->getNext(); + size_--; + } else { + curr = curr->getNext(); + } + } + for (auto& el : to_delete) { + alloc.destroy(el); + alloc.deallocate(el, 1); + } +} + +template +void task::list::unique() { + Node* curr = NIL->getNext()->getNext(); + + while (curr->getPrev() != NIL) { + Node* prev = curr->getPrev(); + if (prev != NIL && prev->getValue() == curr->getValue()) { + Node* next = curr->getNext(); + prev->setNext(next); + next->setPrev(prev); + size_--; + Node* to_delete = curr; + curr = curr->getNext(); + + alloc.destroy(to_delete); + alloc.deallocate(to_delete, 1); + } else { + curr = curr->getNext(); + } + } +} + +template +void task::list::push_back(T&& value) { + Node* curr_last = NIL->getPrev(); + Node* begin = NIL; + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, std::forward(value)); + + new_node->setNext(begin); + new_node->setPrev(curr_last); + begin->setPrev(new_node); + curr_last->setNext(new_node); + ++size_; +} + +template +template +void task::list::emplace_back(Args&& ... args) { + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, std::forward(args)...); + Node* curr_front = NIL->getNext(); + NIL->setNext(new_node); + new_node->setPrev(NIL); + + new_node->setNext(curr_front); + curr_front->setPrev(new_node); + size_++; +} + +template +void task::list::push_front(T&& value) { + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, std::forward(value)); + Node* curr_front = NIL->getNext(); + NIL->setNext(new_node); + new_node->setPrev(NIL); + + new_node->setNext(curr_front); + curr_front->setPrev(new_node); + size_++; +} + +template +template +void task::list::emplace_front(Args&& ... args) { + Node* new_node = static_cast(alloc.allocate(1)); + alloc.construct(new_node, std::forward(args)...); + Node* curr_front = NIL->getNext(); + NIL->setNext(new_node); + new_node->setPrev(NIL); + + new_node->setNext(curr_front); + curr_front->setPrev(new_node); + size_++; +} + +template +task::list task::list::merge(const task::list& left, const task::list& right) { + task::list result; + + const Node* curr_left = left.NIL->getNext(); + const Node* curr_right = right.NIL->getNext(); + + while (curr_left != left.NIL && curr_right != right.NIL) { + if (curr_left->getValue() < curr_right->getValue()) { + result.push_back(curr_left->getValue()); + curr_left = curr_left->getNext(); + } else { + result.push_back(curr_right->getValue()); + curr_right = curr_right->getNext(); + } + } + + while (curr_left != left.NIL) { + result.push_back(curr_left->getValue()); + curr_left = curr_left->getNext(); + } + + while (curr_right != right.NIL) { + result.push_back(curr_right->getValue()); + curr_right = curr_right->getNext(); + } + + return result; +} + +template +std::pair*, task::list*> task::list::bisect(const task::list& source) { + int size = source.size(); + auto* left = new task::list(); + auto* right = new task::list(); + + Node* curr = source.NIL->getNext(); + + for (int i = 0; i < size / 2; ++i, curr = curr->getNext()) { + left->push_back(curr->getValue()); + } + + for (int i = size / 2; i < size; ++i, curr = curr->getNext()) { + right->push_back(curr->getValue()); + } + + return {left, right}; +} + +template +task::list task::list::sorted(const task::list& source) { + if (source.size() > 1) { + auto res = task::list::bisect(source); + return task::list::merge(task::list::sorted(*res.first), task::list::sorted(*res.second)); + } + return source; +} + +template +task::list::list(task::list&& other, const Allocator& alloc) : + alloc(alloc), + NIL(other.NIL) +{ + other.NIL = nullptr; +} + +template +task::list::list(task::list&& other) noexcept : + alloc(std::move(other.alloc)), + NIL(other.NIL) +{ + other.NIL = nullptr; +} + +template +task::list& task::list::operator=(task::list&& other) noexcept { + clear(); + if (node_alloc_traits::propagate_on_container_move_assignment::value) { + alloc = std::move(other.alloc); + NIL = other.NIL; + other.NIL = nullptr; + } else if (node_alloc_traits::is_always_equal::value || alloc == other.alloc) { + NIL = other.NIL; + other.NIL = nullptr; + } else { + for (auto it = other.begin(); it != other.end(); ++it) { + push_back(std::move(*it)); + } + } + + return *this; +} + +template +typename task::list::reference task::list::front() { + if (!size()) { + throw std::runtime_error("get front in empty list"); + } + + return NIL->getNext()->getValueRef(); +} + +template +typename task::list::const_reference task::list::front() const { + if (!size()) { + throw std::runtime_error("get front in empty list"); + } + + return NIL->getNext()->getValueRef(); +} + +template +typename task::list::reference task::list::back() { + if (!size()) { + throw std::runtime_error("get back in empty list"); + } + + return NIL->getPrev()->getValueRef(); +} + +template +typename task::list::const_reference task::list::back() const { + if (!size()) { + throw std::runtime_error("get back in empty list"); + } + + return NIL->getPrev()->getValueRef(); +} + +template +void task::list::sort() { + *this = sorted(*this); +} + +template +void task::list::swap(task::list& other) noexcept { + if (!node_alloc_traits::propagate_on_container_swap::value && alloc != other.alloc) { + throw std::runtime_error("Pop back in empty list"); + } + if (node_alloc_traits::propagate_on_container_swap::value) { + std::swap(alloc, other.alloc); + } + std::swap(NIL, other.NIL); +} + + + + + + + diff --git a/module-1/homework/Allocator/tests.cpp b/module-1/homework/Allocator/tests.cpp index 4d88d43a..ba43eae3 100644 --- a/module-1/homework/Allocator/tests.cpp +++ b/module-1/homework/Allocator/tests.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -7,6 +8,7 @@ #include "src/list/list.h" #include "gtest/gtest.h" +//#define CustomAllocator std::allocator TEST(CopyAssignment, Test) { task::list> actual; @@ -30,7 +32,7 @@ TEST(MoveAssignment, Test1) { l2 = std::move(l1); l3.push_back("hello"); l4 = std::move(l3); - + ASSERT_TRUE(std::equal(l1.begin(), l1.end(), l3.begin(), l3.end())); ASSERT_TRUE(std::equal(l2.begin(), l2.end(), l4.begin(), l4.end())); } @@ -38,7 +40,7 @@ TEST(MoveAssignment, Test1) { TEST(Front, Test1) { task::list> actual; std::list> expected; - + actual.push_back("hello"); expected.push_back("hello"); @@ -56,7 +58,7 @@ TEST(Front, Test1) { TEST(Clear, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.push_back("hello"); expected.push_back("hello"); @@ -69,16 +71,15 @@ TEST(Clear, Test1) { TEST(Swap, Test1) { task::list> actual; + task::list> actual2(actual); std::list> expected; - + std::list> expected2(expected); + for (std::size_t i = 0; i < 10; i++) { actual.push_back("hello"); expected.push_back("hello"); } - task::list> actual2; - std::list> expected2; - for (std::size_t i = 0; i < 10; i++) { actual2.push_back("world"); expected2.push_back("world"); @@ -94,18 +95,19 @@ TEST(PushBack, Test) { std::vector expected_v(10, "hello"); task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.push_back(std::move(actual_v[i])); expected.push_back(std::move(expected_v[i])); } + ASSERT_TRUE(std::equal(actual.begin(), actual.end(), expected.begin(), expected.end())); } TEST(EmplaceBack, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.emplace_back("hello"); expected.emplace_back("hello"); @@ -116,7 +118,7 @@ TEST(EmplaceBack, Test1) { TEST(PopBack, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.emplace_back("hello"); expected.emplace_back("hello"); @@ -134,7 +136,7 @@ TEST(PushFront, Test1) { std::vector expected_v(10, "hello"); task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.push_front(actual_v[i]); expected.push_front(expected_v[i]); @@ -147,18 +149,18 @@ TEST(PushFront, Test2) { std::vector expected_v(10, "hello"); task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.push_front(std::move(actual_v[i])); expected.push_front(std::move(expected_v[i])); } ASSERT_TRUE(std::equal(actual.begin(), actual.end(), expected.begin(), expected.end())); -} +} TEST(EmplaceFront, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.emplace_front("hello"); expected.emplace_front("hello"); @@ -169,7 +171,7 @@ TEST(EmplaceFront, Test1) { TEST(PopFront, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 10; i++) { actual.emplace_back("hello"); expected.emplace_back("hello"); @@ -209,6 +211,11 @@ TEST(Unique, Test1) { std::list> expected; expected.push_back("hello"); expected.push_back("world"); + + for (auto it = actual.begin(); it != actual.end(); ++it) { + std::cout << *it << ' '; + } + ASSERT_TRUE(std::equal(actual.begin(), actual.end(), expected.begin(), expected.end())); } @@ -232,7 +239,7 @@ TEST(Sort, Test1) { TEST(Mixed, Test1) { task::list> actual; std::list> expected; - + for (std::size_t i = 0; i < 5; i++) { actual.push_back("hello"); expected.push_back("hello"); From 9ef5ce55d3e82b38e78deca43ae71e48749adc22 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Sat, 6 Feb 2021 11:36:19 +0300 Subject: [PATCH 2/4] std::move in sorting instead of copying --- module-1/homework/Allocator/src/list/list.h | 27 ++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/module-1/homework/Allocator/src/list/list.h b/module-1/homework/Allocator/src/list/list.h index 8f3c11e1..0e5e4e7c 100644 --- a/module-1/homework/Allocator/src/list/list.h +++ b/module-1/homework/Allocator/src/list/list.h @@ -144,7 +144,7 @@ class list { iterator operator++(int) { iterator copy(*this); - operator++(); + (*this)++; return copy; } @@ -155,7 +155,7 @@ class list { iterator operator--(int) { iterator copy(*this); - operator--(); + (*this)--; return copy; } @@ -315,8 +315,7 @@ void task::list::push_front(const T& value) { template void task::list::pop_front() { if (NIL->getNext() == NIL) { - //throw std::runtime_error("Pop front in empty list"); - return; + throw std::runtime_error("Pop front in empty list"); } Node* curr_front = NIL->getNext(); Node* second = curr_front->getNext(); @@ -343,7 +342,7 @@ void task::list::remove(const T& value) { Node* curr = NIL->getNext(); std::vector to_delete; while (curr != NIL) { - if (curr->getValue() == value) { + if (curr->getValueRef() == value) { to_delete.push_back(curr); Node* prev = curr->getPrev(); prev->setNext(curr->getNext()); @@ -366,7 +365,7 @@ void task::list::unique() { while (curr->getPrev() != NIL) { Node* prev = curr->getPrev(); - if (prev != NIL && prev->getValue() == curr->getValue()) { + if (prev != NIL && prev->getValueRef() == curr->getValueRef()) { Node* next = curr->getNext(); prev->setNext(next); next->setPrev(prev); @@ -445,22 +444,22 @@ task::list task::list::merge(const task::listgetNext(); while (curr_left != left.NIL && curr_right != right.NIL) { - if (curr_left->getValue() < curr_right->getValue()) { - result.push_back(curr_left->getValue()); + if (curr_left->getValueRef() < curr_right->getValueRef()) { + result.push_back(std::move(curr_left->getValueRef())); curr_left = curr_left->getNext(); } else { - result.push_back(curr_right->getValue()); + result.push_back(std::move(curr_right->getValueRef())); curr_right = curr_right->getNext(); } } while (curr_left != left.NIL) { - result.push_back(curr_left->getValue()); + result.push_back(std::move(curr_left->getValueRef())); curr_left = curr_left->getNext(); } while (curr_right != right.NIL) { - result.push_back(curr_right->getValue()); + result.push_back(std::move(curr_right->getValueRef())); curr_right = curr_right->getNext(); } @@ -476,11 +475,11 @@ std::pair*, task::list*> task::listgetNext(); for (int i = 0; i < size / 2; ++i, curr = curr->getNext()) { - left->push_back(curr->getValue()); + left->push_back(std::move(curr->getValueRef())); } for (int i = size / 2; i < size; ++i, curr = curr->getNext()) { - right->push_back(curr->getValue()); + right->push_back(std::move(curr->getValueRef())); } return {left, right}; @@ -574,7 +573,7 @@ void task::list::sort() { template void task::list::swap(task::list& other) noexcept { if (!node_alloc_traits::propagate_on_container_swap::value && alloc != other.alloc) { - throw std::runtime_error("Pop back in empty list"); + throw std::runtime_error("Swap with different allocators"); } if (node_alloc_traits::propagate_on_container_swap::value) { std::swap(alloc, other.alloc); From e72197b8c8b49b3f88e25c3e975c9525a0e6db33 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Sat, 6 Feb 2021 11:38:34 +0300 Subject: [PATCH 3/4] fixed --- module-1/homework/Allocator/src/list/list.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module-1/homework/Allocator/src/list/list.h b/module-1/homework/Allocator/src/list/list.h index 0e5e4e7c..d7e102c4 100644 --- a/module-1/homework/Allocator/src/list/list.h +++ b/module-1/homework/Allocator/src/list/list.h @@ -144,7 +144,7 @@ class list { iterator operator++(int) { iterator copy(*this); - (*this)++; + ++(*this); return copy; } @@ -155,7 +155,7 @@ class list { iterator operator--(int) { iterator copy(*this); - (*this)--; + --(*this); return copy; } From dc2a0720018bfc93f9d437a254177d15706f96e4 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Mon, 8 Feb 2021 11:50:54 +0300 Subject: [PATCH 4/4] renaming --- .../Allocator/src/allocator/allocator.h | 32 ++++---- module-1/homework/Allocator/src/list/list.h | 80 +++++++++---------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/module-1/homework/Allocator/src/allocator/allocator.h b/module-1/homework/Allocator/src/allocator/allocator.h index 5fe3c73b..13037d47 100644 --- a/module-1/homework/Allocator/src/allocator/allocator.h +++ b/module-1/homework/Allocator/src/allocator/allocator.h @@ -44,8 +44,8 @@ class CustomAllocator { private: void* arena_; - int* arena_offset; - int* curr_arena_ref_count; + int* arena_offset_; + int* curr_arena_ref_count_; }; template @@ -61,44 +61,44 @@ bool operator!=(const CustomAllocator& lhs, const CustomAllocator& rhs) no template CustomAllocator::CustomAllocator() { arena_ = ::operator new(40000 * sizeof(T)); - arena_offset = new int(0); - curr_arena_ref_count = new int(1); + arena_offset_ = new int(0); + curr_arena_ref_count_ = new int(1); } template CustomAllocator::CustomAllocator(const CustomAllocator& other) noexcept : arena_(other.arena_), - curr_arena_ref_count(other.curr_arena_ref_count), - arena_offset(other.arena_offset) + curr_arena_ref_count_(other.curr_arena_ref_count_), + arena_offset_(other.arena_offset_) { - (*curr_arena_ref_count)++; + (*curr_arena_ref_count_)++; } template template CustomAllocator::CustomAllocator(const CustomAllocator& other) noexcept : arena_(other.arena_), - curr_arena_ref_count(other.curr_arena_ref_count), - arena_offset(other.arena_offset) + curr_arena_ref_count_(other.curr_arena_ref_count_), + arena_offset_(other.arena_offset_) { - (*curr_arena_ref_count)++; + (*curr_arena_ref_count_)++; } template CustomAllocator::~CustomAllocator() { - (*curr_arena_ref_count)--; - if (*curr_arena_ref_count == 0) { + (*curr_arena_ref_count_)--; + if (*curr_arena_ref_count_ == 0) { ::operator delete(arena_); - delete curr_arena_ref_count; - delete arena_offset; + delete curr_arena_ref_count_; + delete arena_offset_; } } template T* CustomAllocator::allocate(std::size_t n) { - int offset = *arena_offset; + int offset = *arena_offset_; - *arena_offset += n; + *arena_offset_ += n; return static_cast(arena_) + offset; } diff --git a/module-1/homework/Allocator/src/list/list.h b/module-1/homework/Allocator/src/list/list.h index d7e102c4..6c90b2a2 100644 --- a/module-1/homework/Allocator/src/list/list.h +++ b/module-1/homework/Allocator/src/list/list.h @@ -81,7 +81,7 @@ class list { void sort(); allocator_type get_allocator() const noexcept { - return allocator_type(alloc); + return allocator_type(alloc_); } private: @@ -173,7 +173,7 @@ class list { typedef typename std::allocator_traits node_alloc_traits; - node_allocator alloc; + node_allocator alloc_; Node* NIL; @@ -189,20 +189,20 @@ class list { } template -task::list::list(): NIL(alloc.allocate(1)) { +task::list::list(): NIL(alloc_.allocate(1)) { size_ = 0; - alloc.construct(NIL); + alloc_.construct(NIL); NIL->setNext(NIL); NIL->setPrev(NIL); } template task::list::list(const task::list& other): - alloc(node_alloc_traits::select_on_container_copy_construction(other.alloc)), - NIL(alloc.allocate(1)) + alloc_(node_alloc_traits::select_on_container_copy_construction(other.alloc_)), + NIL(alloc_.allocate(1)) { size_ = 0; - alloc.construct(NIL); + alloc_.construct(NIL); NIL->setNext(NIL); NIL->setPrev(NIL); @@ -210,7 +210,7 @@ task::list::list(const task::list& other): } template -task::list::list(const task::list& other, const Allocator& alloc): alloc(alloc), NIL(alloc.allocate(1)) { +task::list::list(const task::list& other, const Allocator& alloc): alloc_(alloc), NIL(alloc.allocate(1)) { alloc.construct(NIL); NIL->setPrev(NIL); NIL->setNext(NIL); @@ -228,21 +228,21 @@ task::list::~list() { while (curr && curr->getNext() != NIL) { Node* to_delete = curr; curr = curr->getNext(); - alloc.destroy(to_delete); - alloc.deallocate(to_delete, 1); + alloc_.destroy(to_delete); + alloc_.deallocate(to_delete, 1); } - alloc.destroy(NIL); - alloc.deallocate(NIL, 1); + alloc_.destroy(NIL); + alloc_.deallocate(NIL, 1); } template task::list& task::list::operator=(const task::list& other) { if (this != &other) { if (node_alloc_traits::propagate_on_container_copy_assignment::value) { - if (alloc != other.alloc) { + if (alloc_ != other.alloc_) { clear(); } - alloc = other.alloc; + alloc_ = other.alloc_; } clear(); @@ -274,8 +274,8 @@ template void task::list::push_back(const T& value) { Node* curr_last = NIL->getPrev(); Node* begin = NIL; - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, value); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, value); new_node->setNext(begin); new_node->setPrev(curr_last); @@ -294,15 +294,15 @@ void task::list::pop_back() { Node* prevLast = last->getPrev(); prevLast->setNext(NIL); NIL->setPrev(prevLast); - alloc.destroy(last); - alloc.deallocate(last, 1); + alloc_.destroy(last); + alloc_.deallocate(last, 1); --size_; } template void task::list::push_front(const T& value) { - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, value); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, value); Node* curr_front = NIL->getNext(); NIL->setNext(new_node); new_node->setPrev(NIL); @@ -321,8 +321,8 @@ void task::list::pop_front() { Node* second = curr_front->getNext(); NIL->setNext(second); second->setPrev(NIL); - alloc.destroy(curr_front); - alloc.deallocate(curr_front, 1); + alloc_.destroy(curr_front); + alloc_.deallocate(curr_front, 1); size_--; } @@ -354,8 +354,8 @@ void task::list::remove(const T& value) { } } for (auto& el : to_delete) { - alloc.destroy(el); - alloc.deallocate(el, 1); + alloc_.destroy(el); + alloc_.deallocate(el, 1); } } @@ -373,8 +373,8 @@ void task::list::unique() { Node* to_delete = curr; curr = curr->getNext(); - alloc.destroy(to_delete); - alloc.deallocate(to_delete, 1); + alloc_.destroy(to_delete); + alloc_.deallocate(to_delete, 1); } else { curr = curr->getNext(); } @@ -385,8 +385,8 @@ template void task::list::push_back(T&& value) { Node* curr_last = NIL->getPrev(); Node* begin = NIL; - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, std::forward(value)); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, std::forward(value)); new_node->setNext(begin); new_node->setPrev(curr_last); @@ -398,8 +398,8 @@ void task::list::push_back(T&& value) { template template void task::list::emplace_back(Args&& ... args) { - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, std::forward(args)...); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, std::forward(args)...); Node* curr_front = NIL->getNext(); NIL->setNext(new_node); new_node->setPrev(NIL); @@ -411,8 +411,8 @@ void task::list::emplace_back(Args&& ... args) { template void task::list::push_front(T&& value) { - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, std::forward(value)); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, std::forward(value)); Node* curr_front = NIL->getNext(); NIL->setNext(new_node); new_node->setPrev(NIL); @@ -425,8 +425,8 @@ void task::list::push_front(T&& value) { template template void task::list::emplace_front(Args&& ... args) { - Node* new_node = static_cast(alloc.allocate(1)); - alloc.construct(new_node, std::forward(args)...); + Node* new_node = static_cast(alloc_.allocate(1)); + alloc_.construct(new_node, std::forward(args)...); Node* curr_front = NIL->getNext(); NIL->setNext(new_node); new_node->setPrev(NIL); @@ -496,7 +496,7 @@ task::list task::list::sorted(const task::list task::list::list(task::list&& other, const Allocator& alloc) : - alloc(alloc), + alloc_(alloc), NIL(other.NIL) { other.NIL = nullptr; @@ -504,7 +504,7 @@ task::list::list(task::list&& other, const Allocator template task::list::list(task::list&& other) noexcept : - alloc(std::move(other.alloc)), + alloc_(std::move(other.alloc_)), NIL(other.NIL) { other.NIL = nullptr; @@ -514,10 +514,10 @@ template task::list& task::list::operator=(task::list&& other) noexcept { clear(); if (node_alloc_traits::propagate_on_container_move_assignment::value) { - alloc = std::move(other.alloc); + alloc_ = std::move(other.alloc_); NIL = other.NIL; other.NIL = nullptr; - } else if (node_alloc_traits::is_always_equal::value || alloc == other.alloc) { + } else if (node_alloc_traits::is_always_equal::value || alloc_ == other.alloc_) { NIL = other.NIL; other.NIL = nullptr; } else { @@ -572,11 +572,11 @@ void task::list::sort() { template void task::list::swap(task::list& other) noexcept { - if (!node_alloc_traits::propagate_on_container_swap::value && alloc != other.alloc) { + if (!node_alloc_traits::propagate_on_container_swap::value && alloc_ != other.alloc_) { throw std::runtime_error("Swap with different allocators"); } if (node_alloc_traits::propagate_on_container_swap::value) { - std::swap(alloc, other.alloc); + std::swap(alloc_, other.alloc_); } std::swap(NIL, other.NIL); }