#include <iostream>
#include <initializer_list>
using namespace std;

class IntArray
{
private:
    int m_length = 0;
    int *m_data = nullptr;

public:
    IntArray(const int &length_in)
        : m_length(length_in) // 길이를 받으면 m_data에 동적할당
    {
        m_data = new int[m_length];
    }

    IntArray(const std::initializer_list<int> &list)
        : IntArray(list.size()) // init_list를 받아 size를 다시 초기화
    {
        int count = 0;

        for (auto & e : list)
        {
            m_data[count] = e; // m_data에 초기화
            count++;
        }
    }

    IntArray & operator =(const IntArray& intArray) // 대입 연산자 오버로딩
    {
        if (this == &intArray) return *this;

        delete[] m_data;

        m_length = intArray.m_length;

        if (intArray.m_data != nullptr)
        {
            m_data = new int[m_length];

            for (int i=0; i < m_length; ++i)
                m_data[i] = intArray.m_data[i];
        }
        else m_data = nullptr;
    }

    IntArray& resize(const int& length_in) 
    {
        if (m_length == length_in) return *this;
        else if (m_length < length_in) // 길이가 길 경우 0으로 초기화
        {
            int *temp = new int[length_in];
            for (int i=0;i<length_in;++i)
                temp[i] = m_data[i];
            for (int i=m_length;i<length_in;++i)
                temp[i] = 0;

            m_length = length_in;
            delete[] m_data;
            m_data = temp;
            
        }
        else // 길이가 짧아질 경우 length_in만큼만 복사
        {
            int *temp = new int[length_in];
            for (int i=0;i<length_in;++i)
                temp[i] = m_data[i];
            m_length = length_in;
            delete[] m_data;
            m_data = temp;
        }

        return *this;
    }

    IntArray& insertBefore(const int &val, const int & idx) 
    {
        resize(m_length + 1); // 사이즈를 늘리고
        for (int i=m_length;i>idx;--i) // 한칸씩 뒤로 미룬 다음
            m_data[i] = m_data[i-1];
        
        m_data[idx] = val; //인덱스에 val을 할당

        return *this;
            
    }

    IntArray& remove(const int &idx)
    {
        for (int i=idx;i<m_length-1;i++) // idx 뒤에서부터 한칸씩 땡기고
            m_data[i] = m_data[i+1];
        resize(m_length-1); // resize

        return *this;
    }

    IntArray& push_back(const int &val)
    {
        resize(m_length+1);
        m_data[m_length-1] = val; // 사이즈 늘리고 제일 뒤 인덱스에 val을 할당
        return *this;
    }

    IntArray& operator = (const std::initializer_list<int> & list) 
    {
        delete[] m_data;
        m_length = list.size();

        m_data = new int[m_length];

        int count = 0;
        for (auto &e: list)
        {
            m_data[count] = e;
            count++;
        }
        return *this;
    }

    friend ostream& operator << (ostream &out, const IntArray &int_arr)
    {
        for (int i=0;i<int_arr.m_length;++i)
            out << int_arr.m_data[i] << " ";
        return out;

    }

    ~IntArray()
    {
        delete[] m_data;
    }
    
};

int main()
{
    IntArray my_array{1,3,5,7,9};
    cout << my_array << "\n";

    my_array.resize(4);
    cout << my_array << "\n";
    my_array.insertBefore(10,1);
    cout << my_array << "\n";
    my_array.push_back(5);
    cout << my_array << "\n";
    
}