#include <iostream>
#include"tensor2D.h"

template<typename T>
Tensor2D<T>::Tensor2D(int rows, int cols) {
	r=rows;
	c=cols;
			data = new T*[r];
			for (int i=0;i<r;i++) {
			data[i]=new T[c];
			for (int j=0;j<c;j++) {
			data[i][j]= T();
				}
			}
			}
template<typename T>
	Tensor2D<T>::Tensor2D(const Tensor2D &other) {
		r=other.r;
		c=other.c;
	data=new T*[r];
	for (int i=0;i<r;i++) {
	data[i]=new T[c];
	for (int j=0;j<c;j++) {
	data[i][j]=other.data[i][j];
		}
		}
		}
	template<typename T>
	Tensor2D<T>& Tensor2D<T>::operator=(const Tensor2D &other) {
	if (this==&other)
	return *this;
	//delete [] data;
		r=other.r;
		c=other.c;
		data=new T*[r];
			for (int i=0;i<r;i++) {
			data[i]=new T[c];
			for (int j=0;j<c;j++) {
			data[i][j]=other.data[i][j];
					}
	    				}
			return *this;	
				}

	template<typename T> Tensor2D<T>::~Tensor2D() {
	for (int i=0;i<r;i++) 
	delete data[i];
	delete[] data;
						}

	template<typename T>
	void Tensor2D<T>::set(int row, int col, const T& value) {
	data[row][col]=value;
								}
	template<typename T>
	T Tensor2D<T>::get(int row, int col) const {
	return data[row][col];
								}
	template<typename T>
	T& Tensor2D<T>::operator() (int row, int col) {
	return data[row][col];
								}

	template<typename T>
	T& Tensor2D<T>::operator() (int row, int col) const {
	return data[row][col];
	}

		

        template<typename T>
	T *Tensor2D<T>::operator[](int row) {
	return data[row];
		}

	template<typename T>
	T *Tensor2D<T>::operator[](int row) const {
	return data[row];
				}

	template<typename T>
	std::pair<int,int> Tensor2D<T>::shape()const
		{
		return {r,c};
                }


template<typename T>
int Tensor2D<T>::rows() const{ 
return r;
}

template<typename T>
int Tensor2D<T>::cols() const {
	return c;
	}

	template<typename T>
	void Tensor2D<T>::print(void) {
		for (int i=0;i<r;i++) {
				for (int j=0;j<c;j++) {
							std::cout << data[i][j] << " ";
									}
	std::cout<<std::endl;}
	}

	/*Explicit template instantiations use*/
	template class Tensor2D<int>;
	template class Tensor2D<double>;
	template class Tensor2D<float>;
