//  (C) Porkolab 2003
//
//  A.1.6.
//  Scope rules for constants 



// file: list.h

#ifndef LIST_H
#define LIST_H

#include <iostream>

class list
{
public:
         list();
         ~list();

    list *remove();
    void  append(list *lp);
    void  insert(list *lp);
    list *get_next() const { return next; }
    list *get_prev() const { return prev; }

    void print( std::ostream& os) const;

    static int get_nid() { return nid; }
private:
    const int  id;
          list *next;
          list *prev;

    static int nid;

    list( const list &rhs);
    list operator=( const list *rhs);
};

std::ostream& operator<<( std::ostream&, const list&);

#endif /* LIST_H */



////////////////////////////////////////////////////////



// file: list.cpp

#include <iostream>
#include "list.h"

using namespace std;

int list::nid = 0;

list::list() : id(nid), prev(0), next(0)
{
    ++nid;
}

list::~list()
{
    remove();
}

list *list::remove()
{
    if ( prev ) prev->next = next;
    if ( next ) next->prev = prev;
    next = prev = 0;
    return this;
}

void list::append( list *lp)
{
    next = lp->next;
    lp->next = this;
    prev = lp;
    if ( next ) next->prev = this;
}

void list::insert( list *lp)
{
    prev = lp->prev;
    lp->prev = this;
    next = lp;
    if ( prev ) prev->next = this;
}

void list::print( ostream& os) const
{
    os << "[ id = " << id << " ]";
}

ostream& operator<<( ostream& os, const list &l)
{
    l.print(os);
    return os;
}



///////////////////////////////////////////////////



// file: listmain.cpp

#include <iostream>
#include "list.h"

using namespace std;

int main()
{
    cout << "# = " << list::get_nid() << endl;
    list l1, l2, l3, l4;

    l2.append(&l1);
    l3.insert(&l2);
    l4.append(&l3);

    for( list *lp = &l1; lp; lp = lp->get_next() )
        cout << *lp << endl;

    cout << "# = " << list::get_nid() << endl;
    return 0;
}