/*
  CoreLinux++ 
  Copyright (C) 1999 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/   

/** \example examp5.cpp
   This example is to test the Iterator pattern implementations in
   libcorelinux++. A more comprehensive test will be provided in
   ex6 which is destined for the Composite pattern implementation.
*/                   


#include <Common.hpp>
#include <List.hpp>
#include <Vector.hpp>

#include <CoreLinuxIterator.hpp>

#include <iostream>
#include <exception>

using namespace corelinux;
using namespace std;

CORELINUX_LIST(  Int ,  IntList );
CORELINUX_VECTOR(  Real ,  RealVector );

//
// In module function prototypes
//

int   main( void );                       

// Function template for iterating over the elements

template<class T>
   void  dumpIterator( Iterator<T> *aIteratorPtr );

//
// Standard issue
//

void  handleAssertion( AssertionCref aAssert );
void  handleException( ExceptionCref aExcp );


int main( void )
{
   //
   // Practice gracefull exception management
   //

   try
   {
      //
      // Our first test is with a Iterator for Integers
      //

      Iterator<Int>  *aIntIterator(NULLPTR);
      IntList        aIntList;

      aIntList.push_back(5);
      aIntList.push_back(6);
      aIntList.push_back(7);

      //
      // Construct the STL list iterator
      //

      aIntIterator = new CoreLinuxIterator<IntListIterator,Int>
         (
            aIntList.begin(),
            aIntList.end()
         );

      dumpIterator<Int>(aIntIterator);

      delete aIntIterator;

      //
      // Now try it with a Iterator for Real
      //

      Iterator<Real> *aRealIterator( NULLPTR );
      RealVector     aRealVector;

      aRealVector.push_back(0.7);
      aRealVector.push_back(2.8);
      aRealVector.push_back(7.19823);

      //
      // Construct the STL vector iterator
      //

      aRealIterator = new CoreLinuxIterator<RealVectorIterator,Real>
         (
            aRealVector.begin(),
            aRealVector.end()
         );

      dumpIterator<Real>(aRealIterator);
      delete aRealIterator;
   }

   //
   // We want to reason with the exception type to give the
   // user a more informative message.
   //

   catch( InvalidIteratorExceptionRef aInvalidIterator )
   {
      cerr << "Invalid iterator constructed." << endl;
      handleException(aInvalidIterator);
   }
   catch( IteratorBoundsExceptionRef aBoundsException )
   {
      cerr << "Bounds exception occured during traversel." << endl;
      handleException(aBoundsException);
   }
   catch( AssertionRef aAssert )
   {
      handleAssertion(aAssert);
   }
   catch( std::exception & e )
   {
      cerr  << e.what() << endl;
   }
   catch( ... )
   {
      cerr  << "Unknown exception." << endl;
   }

   return 0;               
}


template<class T>
   void  dumpIterator( Iterator<T> *aIteratorPtr )
   {
      while( aIteratorPtr->isValid() )
      {
         cout  << aIteratorPtr->getElement() << endl;
         aIteratorPtr->setNext();
      }
   }



//
// Peform default (just show it)
//

void  handleAssertion( AssertionCref aAssert )
{
   cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << 
      "Assertion: ";

   if( aAssert.getType() == Assertion::NEVERGETHERE )
   {
      cerr << "NEVER_GET_HERE";
   }
   else
   {
      if( aAssert.getType() == Assertion::REQUIRE )
      {
         cerr  << "REQUIRE";
      }
      else if( aAssert.getType() == Assertion::ENSURE )
      {
         cerr  << "ENSURE";
      }
      else if( aAssert.getType() == Assertion::CHECK )
      {
         cerr  << "CHECK";
      }
      else 
      {
         cerr  << "ASSERT";
      }
      cerr << "( " << aAssert.getWhy() << " )";
   }

   cerr << endl;
}

void  handleException( ExceptionCref aExcp )
{
   cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" <<
      "Exception: " << aExcp.getWhy() << endl;
}

/*
   Common rcs information do not modify
   $Author: prudhomm $
   $Revision: 1.2 $
   $Date: 2000/08/31 22:49:01 $
   $Locker:  $
*/


