#include <librapid/array/esiterator.hpp>

namespace librapid {
	ESIterator::ESIterator() = default;

	ESIterator::ESIterator(pointer start) : m_ptr(start) {}

	ESIterator::ESIterator(const ESIterator &other) = default;

	ESIterator::~ESIterator() = default;

	ESIterator &ESIterator::operator=(const ESIterator &other) = default;

	ESIterator &ESIterator::operator=(pointer ptr) {
		m_ptr = ptr;
		return *this;
	}

	ESIterator::operator bool() const { return m_ptr ? true : false; }

	bool ESIterator::operator==(const ESIterator &other) const {
		return m_ptr == other.getConstPointer();
	}

	bool ESIterator::operator!=(const ESIterator &other) const {
		return m_ptr != other.getConstPointer();
	}

	ESIterator &ESIterator::operator+=(const differenceType &movement) {
		m_ptr += movement;
		return (*this);
	}

	ESIterator &ESIterator::operator-=(const differenceType &movement) {
		m_ptr -= movement;
		return (*this);
	}

	ESIterator &ESIterator::operator++() {
		++m_ptr;
		return (*this);
	}

	ESIterator &ESIterator::operator--() {
		--m_ptr;
		return (*this);
	}

	ESIterator ESIterator::operator++(int) {
		auto temp(*this);
		++m_ptr;
		return temp;
	}

	ESIterator ESIterator::operator--(int) {
		auto temp(*this);
		--m_ptr;
		return temp;
	}

	ESIterator ESIterator::operator+(const differenceType &movement) const {
		return ESIterator(m_ptr + movement);
	}

	ESIterator ESIterator::operator-(const differenceType &movement) const {
		return ESIterator(m_ptr - movement);
	}

	ESIterator::differenceType
	ESIterator::operator-(const ESIterator &rawIterator) const {
		return std::distance(rawIterator.getPointer(), getPointer());
	}

	ESIterator::reference ESIterator::operator*() { return *m_ptr; }

	const ESIterator::reference ESIterator::operator*() const { return *m_ptr; }

	const ESIterator::pointer ESIterator::getConstPointer() const {
		return m_ptr;
	}

	ESIterator::pointer ESIterator::getPointer() const { return m_ptr; }
} // namespace librapid