#pragma once
#include <luna/Types.h>

template <typename T> class Slice
{
    typedef T* Iterator;
    typedef const T* ConstIterator;

  public:
    Slice(T* data, usize size) : m_data(data), m_size(size)
    {
    }

    template <typename Tp> Slice(const Slice<Tp>& other) : m_data((T*)other.m_data), m_size(other.m_size)
    {
    }

    const T* data() const
    {
        return m_data;
    }

    T* data()
    {
        return m_data;
    }

    usize size() const
    {
        return m_size;
    }

    Iterator begin()
    {
        return m_data;
    }

    ConstIterator begin() const
    {
        return m_data;
    }

    Iterator end()
    {
        return m_data + m_size;
    }

    ConstIterator end() const
    {
        return m_data + m_size;
    }

    const T& operator[](usize index) const
    {
        check(index < m_size);
        return m_data[index];
    }

    T& operator[](usize index)
    {
        check(index < m_size);
        return m_data[index];
    }

  private:
    T* const m_data;
    const usize m_size;
};