#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]= new 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>::Tensor 2D operator=(const Tensor2D &other) {
	if (this==&other)
		return *this;
	delete [] data;
	r=other.r;
	c=other.c;
	data=new T*[c];
	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, 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>::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;
	}
}

