Last active
August 7, 2021 18:45
-
-
Save commander-trashdin/ab5511f46eb7a817cdb67af3b289d749 to your computer and use it in GitHub Desktop.
An attempt to make list with raw pointers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <memory> | |
| template <class T> | |
| class List { | |
| struct Node { | |
| public: | |
| Node(T data, Node* next) : data_(data), next_(next) { | |
| } | |
| T& Data() { | |
| return data_; | |
| } | |
| Node* Next() { | |
| return next_; | |
| } | |
| private: | |
| T data_; | |
| Node* next_; | |
| }; | |
| public: | |
| List() : size_(0), first_(nullptr) { | |
| } | |
| List(std::initializer_list<T> list) : size_(0), first_(nullptr) { | |
| for (auto it = std::rbegin(list); it != std::rend(list); ++it) { | |
| auto newnode = new Node(*it, first_); | |
| first_ = newnode; | |
| size_++; | |
| } | |
| } | |
| List(const List& rhs) { | |
| for (auto cur = rhs.first_; cur != nullptr; cur = cur->next_) { | |
| auto newnode = new Node(cur->data_, first_); | |
| first_ = newnode; | |
| size_++; | |
| } | |
| } | |
| List(List&& rhs) | |
| : size_(std::exchange(rhs.size_, 0)), first_(std::exchange(rhs.first_, nullptr)) { | |
| } | |
| ~List() { | |
| Clear(); | |
| } | |
| List& operator=(const List& rhs) { | |
| if (first_ == rhs.first_) { | |
| return *this; | |
| } | |
| Clear(); | |
| for (auto cur = rhs.first_; cur != nullptr; cur = cur->next_) { | |
| auto newnode = new Node(cur->data_, first_); | |
| first_ = newnode; | |
| size_++; | |
| } | |
| return *this; | |
| } | |
| List& operator=(List&& rhs) { | |
| Clear(); | |
| std::swap(size_, rhs.size_); | |
| std::swap(first_, rhs.first_); | |
| return *this; | |
| } | |
| T& operator[](size_t index) { | |
| auto node = first_; | |
| while (node != nullptr && index != 0) { | |
| node = node->Next(); | |
| index--; | |
| } | |
| if (node == nullptr) { | |
| throw std::runtime_error("Index too large"); | |
| } | |
| return node->Data(); | |
| } | |
| void Push(T newdata) { | |
| auto newnode = new Node(newdata, first_); | |
| first_ = newnode; | |
| size_++; | |
| } | |
| T Pop() { | |
| if (size_ == 0) { | |
| throw std::runtime_error("Cannot pop from an empty list"); | |
| } | |
| T data = std::move(first_->Data()); | |
| auto store = first_; | |
| first_ = first_->Next(); | |
| delete store; | |
| size_--; | |
| return data; | |
| } | |
| size_t Size() { | |
| return size_; | |
| } | |
| bool Empty() { | |
| return size_ == 0; | |
| } | |
| void Clear() { | |
| size_ = 0; | |
| for (auto cur = first_; cur != nullptr;) { | |
| auto store = cur->Next(); | |
| delete cur; | |
| cur = store; | |
| } | |
| } | |
| class iterator { | |
| public: | |
| iterator() { | |
| } | |
| iterator(Node* cur) : cur_(cur) { | |
| } | |
| iterator operator++() { | |
| cur_ = cur_->Next(); | |
| return *this; | |
| } | |
| bool operator!=(iterator rhs) { | |
| return cur_ != rhs.cur_; | |
| } | |
| T& operator*() { | |
| return cur_->Data(); | |
| } | |
| T* operator->() { | |
| return &(cur_->data_); | |
| } | |
| private: | |
| Node* cur_; | |
| }; | |
| iterator begin() { | |
| return iterator(first_); | |
| } | |
| iterator end() { | |
| return nullptr; | |
| } | |
| private: | |
| size_t size_; | |
| Node* first_; | |
| }; | |
| int main() { | |
| auto list = List<int>{5}; | |
| list.Push(6); | |
| list.Push(7); | |
| list.Push(8); | |
| list.Push(9); | |
| for (auto obj : list) { | |
| std::cout << obj << " "; | |
| } | |
| // std::cout << list.Pop() << " "; | |
| // std::cout << list.Pop() << " "; | |
| // std::cout << list.Pop() << " "; | |
| // std::cout << list.Pop() << " "; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment