data-structures/cpp/singly_ll.cpp
2022-09-17 10:04:05 +05:30

111 lines
2.2 KiB
C++

#include <iostream>
#include <algorithm>
template <class T>
struct singly_ll_node {
T data {};
singly_ll_node* next {};
};
template <class T>
class singly_ll {
public:
using node = singly_ll_node<T>;
using node_ptr = node* ;
private:
node_ptr head {};
public:
void push_front(T val) {
auto new_node = new node{val, nullptr};
if (head != nullptr) new_node -> next = head;
head = new_node;
}
void pop_front() {
auto first { head };
if (head) {
head = head -> next;
delete first;
}
else throw "Empty ";
}
struct singly_ll_iterator {
private:
node_ptr ptr;
public:
singly_ll_iterator(node_ptr p) : ptr(p) {}
T& operator*() {
return ptr -> data;
}
node_ptr get() {
return ptr;
}
singly_ll_iterator& operator++() { // pre-increment
ptr = ptr -> next;
return *this;
}
singly_ll_iterator operator++(T) { // post-increment
singly_ll_iterator result { *this };
++(*this);
return result;
}
friend bool operator==(const singly_ll_iterator& left, const singly_ll_iterator& right) {
return left.ptr == right.ptr;
}
friend bool operator!=(const singly_ll_iterator& left, const singly_ll_iterator& right) {
return left.ptr != right.ptr;
}
};
singly_ll_iterator begin() {
return singly_ll_iterator(head);
}
singly_ll_iterator end() {
return singly_ll_iterator(nullptr);
}
singly_ll_iterator begin() const {
return singly_ll_iterator(head);
}
singly_ll_iterator end() const {
return singly_ll_iterator(nullptr);
}
singly_ll() = default;
singly_ll(const singly_ll& other) : head(nullptr) {
if (other.head) {
head = new node;
auto cur {head};
auto it {other.begin()};
while (true) {
cur -> data = *it;
auto tmp {it};
++tmp;
if (tmp == other.end()) break;
cur -> next = new node;
cur = cur -> next;
it = tmp;
}
}
}
singly_ll(const std::initializer_list<T>& ilist) : head(nullptr) {
for (auto it {std::rbegin(ilist)}; it != std::rend(ilist); ++it) push_front(*it);
}
};