#ifndef ROW_HPP
#define ROW_HPP

#include <iostream>
#include <cstdint>
#include <stdexcept>

template<typename T>
class row {
private:
    T* p;
        uint32_t n;

        public:
            // Constructor
            row(T* arr, uint32_t size) : n(size) {
                p = new T[n];
                for (uint32_t i = 0; i < n; ++i) {
                    p[i] = arr[i];
                }
            }
            //empty Constructor
            row() : p(nullptr), n(0) {}

            // Destructor
                ~row() {
                    delete[] p;
                }

            // Copy Constructor (Deep Copy)
            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) {
                    delete[] p;
                    n=other.n;
                    p = new T[n];
                    for (uint32_t i = 0; i < n; ++i) {
                        p[i] = other.p[i];
                    }
                 }
                 return *this;
             }

             // operator []
             T& operator[](uint32_t index) {
                 return p[index];
             }

             const T& operator[](uint32_t index) const {
                 return p[index];
             }

             // operator at (with bounds checking)
             T& at(uint32_t index) {
                 if (index >= n) throw std::out_of_range("Index out of bounds");
                 return p[index];
             }

              // Helper function for size (needed by sorting algorithms)
              uint32_t size() const { return n; }

              // std::ostream operator << (for output)
              friend std::ostream& operator<<(std::ostream& os, const row<T>& r) {
                  for (uint32_t i = 0; i < r.n; ++i) {
                      os << r.p[i] << (i == r.n - 1 ? "" : ", ");
                  }
                  return os;
             }

             // std::istream operator >> (for data input)
             friend std::istream& operator>>(std::istream& is, row<T>& r) {
                for (uint32_t i = 0; i < r.n; ++i) {
                    is >> r.p[i];
                }
                return is;
             }
          };
#endif
