namespace dk {
	template <uint32_t D>
	TileCoords<D>::TileCoords (const coords& parSize) :
		m_pos(CoordinateScalarType(0)),
		m_size(parSize)
	{
		assert(m_pos <= m_size);
	}

	template <uint32_t D>
	TileCoords<D>::TileCoords (const coords& parValue, const coords& parSize) :
		m_pos(parValue),
		m_size(parSize)
	{
		assert(m_pos <= m_size);
	}

	template <uint32_t D>
	TileCoords<D>& TileCoords<D>::operator++ () {
		const coords lower(0);
		for (CoordinateDistType d = 0; d < D - 1; ++d) {
			++m_pos[d];
			if (m_pos[d] > m_size[d])
				m_pos[d] = lower[d];
			else
				return *this;
		}
		++m_pos[D - 1];
		return *this;
	}

	template <uint32_t D>
	TileCoords<D> TileCoords<D>::operator++ (int) {
		TileCoords<D> retval(*this);
		++(*this);
		return retval;
	}

	template <uint32_t D>
	TileCoords<D>& TileCoords<D>::operator-- () {
		const coords lower(0);
		for (CoordinateDistType d = 0; d < D; ++d) {
			if (m_pos[d] > lower[d]) {
				--m_pos[d];
				return;
			}
			else {
				m_pos[d] = m_size[d];
			}
		}
		++m_pos[D - 1];
		return *this;
	}

	template <uint32_t D>
	TileCoords<D> TileCoords<D>::operator-- (int) {
		TileCoords<D> retval(*this);
		--(*this);
		return retval;
	}

	template <uint32_t D>
	const TileCoords<D>& TileCoords<D>::operator+= (CoordinateScalarType parValue) {
		CoordinateScalarType acc(parValue);
		CoordinateScalarType div(1);
		for (uint32_t z = 0; z < D; ++z) {
			m_pos[z] = (m_pos[z] + acc / div) % m_size[z];
			div *= m_size[z];
			acc += m_pos[z];
		}
	}

	template <uint32_t D>
	bool TileCoords<D>::operator== (const TileCoords& parOther) const {
		return m_pos == parOther.m_pos and m_size == parOther.m_size;
	}

	template <uint32_t D>
	bool TileCoords<D>::operator!= (const TileCoords& parOther) const {
		return not(*this == parOther);
	}
} //namespace dk
