#include <iostream>

using namespace std;

class Object
{
    private:
        int data;
    public:
        Object *next;
        Object(int);
        ~Object();
        void print();
    
    friend class myList;
};

Object :: Object(int value)
{
    data = value;
    next = NULL;
    cout << "Created object of " << data << endl;
}

Object :: ~Object()
{
    cout << "Deleted object of " << data << endl;
}

void Object :: print()
{
    cout << data << endl;
}

class myList
{
    private:
        Object *first;
    public:
        myList();
        ~myList();
        int size();
        void push_back(int);
        void erase(int);
        void print();
        int find(int);
};

myList :: myList()
{
    first = NULL;
}

myList :: ~myList()
{
    Object *temp = first;
    
    while (temp)
    {
        delete temp;
        temp = temp->next;
    }
    
    delete temp;
}

int myList :: size()
{
    int size = 0;
    Object *temp = first;
    
    while (temp)
    {
        size++;
        temp = temp->next;
    }
    
    return size;
}

void myList :: push_back(int val)
{
    Object *obj = new Object(val);
    int pos = 0;
    
    if (first == NULL)
    {
        first = obj;
    }
    else
    {
        pos++;
        Object *temp = first;
        
        while (temp->next)
        {
            temp = temp->next;
            pos++;
        }
        
        temp->next = obj;
        temp->next->next = NULL;
    }
    
    cout << "Pushed " << val << " at pos " << pos << endl;
}

void myList :: erase(int index)
{
    if (index > this->size() or index < 1)
    {
        cout << "Index out of range!" << endl;
        return;
    }
    else
    {
        int i = 1;
        Object *temp = first;
        
        if (index == i)
        {
            delete first;
            first = temp->next;
        }
        else if (index >= 2)
        {
            while (temp)
            {
                if ((i + 1) == index)
                {
                    Object *temp2 = temp->next->next;
                    delete temp->next;
                    temp->next = temp2;
                    break;
                }
                
                temp = temp->next;
                i++;
            }
        }
    }
}

void myList :: print()
{
    Object *temp = first;
    int pos = 0;
    
    while (temp)
    {
        cout << pos << ": ";
        temp->print();
        temp = temp->next;
        pos++;
    }
}

int myList :: find(int val)
{
    int pos = 1;
    Object *temp = first;
    
    while (temp)
    {
        if (temp->data == val)
        {
            cout << "Found " << val << " at pos " << pos << endl;
            return pos;
        }
        else
        {
            pos++;
            temp = temp->next;
        }
    }
    
    cout << "Not found " << val << " in list" << endl;
    return -1;
}

int main()
{
    myList *list = new myList();
    
    list->push_back(3);
    list->push_back(6);
    list->push_back(2);
    list->push_back(4);
    list->push_back(-6);
    
    cout << "size: " << list->size() << endl;
    list->print();
    
    list->erase(3);
    cout << "size: " << list->size() << endl;
    list->print();
    
    list->erase(list->find(6));
    cout << "size: " << list->size() << endl;
    list->print();
    
    delete list;
    
    return 0;
}