
#include <objc/Object.h>
#include <coll/coll.h>

#define LAMBDA(RETTYPE, ARGS, BODY) \
({RETTYPE __lambda_func ARGS BODY __lambda_func;})

@interface Collection (TestingExtras)
- printCount;
@end
@implementation Collection (TestingExtras)
- printCount
{
  printf("%s: count=%d\n", [self name], [self count]);
  return self;
}
@end

void checkSameContents(id colllist)
{
  unsigned i, c = [colllist count];
  
  for (i = 1; i < c; i++)
    if (![[colllist objectAtIndex:0] 
	  includesSameContents:[colllist objectAtIndex:i]])
      printf("collection 0 does not have same contents as collection %d\n", i);
}


BOOL nonNullTest(elt e)
{
  if (e.void_ptr_u == 0) return NO;
  else return YES;
}

main()
{
  int i, j, e;
  char *s;
  void *enumState;
  elt anElt;

  id btest = [[BinaryTree alloc] init];
  id bc = [BinaryTree class];

  id array = [[Array alloc] initEncoding:@encode(int)];
  id bag = [[Bag alloc] initEncoding:"i"];
  id stack = [[Stack alloc] initEncoding:"i"];
  id queue = [[Queue alloc] initEncoding:"i"];
  id gaparray = [[GapArray alloc] initEncoding:"i"];
  id llist = [[EltNodeCollector alloc] initEncoding:"i"
	      nodeCollector:[[LinkedList alloc] init]
	      nodeClass:[LinkedListEltNode class]];
  id bt = [[EltNodeCollector alloc] initEncoding:"i"
	   nodeCollector:[[BinaryTree alloc] init]
	   nodeClass:[BinaryTreeEltNode class]];
  id foo = [[Array alloc] initEncoding:"i"];

  id collections = [DelegateList new];

//  print_methods_for_class(bc);

  [collections delegateListAddObject:array];
  [collections delegateListAddObject:llist];
  [collections delegateListAddObject:bag];
  [collections delegateListAddObject:stack];
  [collections delegateListAddObject:queue];
  [collections delegateListAddObject:gaparray];
  [collections delegateListAddObject:bt];
  [collections delegateListAddObject:foo];

  printf("delegateList filled, count=%d\n",
	 [[collections delegateListList] count]);

  [collections addElement:99];
  [collections printCount];

  printf("Adding numbers...\n");
  for (i = 0; i < 17; i++)
    {
      e = random() % 99;
      printf("%2d ", e);
      [collections addElement:e];
    }
  printf("\ncollections filled\n\n");
  [collections printForDebugger];

  if ([array trueForAllElementsByCalling:nonNullTest])
    printf("Array contains no zero's\n");

  if ([array trueForAllElementsByCalling:
	     LAMBDA(BOOL, (elt e), {if (e.void_ptr_u == 0) return NO;
				    else return YES;})
	     ])
    printf("Array contains no zero's\n");

  checkSameContents([collections delegateListList]);

  printf("\nremoving 99\n\n");
  [collections removeElement:99];

  [foo removeElement:[foo minElement]];
  [foo addElement:99];
  printf("Collections 0 and 7 should mismatch\n");
  [collections printForDebugger];

/*
  enumState = NULL;
  while ([bt getNextElement:&anElt withEnumState:&enumState])
    printf("bt occurences of %d is %d\n", 
	   anElt.int_u, [bt occurrencesOfElement:anElt]);
*/

  checkSameContents([collections delegateListList]);

  [collections empty];

  exit(0);

/*
  if (![collections trueForAllByPerforming:@selector(includesSameContents:)
	      with:array])
    printf("error: collections not all the same\n");
*/
}


