Generic Doubly Linked List Library (similar to C++ STL list and other C++ STL data structures).

From: Amit
Date: Tue Jul 16 2024 - 11:18:52 EST


This is a generic linked list library implementation, similar to C++ STL list.
By using a combination of functions provided in this library, this library can
also be used as other C++ STL data structures such as - stack, queue, deque,
map, set, multimap, multiset, unordered_map, unordered_set, unordered_multimap,
and unordered_multiset.

The unique feature of this library is that it copies user's data into its
elements, so the user doesn't have to keep his/her copy of data around. User's
data safely resides in the elements.

-----------------------------------------------
An example of using this library as a 'set' is:
-----------------------------------------------

if (gdlll_peek_matching_element(...) == NULL) {
gdlll_add_element_sorted_ascending(...);
}

----------------------------------------------------------
An example of using this library as an 'unordered_set' is:
----------------------------------------------------------

if (gdlll_peek_matching_element(...) == NULL) {
gdlll_add_element_to_front(...);
}

-------------------------------------------------------------------------------
For using this library as a 'map', etc, your 'data_ptr' must point to a
structure that has a 'key' member and a 'value' member.

struct mymap
{
char *key;
int value;
};

data_ptr = malloc(sizeof(mymap));
data_ptr->key = malloc(10);
strncpy(data_ptr->key, "abcd", 10);
data_ptr->key[4] = 0;
data_ptr->value = 20;
gdlll_add_element_to_front(gdllc_ptr, data_ptr, sizeof(mymap));
-------------------------------------------------------------------------------

------------------------------------
generic_doubly_linked_list_library.h
------------------------------------


/*
* License: This file has been released under APACHE LICENSE, VERSION 2.0
* The license details can be found here:
* https://www.apache.org/licenses/LICENSE-2.0
*/

/*
* Author: Amit Choudhary
* Email: amitchoudhary0523 AT gmail DOT com
*/

#ifndef _GENERIC_DOUBLY_LINKED_LIST_LIBRARY_H_
#define _GENERIC_DOUBLY_LINKED_LIST_LIBRARY_H_

// gdlll means generic doubly linked list library.
// gdllc means generic doubly linked list container.
// gdll means generic doubly linked list.

// Everything happened successfully.
#define GDLLL_SUCCESS 0

// 'gdllc_ptr' argument is NULL.
#define GDLLL_GDLLC_PTR_IS_NULL -1

// 'data_ptr' argument is NULL.
#define GDLLL_DATA_PTR_IS_NULL -2

// 'data_size' argument is <= 0.
#define GDLLL_DATA_SIZE_IS_INVALID -3

// There are no elements in the container.
#define GDLLL_CONTAINER_IS_EMPTY -4

// No memory available.
#define GDLLL_NO_MEMORY -5

// Matching element was not found in the list.
#define GDLLL_MATCHING_ELEMENT_NOT_FOUND -6

// The function pointer given by the user for comparing elements is NULL.
#define GDLLL_COMPARE_ELEMENTS_FUNC_PTR_IS_NULL -7

// This is used only for initializing error variables.
#define GDLLL_ERROR_INIT_VALUE -99

struct element
{
void *data_ptr;
long data_size;
struct element *prev;
struct element *next;
};

/*
* The user needs to give a function pointer to compare elements in some
* functions of this library. Below is the signature of the elements comparator
* function.
*
* The return value of this function should be -1 if 'first' is less than the
* 'second', 0 if 'first' is equal to the 'second', and 1 if 'first' is greater
* than the 'second'.
*/
typedef int (*compare_elements_function)(struct element *first,
struct element *second);

struct gdll_container
{
struct element *first;
struct element *last;
long total_number_of_elements;
// This function pointer will be called before freeing 'data_ptr' member of
// the element structure. This will be needed if the user has allocated some
// memory in 'data_ptr' and the user wants to free it before the 'data_ptr'
// member is freed by this library. So, if the user has a need for it then
// the user can give a valid function pointer to call when initializing this
// library (by calling the function 'gdlll_init_gdll_container'). The user
// may also give NULL function pointer if the user doesn't need this
// functionality.
void (*call_function_before_deleting_data)(void *data_ptr, long data_size);
};

// This function doesn't check the validity of its arguments. It is the
// responsibility of the calling function to check the arguments it is passing
// to this function.
static struct element *gdlll_create_standalone_element(void *data_ptr,
long data_size);

// This function doesn't check the validity of its arguments. It is the
// responsibility of the calling function to check the arguments it is passing
// to this function. This function just removes the element from the list,
// it doesn't decrement total_number_of_elements by 1. Decrementing has to be
// done in the calling function. This function should not be called if the
// number of elements in the container is 0. The calling function should first
// check whether the number of elements in the container is 0 or not.
static void gdlll_remove_element_from_list(struct gdll_container *gdllc_ptr,
struct element *elem_ptr);

// This function doesn't check the validity of its arguments. It is the
// responsibility of the calling function to check the arguments it is passing
// to this function. This function just inserts the element in the list at the
// appropriate place, it doesn't increment total_number_of_elements by 1.
// Incrementing has to be done in the calling function. This function should not
// be called if the number of elements in the container is 0. The calling
// function should first check whether the number of elements in the container
// is 0 or not.
static void insert_element_before_element(struct gdll_container *gdllc_ptr,
struct element *elem_to_insert_ptr,
struct element *elem_before_which_to_insert_ptr);

struct gdll_container *gdlll_init_gdll_container(
void *function_ptr_to_call_before_deleting_data);

// If gdllc_ptr is NULL, then this function returns 0
long gdlll_get_total_number_of_elements_in_gdll_container(
struct gdll_container *gdllc_ptr);

int gdlll_add_element_to_front(struct gdll_container *gdllc_ptr, void *data_ptr,
long data_size);

int gdlll_add_element_to_back(struct gdll_container *gdllc_ptr, void *data_ptr,
long data_size);

int gdlll_add_element_sorted_ascending(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func);

int gdlll_add_element_sorted_descending(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func);

// All gdlll_get_* functions remove the element from the list and then return
// the element. If you don't want the element to be removed from the list then
// use gdlll_peek_* functions. If there are no elements in the container
// then NULL is returned.
struct element *gdlll_get_front_element(struct gdll_container *gdllc_ptr);

struct element *gdlll_get_last_element(struct gdll_container *gdllc_ptr);

struct element *gdlll_get_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func);

// All gdlll_peek_* functions return the element without removing it from the
// list. If there are no elements in the container then NULL is returned.
struct element *gdlll_peek_front_element(struct gdll_container *gdllc_ptr);

struct element *gdlll_peek_last_element(struct gdll_container *gdllc_ptr);

struct element *gdlll_peek_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func);

int gdlll_replace_data_in_matching_element(struct gdll_container *gdllc_ptr,
void *old_data_ptr, long old_data_size,
void *new_data_ptr, long new_data_size,
compare_elements_function comp_func);

void gdlll_delete_front_element(struct gdll_container *gdllc_ptr);

void gdlll_delete_last_element(struct gdll_container *gdllc_ptr);

void gdlll_delete_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func);

void gdlll_delete_standalone_element(struct gdll_container *gdllc_ptr,
struct element *element_to_delete);

void gdlll_delete_all_elements_in_gdll_container(
struct gdll_container *gdllc_ptr);

void gdlll_delete_gdll_container(struct gdll_container *gdllc_ptr);

#endif


------------------------------------
generic_doubly_linked_list_library.c
------------------------------------


/*
* License: This file has been released under APACHE LICENSE, VERSION 2.0
* The license details can be found here:
* https://www.apache.org/licenses/LICENSE-2.0
*/

/*
* Author: Amit Choudhary
* Email: amitchoudhary0523 AT gmail DOT com
*/

#include "generic_doubly_linked_list_library.h"

#include <stdlib.h>
#include <string.h>

static struct element *gdlll_create_standalone_element(void *data_ptr,
long data_size)
{
struct element *elem_ptr = NULL;

elem_ptr = malloc(sizeof(*elem_ptr));
if (!elem_ptr) {
return NULL;
}

elem_ptr->data_ptr = malloc((size_t)(data_size));
if (!(elem_ptr->data_ptr)) {
free(elem_ptr);
return NULL;
}

memmove(elem_ptr->data_ptr, data_ptr, (size_t)(data_size));
elem_ptr->data_size = data_size;

elem_ptr->prev = NULL;
elem_ptr->next = NULL;

return elem_ptr;

} // end of gdlll_create_standalone_element() function

static void gdlll_remove_element_from_list(struct gdll_container *gdllc_ptr,
struct element *elem_ptr)
{

if (elem_ptr == gdllc_ptr->first) {
gdllc_ptr->first = elem_ptr->next;
if (gdllc_ptr->first == NULL) {
gdllc_ptr->last = NULL;
} else {
gdllc_ptr->first->prev = NULL;
}
} else if (elem_ptr == gdllc_ptr->last) {
gdllc_ptr->last = elem_ptr->prev;
if (gdllc_ptr->last == NULL) {
gdllc_ptr->first = NULL;
} else {
gdllc_ptr->last->next = NULL;
}
} else {
elem_ptr->prev->next = elem_ptr->next;
elem_ptr->next->prev = elem_ptr->prev;
}

elem_ptr->prev = NULL;
elem_ptr->next = NULL;

} // end of gdlll_remove_element_from_list() function

static void insert_element_before_element(struct gdll_container *gdllc_ptr,
struct element *elem_to_insert_ptr,
struct element *elem_before_which_to_insert_ptr)
{

if (elem_before_which_to_insert_ptr == NULL) {

// add elem_to_insert_ptr to back
gdllc_ptr->last->next = elem_to_insert_ptr;
elem_to_insert_ptr->prev = gdllc_ptr->last;
gdllc_ptr->last = elem_to_insert_ptr;

} else if (elem_before_which_to_insert_ptr == gdllc_ptr->first) {

// add elem_to_insert_ptr to front
elem_to_insert_ptr->next = gdllc_ptr->first;
elem_to_insert_ptr->next->prev = elem_to_insert_ptr;
gdllc_ptr->first = elem_to_insert_ptr;

} else {

// insert elem_to_insert_ptr before elem_before_which_to_insert_ptr
elem_to_insert_ptr->next = elem_before_which_to_insert_ptr;
elem_to_insert_ptr->prev = elem_before_which_to_insert_ptr->prev;
elem_before_which_to_insert_ptr->prev = elem_to_insert_ptr;
elem_to_insert_ptr->prev->next = elem_to_insert_ptr;

}

} // end of insert_element_before_element() function

struct gdll_container *gdlll_init_gdll_container(
void *function_ptr_to_call_before_deleting_data)
{

struct gdll_container *gdllc_ptr = malloc(sizeof(*gdllc_ptr));

if (!gdllc_ptr)
return NULL;

gdllc_ptr->first = NULL;
gdllc_ptr->last = NULL;
gdllc_ptr->total_number_of_elements = 0;
gdllc_ptr->call_function_before_deleting_data =
function_ptr_to_call_before_deleting_data;

return gdllc_ptr;

} // end of gdlll_init_gdll_container() function

long gdlll_get_total_number_of_elements_in_gdll_container(
struct gdll_container *gdllc_ptr)
{

if (!gdllc_ptr) {
return 0;
}

return (gdllc_ptr->total_number_of_elements);

} // end of gdlll_get_total_number_of_elements_in_gdll_container() function

int gdlll_add_element_to_front(struct gdll_container *gdllc_ptr, void *data_ptr,
long data_size)
{

struct element *elem_ptr = NULL;

if (!gdllc_ptr) {
return GDLLL_GDLLC_PTR_IS_NULL;
}

if (!data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

elem_ptr = gdlll_create_standalone_element(data_ptr, data_size);

if (!elem_ptr) {
return GDLLL_NO_MEMORY;
}

if (gdllc_ptr->first == NULL) {
gdllc_ptr->first = elem_ptr;
gdllc_ptr->last = elem_ptr;
} else {
elem_ptr->next = gdllc_ptr->first;
elem_ptr->next->prev = elem_ptr;
gdllc_ptr->first = elem_ptr;
}

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements + 1;

return GDLLL_SUCCESS;

} // end of gdlll_add_element_to_front() function

int gdlll_add_element_to_back(struct gdll_container *gdllc_ptr, void *data_ptr,
long data_size)
{

struct element *elem_ptr = NULL;

if (!gdllc_ptr) {
return GDLLL_GDLLC_PTR_IS_NULL;
}

if (!data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

elem_ptr = gdlll_create_standalone_element(data_ptr, data_size);

if (!elem_ptr) {
return GDLLL_NO_MEMORY;
}

if (gdllc_ptr->first == NULL) {
gdllc_ptr->first = elem_ptr;
gdllc_ptr->last = elem_ptr;
} else {
gdllc_ptr->last->next = elem_ptr;
elem_ptr->prev = gdllc_ptr->last;
gdllc_ptr->last = elem_ptr;
}

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements + 1;

return GDLLL_SUCCESS;

} // end of gdlll_add_element_to_back() function

int gdlll_add_element_sorted_ascending(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func)
{

struct element *elem_ptr = NULL;

if (!gdllc_ptr) {
return GDLLL_GDLLC_PTR_IS_NULL;
}

if (!data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

if (!comp_func) {
return GDLLL_COMPARE_ELEMENTS_FUNC_PTR_IS_NULL;
}

elem_ptr = gdlll_create_standalone_element(data_ptr, data_size);

if (!elem_ptr) {
return GDLLL_NO_MEMORY;
}

if (gdllc_ptr->first == NULL) {
gdllc_ptr->first = elem_ptr;
gdllc_ptr->last = elem_ptr;
} else {
struct element *temp = gdllc_ptr->first;
while ((temp) && (comp_func(elem_ptr, temp) > 0)) {
temp = temp->next;
}
// insert elem_ptr before temp
insert_element_before_element(gdllc_ptr, elem_ptr, temp);
}

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements + 1;

return GDLLL_SUCCESS;

} // end of gdlll_add_element_sorted_ascending() function

int gdlll_add_element_sorted_descending(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func)
{

struct element *elem_ptr = NULL;

if (!gdllc_ptr) {
return GDLLL_GDLLC_PTR_IS_NULL;
}

if (!data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

if (!comp_func) {
return GDLLL_COMPARE_ELEMENTS_FUNC_PTR_IS_NULL;
}

elem_ptr = gdlll_create_standalone_element(data_ptr, data_size);

if (!elem_ptr) {
return GDLLL_NO_MEMORY;
}

if (gdllc_ptr->first == NULL) {
gdllc_ptr->first = elem_ptr;
gdllc_ptr->last = elem_ptr;
} else {
struct element *temp = gdllc_ptr->first;
while ((temp) && (comp_func(elem_ptr, temp) < 0)) {
temp = temp->next;
}
// insert elem_ptr before temp
insert_element_before_element(gdllc_ptr, elem_ptr, temp);
}

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements + 1;

return GDLLL_SUCCESS;

} // end of gdlll_add_element_sorted_descending() function

struct element *gdlll_get_front_element(struct gdll_container *gdllc_ptr)
{

struct element *temp = NULL;

if (!gdllc_ptr) {
return NULL;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return NULL;
}

temp = gdllc_ptr->first;

gdlll_remove_element_from_list(gdllc_ptr, gdllc_ptr->first);

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;

return temp;

} // end of gdlll_get_front_element() function

struct element *gdlll_get_last_element(struct gdll_container *gdllc_ptr)
{

struct element *temp = NULL;

if (!gdllc_ptr) {
return NULL;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return NULL;
}

temp = gdllc_ptr->last;

gdlll_remove_element_from_list(gdllc_ptr, gdllc_ptr->last);

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;

return temp;

} // end of gdlll_get_last_element() function

struct element *gdlll_get_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func)
{

struct element *matching_elem_ptr = NULL;

if (!gdllc_ptr) {
return NULL;
}

if (!data_ptr) {
return NULL;
}

if (data_size <= 0) {
return NULL;
}

if (!comp_func) {
return NULL;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return NULL;
}

matching_elem_ptr = gdlll_peek_matching_element(gdllc_ptr, data_ptr,
data_size, comp_func);

if (matching_elem_ptr == NULL) {
return NULL;
}

gdlll_remove_element_from_list(gdllc_ptr, matching_elem_ptr);

gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;

return matching_elem_ptr;

} // end of gdlll_get_matching_element() function

struct element *gdlll_peek_front_element(struct gdll_container *gdllc_ptr)
{

if (!gdllc_ptr) {
return NULL;
}

return (gdllc_ptr->first);

} // end of gdlll_peek_front_element() function

struct element *gdlll_peek_last_element(struct gdll_container *gdllc_ptr)
{

if (!gdllc_ptr) {
return NULL;
}

return (gdllc_ptr->last);

} // end of gdlll_peek_last_element() function

struct element *gdlll_peek_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func)
{

struct element *elem_ptr = NULL;
struct element *temp = NULL;

if (!gdllc_ptr) {
return NULL;
}

if (!data_ptr) {
return NULL;
}

if (data_size <= 0) {
return NULL;
}

if (!comp_func) {
return NULL;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return NULL;
}

elem_ptr = gdlll_create_standalone_element(data_ptr, data_size);

if (!elem_ptr) {
return NULL;
}

temp = gdllc_ptr->first;

while ((temp) && (comp_func(elem_ptr, temp) != 0)) {
temp = temp->next;
}

gdlll_delete_standalone_element(gdllc_ptr, elem_ptr);

return temp;

} // end of gdlll_peek_matching_element() function

int gdlll_replace_data_in_matching_element(struct gdll_container *gdllc_ptr,
void *old_data_ptr, long old_data_size,
void *new_data_ptr, long new_data_size,
compare_elements_function comp_func)
{

struct element *matching_elem_ptr = NULL;
void *temp_data_ptr = NULL;

if (!gdllc_ptr) {
return GDLLL_GDLLC_PTR_IS_NULL;
}

if (!old_data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (old_data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

if (!new_data_ptr) {
return GDLLL_DATA_PTR_IS_NULL;
}

if (new_data_size <= 0) {
return GDLLL_DATA_SIZE_IS_INVALID;
}

if (!comp_func) {
return GDLLL_COMPARE_ELEMENTS_FUNC_PTR_IS_NULL;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return GDLLL_CONTAINER_IS_EMPTY;
}

matching_elem_ptr = gdlll_peek_matching_element(gdllc_ptr, old_data_ptr,
old_data_size, comp_func);

if (matching_elem_ptr == NULL) {
return GDLLL_MATCHING_ELEMENT_NOT_FOUND;
}

temp_data_ptr = malloc((size_t)(new_data_size));
if (!temp_data_ptr) {
return GDLLL_NO_MEMORY;
}

// Now, call the call_function_before_deleting_data() for 'data_ptr' of the
// matching element and then free the 'data_ptr' of the matching element
if (gdllc_ptr->call_function_before_deleting_data) {
gdllc_ptr->call_function_before_deleting_data(
matching_elem_ptr->data_ptr, matching_elem_ptr->data_size);
}
free(matching_elem_ptr->data_ptr);

matching_elem_ptr->data_ptr = temp_data_ptr;
memmove(matching_elem_ptr->data_ptr, new_data_ptr, (size_t)(new_data_size));
matching_elem_ptr->data_size = new_data_size;

return GDLLL_SUCCESS;

} // end of gdlll_replace_data_in_matching_element() function

void gdlll_delete_front_element(struct gdll_container *gdllc_ptr)
{

struct element *temp_elem_ptr = NULL;

if (!gdllc_ptr) {
return;
}

temp_elem_ptr = gdllc_ptr->first;

if (temp_elem_ptr) {
gdlll_remove_element_from_list(gdllc_ptr, temp_elem_ptr);
gdlll_delete_standalone_element(gdllc_ptr, temp_elem_ptr);
gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;
}

return;

} // end of gdlll_delete_front_element() function

void gdlll_delete_last_element(struct gdll_container *gdllc_ptr)
{

struct element *temp_elem_ptr = NULL;

if (!gdllc_ptr) {
return;
}

temp_elem_ptr = gdllc_ptr->last;

if (temp_elem_ptr) {
gdlll_remove_element_from_list(gdllc_ptr, temp_elem_ptr);
gdlll_delete_standalone_element(gdllc_ptr, temp_elem_ptr);
gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;
}

return;

} // end of gdlll_delete_last_element() function

void gdlll_delete_matching_element(struct gdll_container *gdllc_ptr,
void *data_ptr, long data_size,
compare_elements_function comp_func)
{

struct element *matching_elem_ptr = NULL;

if (!gdllc_ptr) {
return;
}

if (!data_ptr) {
return;
}

if (data_size <= 0) {
return;
}

if (!comp_func) {
return;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return;
}

matching_elem_ptr = gdlll_peek_matching_element(gdllc_ptr, data_ptr,
data_size, comp_func);

if (matching_elem_ptr == NULL) {
return;
}

gdlll_remove_element_from_list(gdllc_ptr, matching_elem_ptr);
gdlll_delete_standalone_element(gdllc_ptr, matching_elem_ptr);
gdllc_ptr->total_number_of_elements =
gdllc_ptr->total_number_of_elements - 1;

return;

} // end of gdlll_delete_matching_element() function

void gdlll_delete_standalone_element(struct gdll_container *gdllc_ptr,
struct element *element_to_delete)
{

if (!gdllc_ptr) {
return;
}

if (!element_to_delete) {
return;
}

// Call the call_function_before_deleting_data() for 'data_ptr' of
// 'element_to_delete' and then free the 'data_ptr' of 'element_to_delete'.
// Then free the 'element_to_delete'.
if (gdllc_ptr->call_function_before_deleting_data) {
gdllc_ptr->call_function_before_deleting_data(
element_to_delete->data_ptr, element_to_delete->data_size);
}

free(element_to_delete->data_ptr);

free(element_to_delete);

return;

} // end of gdlll_delete_standalone_element() function

void gdlll_delete_all_elements_in_gdll_container(
struct gdll_container *gdllc_ptr)
{

struct element *temp_elem_ptr = NULL;

if (!gdllc_ptr) {
return;
}

if (gdllc_ptr->total_number_of_elements == 0) {
return;
}

temp_elem_ptr = gdllc_ptr->first;

while (temp_elem_ptr) {
gdlll_delete_front_element(gdllc_ptr);
temp_elem_ptr = gdllc_ptr->first;
}

return;

} // end of gdlll_delete_all_elements_in_gdll_container() function

void gdlll_delete_gdll_container(struct gdll_container *gdllc_ptr)
{

if (!gdllc_ptr) {
return;
}

gdlll_delete_all_elements_in_gdll_container(gdllc_ptr);

free(gdllc_ptr);

return;

} // end of gdlll_delete_gdll_container() function