/*
 * Example 3: class RWGDlist; generic doubly-linked lists, using ints
 *
 * $Id: example3.cpp,v 2.3 1993/04/12 11:17:32 jims Exp $
 *
 ****************************************************************************
 *
 * Rogue Wave Software, Inc.
 * P.O. Box 2328
 * Corvallis, OR 97339
 * Voice: (503) 754-2311	FAX: (503) 757-7350
 *
 * Copyright (C) 1989, 1990, 1991. This software is subject to copyright 
 * protection under the laws of the United States and other countries.
 *
 ***************************************************************************
 *
 * $Log: example3.cpp,v $
 * Revision 2.3  1993/04/12  11:17:32  jims
 * Replaced "GDlist" with "RWGDlist"
 *
 * Revision 2.2  1993/02/13  21:46:42  keffer
 * Zortech does not have a definition for ostream::flush().
 *
 * Revision 2.1  1993/02/09  18:37:29  keffer
 * Updated with new iterator semantics.
 *
 * Revision 2.0  1992/10/23  03:34:26  keffer
 * RCS Baseline version
 *
 * 
 *    Rev 1.1   07 Jun 1992 17:11:08   KEFFER
 * Tools.h++ V5.1
 * 
 */


// Include the header file for the class RWGDlist:
#include <rw/gdlist.h>
#include <rw/rstream.h>

/* The class RWGDlist makes use of the macro declare defined in the header file
 * <generic.h> to implement the current C++ approximation to parameterized types.
 * The first argument is the class name (RWGDlist).
 * The second argument is the type of object being stored (int).
 */

declare(RWGDlist,int)

// Some data to be stored:
int idata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

main()
{
  // Construct a linked-list of pointers to ints with no links:
  // The form: RWGDlist(int) is converted via a macro to intRWGDlist.
  RWGDlist(int) L;

  cout << "Prepend ints: 4 3 2 1 0\n";
  L.prepend(&idata[4]);
  L.prepend(&idata[3]);
  L.prepend(&idata[2]);
  L.prepend(&idata[1]);
  L.prepend(&idata[0]);

  cout << "Insert (append) ints: 5 6 7 8\n";
  L.insert(&idata[5]);
  L.insert(&idata[6]);
  L.insert(&idata[7]);
  L.insert(&idata[8]);

  cout << "Value at head is:   " << *L.first()   << endl;
  cout << "Value at tail is:   " << *L.last()    << endl;
  cout << "Number of links is: " <<  L.entries() << endl;

  cout << "Now remove and print each link from head:\n";
  while ( !L.isEmpty() )
    cout << *L.get() << endl;

  cout << "Remake list L, insert: 0 1 2 3 4 5\n\n";
  L.insert(&idata[0]);
  L.insert(&idata[1]);
  L.insert(&idata[2]);
  L.insert(&idata[3]);
  L.insert(&idata[4]);
  L.insert(&idata[5]);

  cout << "Construct an iterator for the linked-list.\n";
  RWGDlistIterator(int) c(L);

  // Exercise the iterator:

  cout << "Advance iterator 1 link.  Should point to: 0\n";
  ++c;
  cout << " *c.key() = " << *c.key() << endl;

  cout << "Advance iterator again.  Should point to: 1\n";
  ++c;
  cout << " *c.key() = " << *c.key() << endl;

  cout << "Move iterator to head of list.  Should point to: 0\n";
  c.toFirst();
  cout << " *c.key() = " << *c.key() << endl;

  cout << "Move iterator to find '4' and print it out:\n";
  c.findNextReference(&idata[4]);
  cout << " *c.key() = " << *c.key() << endl;

  cout << "Delete current item (which is 4).  Should point to 3.\n";
  c.remove();
  cout << " *c.key() = " << *c.key() << endl;

  // Use the operator () to move through the list:
  // first, reset the iterator:
  c.reset();

  cout << "Now reset the iterator and use operator() to move through the list.\n";
  cout << "Should read 0 1 2 3 5:\n";
  const int* v;
  while( (v = c()) != 0 )
    cout << *v << " ";

  cout << endl;

  return 0;
}
