#ifndef ROW_CPP
#define ROW_CPP

#include "sorting_algorithms.hpp"
#include "row.hpp"

#include <iostream>
#include <cstdint>
#include <utility>

using namespace std;

template <typename T>
Row<T>::Row(uint32_t size){
	n=size;
	if(n>0){
		p = new T[n];
		}
	else {
		p = nullptr;
		}
}

template <typename T>
Row<T>::Row(T* arr, uint32_t size){
	n=size;
	p= new T[n];
	for (uint32_t i=0; i<n; i++){
		p[i]= arr[i];
		}
}

template <typename T>
Row<T>::~Row(){
	if (p!= nullptr){
		delete[] p;
		p=nullptr;
	}
}

template <typename T>
Row<T>::Row(const Row<T>& other){
	n=other.n;
	if (n>0){
		p = new T[n];
		for (uint32_t i=0; i<n; i++){
			p[i]=other.p[i];
			}
		}
	else {
		p =nullptr;
		}
}

template <typename T>
Row<T>& Row<T>::operator=(const Row<T>& other){
	if (this == other){
		return *this;
		}
	delete[] p;

	if(n>0){
		p =new T[n];
		for (uint32_t i=0; i<n; i++){
			p[i]=other.p[i];
			}
		}
	else{
		p=nullptr;
		}
return *this;
}

template <typename T>
T& Row<T>::operator[](uint32_t idx){
	return p[idx];
}

template <typename T>
const T& Row<T>::operator[](uint32_t idx) const{
	return p[idx];
}

template <typename T>
T& Row<T>::at(uint32_t idx){
	if (idx >=n){
		throw out_of_range("εκτος οριων");
		}
return p[idx];
}

template <typename T>
const T& Row<T>::at(uint32_t idx) const{
	if  (idx >=n){
		throw out_of_range("εκτος οριων");
		}
return p[idx];
}

//template <typename T>
//ostream& operator<<(ostream& os, const Row<T>& r){
//	for(uint32_t i=0; i<r.n; i++){
//		os << r.p[i];
//		if (i<r.n-1){
//			os <<" ";
//			}
//		}
//return os;
//}

//template <typename T>
//istream& operator>>(istream& is, const Row<T>& r){
//	for (uint32_t i=0; i< r.n; i++){
//		is >> r.p[i];
//		}
//return is;
//}

template <typename T>
uint32_t Row<T>::size() const{
return n;
}


#endif 
