#pragma once

#include <vector>
#include <string>
#include <stdexcept>  

class AbstractList
{
public:
	virtual ~AbstractList() = default;

	virtual std::size_t getLength() const = 0;
};

template<typename T>
class List : public AbstractList
{
public:
	List() = default;

	void initializeTo(std::size_t size, T value)
	{
		mData = std::vector<T>(size, value);
	}

	const T* getDataPtr() const
	{
		return mData.data();
	}

	const std::vector<T>& getData() const
	{
		return mData;
	}

	T getItem(std::size_t index) const
	{
		if (index < mData.size())
		{
			return mData[index];
		}
		else
		{
			const auto msg = "Tried to access out of range index: " + std::to_string(index) + " with size " + std::to_string(mData.size());
			throw std::out_of_range(msg);
		}
	}

	void setData(const std::vector<T>& data)
	{
		mData = data;
	}

	void setItem(std::size_t index, T item)
	{
		if (index < mData.size())
		{
			mData[index] = item;
		}
	}

	std::size_t getLength() const override
	{
		return mData.size();
	}

private:
	std::vector<T> mData;
};
