Skip to content

Instantly share code, notes, and snippets.

@commander-trashdin
Last active August 7, 2021 18:45
Show Gist options
  • Select an option

  • Save commander-trashdin/ab5511f46eb7a817cdb67af3b289d749 to your computer and use it in GitHub Desktop.

Select an option

Save commander-trashdin/ab5511f46eb7a817cdb67af3b289d749 to your computer and use it in GitHub Desktop.
An attempt to make list with raw pointers
#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