#include <stdlib.h>
#include <assert.h>

#include "llist.h"

struct llist_node_t {
  struct llist_node_t *next;
  void *data;
};

// Initializes an LList
LList LList_init(LList *pList) {
  assert(pList != NULL);
  *pList = NULL;
  return *pList;
}


LList LList_push(LList *pList, void *data) {
  assert(pList != NULL);
  LList_node *pNode = (LList_node*)malloc(sizeof(LList_node));
  if ( pNode == NULL ) return NULL;
  pNode->next = *pList;
  pNode->data = data;
  *pList = pNode;
  return *pList;
}

void* LList_pop(LList *pList) {
  assert(pList != NULL);
  if ( *pList == NULL ) return NULL;
  void *result = (*pList)->data;
  LList_node *pTemp = (*pList)->next;
  free((*pList));
  *pList = pTemp;
  return result;
}

bool LList_isEmpty(const LList pList) {
  return pList == NULL;
}

LList LList_map(const LList list, LList_map_callback callback) {
  for ( LList_node *pNode = list; pNode; pNode = pNode->next ) {
    callback(pNode->data);
  }
  return list;
}