// The node class for singly-linked list of integers

#include <cassert>
#include <iostream>
using namespace std;

class Node
{
    friend void print_list( Node const& head );
public:
    Node* pnext;
    int data;

    // Constructor taking initial value:
    Node( int value = 0 )
    : pnext( NULL ), data( value )
    {
    }

    // Copy constructor:
    Node( Node const& other )
        : pnext( NULL ), data( other.data )
    {
    }

    // Insert new node in front:
    void insert( Node* newNode )
    {
        newNode->pnext = pnext;
        pnext = newNode;
    }

    // Remove node in front:
    void remove_next()
    {
        if ( pnext == NULL ) return;
        Node* obsolete = pnext;
        this->pnext = obsolete->pnext;
        // Make node "single":
        obsolete->pnext = NULL;
    }

    // Remove other node in front:
    bool remove( Node* other )
    {
        Node* previous = this;
        Node* iter = pnext;
        while ( iter != other ) {
            if ( iter == NULL )
                return false;
            previous = iter;
            iter = iter->pnext;
        }
        previous->pnext = iter->pnext;
        // Make node "single" after successful removal:
        other->pnext = NULL;
        return true;
    }

    // Measure distance to other node:
    int distance( Node const* other ) const
    {
        int hops = 1;
        Node const* iter = pnext;
        while ( iter != other ) {
            if ( iter == NULL ) {
                // Don't count this last hop:
                return hops - 1;
            }
            iter = iter->pnext;
            ++hops;
        }
        return hops;
    }
    // Calculate number of nodes in the list:
    size_t size() const
    {
        return distance( NULL );
    }
};

// Print contents of the list:
void print_list( Node const& head )
{
    cout << '[' << head.size() << "] ";
    Node const* iter = &head;
    do {
        cout << iter->data << ' ';
        iter = iter->pnext;

    } while ( iter != NULL );
    cout << '\n';
}

