/*

File: set.c
Author: Neil Cafferkey
Copyright (C) 1999-2001 Neil Cafferkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.

*/

#include <stdio.h>

#include "memory_protos.h"
#include "set_protos.h"


/* Function: CreateSet
 * ===================
 * Creates a Set.
 */

Set CreateSet(VOID)
{
   Set set=Malloc(sizeof(Set_imp));
   set->first=NULL;
   return set;
}


/* Function: PutInSet
 * ==================
 */

VOID PutInSet(Set set,APTR element)
{
   SetNode old_first=set->first;

   if(!IsInSet(set,element))
   {
      set->first=Malloc(sizeof(SetNode_imp));
      set->first->next=old_first;
      set->first->element=element;
   }

   return;
}


/* Function: TakeFromSet
 * =====================
 */

APTR TakeFromSet(Set set)
{
   SetNode node=set->first;
   APTR element;

   if(node==NULL)
      element=NULL;
   else
   {
      element=node->element;

      set->first=node->next;

      Free(node,sizeof(SetNode_imp));
   }

   return element;
}


/* Function: IsInSet
 * =================
 */

BOOL IsInSet(Set set,APTR element)
{
   SetNode node=set->first;
   while(node!=NULL)
   {
      if(node->element==element)
         return TRUE;
      node=node->next;
   }
   return FALSE;
}


/* Function: IsEmptySet
 * ====================
 */

BOOL IsEmptySet(Set set)
{
   return set->first==NULL;
}


/* Function: GetSetSize
 * ====================
 */

ULONG GetSetSize(Set set)
{
   SetNode node;
   ULONG count=0;

   for(node=set->first;node!=NULL;node=node->next)
      count++;

   return count;
}


/* Function: DupSet
 * ================
 */

Set DupSet(Set source)
{
   Set dest=CreateSet();
   SetNode node=source->first;

   while(node!=NULL)
   {
      PutInSet(dest,node->element);
      node=node->next;
   }
   return dest;
}


/* Function: KillSet
 * =================
 * Kills the set but not its elements.
 */

VOID KillSet(Set set)
{
   while(set->first!=NULL)
      TakeFromSet(set);
   Free(set,sizeof(Set_imp));
   return;
}


#ifdef TEST

#include <assert.h>


LONG main(VOID)
{
   Set set=CreateSet(),set2;

   PutInSet(set,7);
   PutInSet(set,4);
   PutInSet(set,18);

   assert(IsInSet(set,18));
   assert(IsInSet(set,18));
   assert(!IsInSet(set,0));
   assert(!IsEmptySet(set));

   set2=DupSet(set);

   printf("%d\n",TakeFromSet(set));
   printf("%d\n",TakeFromSet(set));
   printf("%d\n",TakeFromSet(set));

   ShowSet(set2);

   printf("%d\n",TakeFromSet(set2));
   printf("%d\n",TakeFromSet(set2));
   printf("%d\n",TakeFromSet(set2));

   assert(IsEmptySet(set2));
   assert(TakeFromSet(set)==NULL);
   assert(!IsInSet(set,18));

   KillSet(set);

   return EXIT_SUCCESS;
}

#endif


