#include <iostream>
// userdata - - -
struct userdata {
int a;
userdata(int i): a(i) {
}
int get() const {
return a;
}
void set(const int val) {
a = val;
}
friend std::ostream& operator<<(std::ostream& os, const userdata& obj) {
os << obj.a << std::endl;
return os;
}
};
// dynarray - - -
template <typename T> class dynarray {
unsigned len;
struct elem {
T *data;
elem *next;
elem(T *init) : data(init) {}
};
elem *first, *last;
inline bool is_empty() const {
return first == nullptr;
}
public:
// default constructor
dynarray(): len(0), first(nullptr), last(nullptr), func(nullptr) {}
// default destructor
~dynarray() {
while (first) {
auto tmp = first;
delete first->data; // нужно ли чистить данные или оставлять их висеть в памяти - я х3 чё надо
first = (first == last) ? nullptr : first->next;
delete tmp;
}
}
// operator [] function
T *operator[](const unsigned Index) const {
if (is_empty() || Index >= len) return nullptr;
T *ret = nullptr;
auto tmp = first;
for (unsigned i = 0; i <= Index; ++i) {
if (i == Index) {
ret = tmp->data;
break;
}
tmp = tmp->next;
}
return ret;
}
// for_each function
typedef void (*for_each_func)(T *);
for_each_func func;
int for_each(unsigned Begin, unsigned End, for_each_func Func) {
int ret = 0;
if (End <= len) {
for (; Begin < End; ++Begin) {
Func(operator[](Begin));
ret++;
}
}
return ret;
}
unsigned Length() const {
return len;
}
// push_back function
void push_back(T *obj) {
elem *ins = new elem(obj);
elem *tmp = last;
if (tmp == nullptr) {
first = ins;
last = ins;
first->next = last;
} else {
last->next = ins;
last = ins;
}
len++;
}
// Delete element function
void Delete(unsigned Index) {
if (Index >= len) return;
elem *prev = nullptr;
elem *curr = first;
for (unsigned i = 0; i <= Index; ++i) {
if (i == Index) {
if (curr == first) first = (len > 1) ? first->next : nullptr;
if (curr == last) last = (len > 1) ? prev : nullptr;
if (prev) prev->next = curr->next;
delete curr->data;
delete curr;
len--;
break;
} else {
prev = curr;
curr = curr->next;
}
}
}
// For dump
friend std::ostream& operator<<(std::ostream& os, const dynarray<T>& obj) {
os << "Current number of items: " << obj.Length() << std::endl << "---------------------------------" << std::endl;
elem *tmp = obj.first;
for (unsigned i = 0; i < obj.Length(); ++i) {
os << " " << *(tmp->data);
tmp = tmp->next;
}
os << "---------------------------------\nDone." << std::endl;
return os;
}
};
using namespace std;
int main() {
// создаем и печатаем пустой список
dynarray < userdata > d;
std::cout << d << std::endl;
// заполняем список 5-ю элементами и печатаем список
for (auto i = 0; i < 5; ++i) d.push_back(new userdata(i));
std::cout << d << std::endl;
// печатаем второй элемент по индексу
std::cout << "Item #2: " << *(d[2]) << std::endl;
// Удаляем нулевой элемент (из 5-ти) и печатаем список
d.Delete(0);
std::cout << d << std::endl;
// Удаляем первый элемент (из 4-х) и печатаем список
d.Delete(1);
std::cout << d << std::endl;
// Удаляем второй элемент (из 3-х) и печатаем список
d.Delete(2);
std::cout << d << std::endl;
// Удаляем первый элемент (из 2-х) и печатаем список
d.Delete(1);
std::cout << d << std::endl;
// Удаляем нулевой элемент (из 1-го) и печатаем список
d.Delete(0);
std::cout << d << std::endl;
// Удаляем нулевой элемент (из пустого списка) и печатаем список
d.Delete(0);
std::cout << d << std::endl;
return 0;
}