#ifndef LIST_H #define LIST_H #include #include "utils/StringBuffer.h" template class List final { char data[sizeof (T) * N]; int length = 0; void copy(const List& other) { for(int i = 0; i < other.length; i++) { add(other[i]); } } void move(List&& other) { for(int i = 0; i < other.length; i++) { add(std::move(other[i])); } } public: List() = default; void clear() { for(int i = 0; i < length; i++) { (*this)[i].~T(); } length = 0; } ~List() { clear(); } List(const List& other) : length(0) { copy(other); } List& operator=(const List& other) { if(&other != this) { clear(); copy(other); } return *this; } List(List&& other) : length(0) { move(std::move(other)); other.clear(); } List& operator=(List&& other) { if(&other != this) { clear(); move(std::move(other)); other.clear(); } return *this; } T* begin() { return reinterpret_cast (data); } T* end() { return reinterpret_cast (data) + length; } const T* begin() const { return reinterpret_cast (data); } const T* end() const { return reinterpret_cast (data) + length; } bool add(const T& t) { if(length >= N) { return true; } new (end()) T(t); length++; return false; } bool add(T&& t) { if(length >= N) { return true; } new (end()) T(std::move(t)); length++; return false; } template bool add(Args&&... args) { if(length >= N) { return true; } new (end()) T(std::forward(args)...); length++; return false; } T& operator[](int index) { return begin()[index]; } const T& operator[](int index) const { return begin()[index]; } int getLength() const { return length; } template void toString(StringBuffer& s) const { s.append("["); for(int i = 0; i < length - 1; i++) { s.append((*this)[i]); s.append(", "); } if(length > 0) { s.append((*this)[length - 1]); } s.append("]"); } bool remove(int index) { if(index < 0 || index >= length) { return true; } else if(index + 1 == length) { (*this)[index].~T(); length--; return false; } (*this)[index] = std::move((*this)[length - 1]); (*this)[length - 1].~T(); length--; return false; } }; #endif