//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//

#include <cool/String.h>
#include <cool/Iterator.h>
#include <cool/Vector.h>
#include <cool/Association.h>
#include <cool/Queue.h>
#include <cool/List.h>
#include <cool/Set.h>
#include <cool/Bit_Set.h>
#include <cool/Hash_Table.h>
#include <cool/Package.h>
#include <test.h>

DECLARE Vector<int>;
IMPLEMENT Vector<int>;

DECLARE Association<int,char*>;
IMPLEMENT Association<int,char*>;

DECLARE List<int>;
IMPLEMENT List<int>;

DECLARE Hash_Table<int,String>;
IMPLEMENT Hash_Table<int,String>;

DECLARE Set<int>;
IMPLEMENT Set<int>;

DECLARE Queue<int>;
IMPLEMENT Queue<int>;

DECLARE Iterator<Queue>;
DECLARE Iterator<Set>;
DECLARE Iterator<Bit_Set>;
DECLARE Iterator<Hash_Table>;
DECLARE Iterator<List>;
DECLARE Iterator<Package>;
DECLARE Iterator<Association>;
DECLARE Iterator<Vector>;

void test_Iter_Vector() {
  Vector<int> v(10);
  TEST ("Vector<int> v(10)", v.capacity(), 10);
  Iterator<Vector> iv;
  TEST ("Iterator<Vector> iv", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) v.push(i)",
	    for (int i = 0; i < 10; i++) v.push(i), v.length(), 10);
  TEST ("v.reset()", (v.reset(), 1),1);
  TEST ("iv = v.current_position()", (iv = v.current_position(), iv), INVALID);
  TEST ("v.next; v.value()==0;", (v.next (), v.value()), 0);
  TEST ("v.next; v.value()==1;", (v.next (), v.value()), 1);
  TEST ("v.current_position() = iv", (v.current_position()=iv, iv), INVALID);
  TEST ("v.next(); v.value()==0;", (v.next(),v.value()), 0);
}

void test_Iter_Association() {
  Association<int,char*> a(10);
  TEST ("Association<int,char*> a(10)", a.capacity(), 10);
  Iterator<Association> ia;
  TEST ("Iterator<Association> ia", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) a.put(i,\"ABC\")",
	    for (int i = 0; i < 10; i++) a.put(i, "ABC"), a.length(), 10);
  TEST ("a.reset()", (a.reset(), 1),1);
  TEST ("ia = a.current_position()", (ia = a.current_position(), ia), INVALID);
  TEST ("a.next; a.value()==(0,\"ABC\");", 
	(a.next (), (a.key()==0 && !strcmp(a.value(),"ABC"))), 1);
  TEST ("a.next; a.value()==(1,\"ABC\");", 
	(a.next (), (a.key()==1 && !strcmp(a.value(),"ABC"))), 1);
  TEST ("a.current_position() = ia", (a.current_position()=ia, ia), INVALID);
  TEST ("a.next; a.value()==(0,\"ABC\");", 
	(a.next (), (a.key()==0 && !strcmp(a.value(),"ABC"))), 1);
}

void test_Iter_List() {
  List<int> l;
  TEST ("List<int> l", 1, 1);
  Iterator<List> il;
  TEST ("Iterator<List> il", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) l.push(i)",
	    for (int i = 0; i < 10; i++) l.push(i), l.length(), 10);
  TEST ("l.reset()", (l.reset(), 1),1);
  TEST ("il = l.current_position()", (il = l.current_position(), il), NULL);
  TEST ("l.next; l.value()==9;", (l.next (), l.value()), 9);
  TEST ("l.next; l.value()==8;", (l.next (), l.value()), 8);
  TEST ("l.current_position() = il", (l.current_position()=il, il), NULL);
  TEST ("l.next(); l.value()==9;", (l.next(),l.value()), 9);
}

void test_Iter_Queue() {
  Queue<int> q(10);
  TEST ("Queue<int> q(10)", q.capacity(), 10);
  Iterator<Queue> iq;
  TEST ("Iterator<Queue> iq", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) q.put(i)",
	    for (int i = 0; i < 10; i++) q.put(i),q.length(), 10);
  TEST ("q.reset()", (q.reset(), 1),1);
  TEST ("iq = q.current_position()", (iq = q.current_position(), 0), 0);
  TEST ("q.next; q.value()==0;", (q.next (), q.value()), 0);
  TEST ("q.next; q.value()==1;", (q.next (), q.value()), 1);
  TEST ("q.current_position() = iq", (q.current_position()=iq, 0), 0);
  TEST ("q.next(); q.value()==0;", (q.next(),q.value()), 0);
}


void test_Iter_Set() {
  Set<int> s(10);
  TEST ("Set<int> s(10)", (s.capacity() >= 10), 1);
  Iterator<Set> is;
  TEST ("Iterator<Set> is", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) s.put(i)",
	    for (int i = 0; i < 10; i++) s.put(i),s.length(), 10);
  TEST ("s.reset()", (s.reset(), 1),1);
  TEST ("is = s.current_position()", (is = s.current_position(), is), INVALID);
  TEST ("s.next; s.value()==0;", (s.next (), s.value()), 0);
  TEST ("s.next; s.value()==1;", (s.next (), s.value()), 1);
  TEST ("s.current_position() = is", (s.current_position()=is, is), INVALID);
  TEST ("s.next(); s.value()==0;", (s.next(),s.value()), 0);
 }

void test_Iter_Bit_Set() {
  Bit_Set b(10);
  TEST ("Bit_Set b(10)", (b.capacity() >= 10), 1);
  Iterator<Bit_Set> ib;
  TEST ("Iterator<Bit_Set> ib", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) b.put(i)",
	    for (int i = 0; i < 10; i++) b.put(i),b.length(), 10);
  TEST ("b.reset()", (b.reset(), 1),1);
  TEST ("ib = b.current_position()", (ib = b.current_position(), ib), INVALID);
  TEST ("b.next; b.value()==0;", (b.next (), b.value()), 0);
  TEST ("b.next; b.value()==1;", (b.next (), b.value()), 1);
  TEST ("b.current_position() = ib", (b.current_position()=ib, ib), INVALID);
  TEST ("b.next(); b.value()==0;", (b.next(),b.value()), 0);
}

void test_Iter_Hash_Table() {
  Hash_Table<int,String> h(10);
  TEST ("Hash_Table<int,String> h(10)", (h.capacity() >= 10), 1);
  Iterator<Hash_Table> ih;
  TEST ("Iterator<Hash_Table> ih", 1, 1);
  TEST_RUN ("for (int i=0;i<10;i++) h.put(i,String(\"ABC\"))",
	    for (int i=0; i < 10; i++) h.put(i, String("ABC")),h.length(), 10);
  TEST ("h.reset()", (h.reset(), 1),1);
  TEST ("ih = h.current_position()", (ih = h.current_position(), ih), INVALID);
  TEST ("h.next; h.value()==(0,String(\"ABC\"));", 
	(h.next (), (h.key()==0 && !strcmp(h.value(),"ABC"))), 1);
  TEST ("h.next; h.value()==(1,String(\"ABC\"));", 
	(h.next (), (h.key()==1 && !strcmp(h.value(),"ABC"))), 1);
  TEST ("h.current_position() = ih", (h.current_position()=ih, ih), INVALID);
  TEST ("h.next; h.value()==(0,String(\"ABC\"));", 
	(h.next (), (h.key()==0 && !strcmp(h.value(),"ABC"))), 1);
 }

void test_Iter_Package() {
  Package p(10);
  TEST ("Package p(10)", (p.capacity() >= 10), 1);
  Iterator<Package> ip;
  TEST ("Iterator<Package> ip", 1, 1);
  Symbol* sym_a = p.intern("A");
  Symbol* sym_b = p.intern("B");
  Symbol* sym_c = p.intern("C");
  Symbol* sym_d = p.intern("D");
  Symbol* sym_e = p.intern("E");
  Symbol* sym_f = p.intern("F");
  Symbol* sym_g = p.intern("G");
  Symbol* sym_h = p.intern("H");
  Symbol* sym_i = p.intern("I");
  Symbol* sym_j = p.intern("J");
  TEST ("p.intern(\"ABCDEFGHIJ\")",p.length(), 10);
  TEST ("p.reset()", (p.reset(), 1),1);
  TEST ("ip = p.current_position()", (ip = p.current_position(), ip), INVALID);
  TEST ("p.next; p.value()", (p.next (), p.value()), sym_b);
  TEST ("p.next; p.value()", (p.next (), p.value()), sym_e);
  TEST ("p.current_position() = ip", (p.current_position()=ip, ip), INVALID);
  TEST ("p.next; p.value()", (p.next (), p.value()), sym_b);
}


int main () {
  START("Iterator");

  test_Iter_Vector();
  test_Iter_Association();
  test_Iter_List();
  test_Iter_Queue();
  test_Iter_Set();
  test_Iter_Bit_Set();
  test_Iter_Hash_Table();
  test_Iter_Package();

  SUMMARY();
  return 0;
}
