#pragma once
#include <concepts>
namespace zstd {
	template<typename T>
	class parray {
	protected:
		uint32_t m_size;
		uint32_t m_head{0};
		uint32_t m_tsize;
		char* m_buf;
	public:
		~parray() {
			if (m_buf) {
				free(m_buf);
			}
		}
		parray(uint32_t size = 1, uint32_t tsize = sizeof(T)) : m_buf((char*)malloc(tsize * size)), m_size(size) , m_tsize(tsize){}
		parray(parray& other) noexcept{
			m_size = other.m_size;
			m_head = other.m_head;
			m_tsize = other.m_tsize;
			m_buf = other.m_buf;
			other.m_buf = nullptr;
		}
		uint32_t size() {
			return m_head;
		}
		uint32_t data_size() {
			return m_tsize * m_head;
		}
		void* data() {
			return m_buf;
		}
		template<typename S>
		requires std::is_base_of<T, S>::value
		void push_back(S& s) {
			if (m_head >= m_size) {
				return;
			}
			*(S*)(m_buf + m_head * m_tsize) = s;
			m_head++;
		};
		T* at(int i) {
			if (i >= m_head) {
				return nullptr;
			}
			return (T*)(m_buf + i * m_tsize);
		};
	};
}