#include "ilist_destructive.h"
#include <stdlib.h>
// The ilist ADT is a pointer to this secret struct
struct ilist_ADT {
struct ilist_ADT * rest;
int first;
int length;
};
// returns an empty ilist
ilist iempty(){
return NULL;
}
// returns 1 if the ilist is empty, 0 if it is not
int iempty_huh(ilist il){
if (il == iempty()) {
return 1;
}
else return 0;
}
// reutrns the first element in an ilist
// ilist should not be empty
int ifirst(ilist il){
return il->first;
}
// icons creates a new node
ilist icons(int in, ilist il) {
ilist r = malloc(sizeof(struct ilist_ADT));
r->first = in;
r->rest = il;
return r;
}
// returns an ilist with a in added as the first element of the ilist
// references cease to be valid ilists
// does not promise not to mutate its arguments
ilist icons_destroy(int in, ilist il) {
if(iempty_huh(il)) {
ilist newlist = malloc(sizeof(struct ilist_ADT));
newlist->rest = iempty();
newlist->length = 1;
newlist->first = in;
return newlist;
}
ilist newlist2 = malloc(sizeof(struct ilist_ADT));
newlist2->length = il->length;
newlist2->first = il->first;
newlist2->rest = il->rest;
il->length = ilength(il) + 1;
il->rest = newlist2;
il->first = in;
return il;
}
// modifies il to remove the first element,
// and returns the modified ilist
// frees memory associated with the first element
ilist irest_destroy(ilist il){
ilist temp = il->rest;
if(iempty_huh(il) == 1) {
free(il); return temp;
}
il->first = temp->first;
il->length = temp->length;
il->rest = temp->rest;
free(temp);
return il;
}
// returns a new copy of the ilist that continues to be a vild
// ilist with the same elemnts even when il is destroyed
ilist icopy(ilist il){
if (il== NULL) return NULL;
int length_temp = il->length;
ilist head = malloc(sizeof(struct ilist_ADT ));
head ->first = il ->first;
head ->rest = NULL;
ilist lstend = head;
for (ilist a = il ->rest; a != NULL; a = a->rest) {
ilist tmp = malloc(sizeof(struct ilist_ADT ));
tmp ->first = a->first;
tmp ->rest = NULL;
lstend ->rest = tmp;
lstend = tmp;
}
head->length = length_temp;
return head;
}
// returns the length of an ilist
int ilength(ilist il){
if (il == NULL) {
return 0;
}
else {
return il->length;
}
}
// free memory for entire ilist
void idelete(ilist il){
while (il != NULL) {
ilist next = il->rest;
free(il);
il = next;
}
}