// ANASTASIA_PAPOUDA_12736
#ifndef ROW_HPP
#define ROW_HPP
#include <iostream>
#include <cstdint>
#include <stdexcept>
#include "sort_algorithms.hpp"

template<typename T>
class row {
private:
    T* p;          //pointer
    uint32_t n;    //number of elements

public:

    // constructor
    row(T* data, uint32_t size) {
        n = size;
        p = new T[n];	//allocates new memory on heap
        for (uint32_t i = 0; i < n; i++)	//copies elements
            p[i] = data[i];
    }

    // destructor
    ~row() {
        delete[] p;	 //frees the memory we allocated
    }

    // copy constructor
    row(const row& other) {
        n = other.n;
        p = new T[n];
        for (uint32_t i = 0; i < n; i++)
            p[i] = other.p[i];
    }

    // assignment operator(deep copy)
    row& operator=(const row& other) {
         if (this == &other)
        {
            return *this;   //if it's the same object do nothing
        }

        delete[] p;   //deletes old memory
		n = other.n;
        p = new T[n];

        for (uint32_t i = 0; i < n; i++)
        {
            p[i] = other.p[i];
        }

        return *this;	//returns current object
    }

    // size function
    uint32_t size() const {
        return n;
    }

    // operator[]
    T& operator[](uint32_t index) {	 //no bounds checking
        return p[index];
    }

    // operator at
    T& at(uint32_t index) {	 //with bounds checking
        if (index >= n)
        {
            std::cout << "Index out of range" << std::endl;
            exit(1);
    	}
        return p[index];
    }

    // operator <<(output)
    friend std::ostream& operator<<(std::ostream& os, const row& r) {
        for (uint32_t i = 0; i < r.n; i++)
            os << r.p[i] << " ";
        return os;
    }

    // operator >>(input)
    friend std::istream& operator>>(std::istream& is, row& r) {
        for (uint32_t i = 0; i < r.n; i++)
            is >> r.p[i];
        return is;
    }
};

#endif
