sortiva/include/collections.hpp

138 lines
2.4 KiB
C++
Raw Normal View History

#pragma once
#include <stdexcept>
template<typename T>
class tree
{
size_t m_CountBranches = 0;
tree<T>* branches = nullptr;
public:
T value;
tree() = default;
~tree()
{
delete[] branches;
m_CountBranches = 0;
}
bool operator==(const tree& rhs) const
{
return branches == rhs.branches;
}
template<typename ...Args>
explicit tree(Args&&... args) : value(std::forward<Args>(args)...) {}
tree<T>& get(size_t idx)
{
if (m_CountBranches <= idx || !branches) throw std::out_of_range("Index is out of range!");
return branches[idx];
}
void set(size_t idx, const tree<T>* t)
{
if (m_CountBranches >= idx || !t || !branches) throw std::out_of_range("Index is out of range!");
branches[idx] = *t;
}
void add(const tree<T>* t)
{
tree<T>* tmp = new tree<T>[m_CountBranches + 1];
if (branches) {
memcpy(tmp, branches, sizeof(tree<T>) * m_CountBranches);
delete[] branches;
}
branches = tmp;
tmp[m_CountBranches++] = *t;
}
void set(size_t idx, const T& val)
{
if (m_CountBranches >= idx || !branches) throw std::out_of_range("Index is out of range!");
branches[idx].value = value;
}
template<typename ...Args>
void add(Args&& ...args)
{
tree<T>* tmp = new tree<T>[m_CountBranches + 1];
if (branches) {
memcpy(tmp, branches, sizeof(tree<T>) * m_CountBranches);
delete[] branches;
}
branches = tmp;
tmp[m_CountBranches++] = tree(std::forward<Args>(args)...);
}
size_t depth()
{
if (branches) return 1;
size_t res = 0;
for (int i = 0; i < m_CountBranches; ++i)
{
res = max(res, branches[i].depth());
}
return res + 1;
}
size_t width() const
{
return m_CountBranches;
}
tree<T>& operator[](size_t idx)
{
return get(idx);
}
};
template<typename T>
struct linked_list
{
linked_list<T>* next = nullptr;
linked_list<T>* first = nullptr;
T value;
linked_list() = default;
linked_list(T val) : value(val) {}
~linked_list()
{
delete next;
}
bool operator==(const linked_list& rhs) const
{
return
this->first == rhs.first &&
this->next == rhs.next &&
this->value == rhs.value;
}
linked_list& put(const T& val)
{
if (!next)
{
next = new linked_list<T>(val);
if (first)
next->first = first;
else
next->first = this;
return *next;
}
if (first)
next->first = first;
else
next->first = this;
return next->put(val);
}
size_t depth()
{
if (!next) return 1;
return next->depth() + 1;
}
};