RayList Project Documentation

RayList Library

RayList is a C library that implements a dynamic linked list supporting multiple data types, with various functions for list manipulation. It allows you to manage lists, stacks, and queues efficiently with support for custom data types and asynchronous task execution. raylist also contains magic macros to solve list C problems like (RLSetObject , RLDefer , ...)

Features

  • Dynamic linked list supporting multiple data types
  • Functions for list manipulation (append, insert, delete, search, filter, map, etc.)
  • Support for stack and queue data structures
  • Asynchronous task execution using threads
  • Customizable memory allocation functions

Installation

To use RayList in your project, include the raylist.h header file and link against the compiled library. Ensure you have the required dependencies installed. and define macro LIST_C to act like C file because the library is like stb stile header only library

// should include stdarg.h
#include <stdarg.h>
// enable raylist implementation
#define LIST_C
#include "raylist.h"
                

Usage

Here is a basic example of how to use RayList:

#include<stdarg.h>
#include<stdio.h>

#define LIST_C
#include "raylist.h"

int main() {
    RLList my_list = List(0);  // Initialize an empty list
    my_list.List_Append(RL_INT, (void*)&(int){10});
    my_list.List_Append(RL_STR, "Hello, World!");
    my_list.List_Print();
    return 0;
}
                

List

list contains methods like in python and it's own preffix Example :


// this macro enable list preffix
#define USING_LIST

#define LIST_C
#include "raylist.h"

int main() {
    RLList my_list = List(0);

    // after define USING_LIST macro
    my_list.Filter(callback, RL_INT); // now you can use method like this
    my_list.Print();
    return 0;
}
                

List Types

types can used in list , stack , queue this type helps raylist for memory managment


// this macro enable list preffix
#define USING_LIST

#define LIST_C
#include "raylist.h"

int main() {
	// RL_INT	type int
	// RL_STR	type str (char*)
	// RL_VOIDPTR	type void ptr (void*)
	// RL_FLT	type float
	// RL_BOOL	type boolean
	// RL_CHR	type char

	// RL_STRFUNC   type function return string
	// RL_CHARFUNC	type function return char
	// RL_INTFUNC	type function return int
	// RL_VOIDFUNC	type function return void

    return 0;
}
                

List

List return RLList interface which implements all list method
list also accept va_list arguments to add data dynamicly


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3, // 3 is number of the data we add to the list
				RL_STR , "Hello", // <type> , <data>
				RL_BOOL , true,	  //   .
				RL_STR , "world"  //   .
	);
    return 0;
}
                

List RLAppend

RLAppend macro works like append method but use generics
macro can detecte type of the data , without casting to void*
work with int , float and char only


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(0);
	RLAppend(RL_INT , 1);
	RLAppend(RL_INT , 2);
	RLAppend(RL_INT , 3);
	RLAppend(RL_CHR , 'e');
	RLAppend(RL_CHR , 'h');
	RLAppend(RL_FLT , 3.14f);
	RLAppend(RL_FLT , 2.73f);
    return 0;
}
                

List Append

append method takes type and data


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(0);
	// U can call method append like this if you defined USING_LIST macro
	mylist.Append(RL_STR , "Hello");
	mylist.Append(RL_STR , "World");
	// if not
	mylist.List_Append(RL_STR , "Hello");
	mylist.List_Append(RL_STR , "World");

    return 0;
}
                

List Insert

insert method takes index poition to add data , type and data


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(4,
		RL_STR , "Hello",
		RL_STR , "World",
		RL_STR , "rayden",
		RL_STR , "foo"

	);
	mylist.List_Insert(2 , RL_STR , "bar"); // insert bar str in index 2
	mylist.List_Insert(0 , RL_STR , "baz"); // insert baz str in index 0

    return 0;
}
                

List Delete

delete method takes int index the position of the data we want to delete


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(2,
		RL_STR , "Hello",
		RL_STR , "World"

	);

	//  Hello data will  be delete it
	mylist.Del_Index(0);

    return 0;
}
                

List Get

get method takes int index the position of the data we want to get


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3,
		RL_STR , "World",
		RL_STR , "foo",
		RL_STR , "bar"

	);
	// function will return foo
	puts((char*)mylist.List_Get(1));

    return 0;
}
                

List Reverse

reverse method take no argument and return nothing
reverse will reverse the list


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3,
		RL_STR , "World",
		RL_STR , "foo",
		RL_STR , "bar"

	);
	mylist.List_Reverse(); // list reverse

    return 0;
}
                

List Print

print method take no argument and return nothing
print method will print the data in list like python3 format


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3,
		RL_STR , "World",
		RL_STR , "foo",
		RL_STR , "bar"

	);
	mylist.List_Print();

    return 0;
}
                

List Error Handle

get_error method take no argument and return string error , and NULL if not
while you working with raylist , library detecte errors , so after any operation
check if method return NULL or not ,
if return value is not NULL log the error


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3,
		RL_STR , "World",
		RL_STR , "foo",
		RL_STR , "bar"

	);
	char* err = mylist.List_Get_Error();
	if(err != NULL){
		fprintf(stderr , "[ERROR] %s" , err);
	}

    return 0;
}
                

List length

len method take no argument and return how many data in list


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(3,
		RL_STR , "World",
		RL_STR , "foo",
		RL_STR , "bar"

	);
	int len = mylist.List_Len(); // len == 3

    return 0;
}
                

List Call Functions Sync

exec_sync method take index of the function , and the data (data passed to calling function argument) , and the flag
if index is less than 0 or bigger than length of list will execute all functions
Exec_Flag :
OUTT the return value from called function will returned in Exec_Sync method
OUTT flag is not enabled if index parameter in Exec_Sync was out of range
INPLACE the return value will replaced function callback index
the void function is not replaced
ADDED the function return value will added to the list


#define LIST_C
#include "raylist.h"

void foo(void){
	printf("foo");
}

char* myname(char* name) {
	return name;
}

int main() {
	// Example Append
	RLList mylist = List(2,
		RL_VOIDFUNC , foo,
		RL_STRFUNC , myname

	);
	myname.List_Exec_Sync(0 , NULL , OUTT); // void return type function don't care about flag
	myname.List_Exec_Sync(1 , "rayden" , ADDED);

    return 0;
}
                

List Call Functions Async

exec_async method take index of the function , and the data (data passed to calling function argument)
if index is less than 0 or bigger than length of list will execute all functions
this function will call functions Asynchronously , this method call function iin separite thread and return interface
interface :
thread_id -> thread handler of the calling function
Kill :
* Kill function
* for killing the thread
Wait :
* Wait function
* function waits for the thread specified by thread to terminate
- both of these method takes handle thread in parameter
this method work with specific macro called RLTestCancel this macro should be called inside target function Kill method can detecte the function and kill thread


#define LIST_C
#include "raylist.h"

void limitloop(void)
{
	for(int i = 0 ; i < 20 ; i++){
		puts("Test");
		sleep(1);
		RLTestCancel();
	}
}

void limitloop2(void)
{
	for(int i = 0 ; i < 20 ; i++){
		puts("Hello");
		sleep(1);
		RLTestCancel();
	}
}

int main() {
	// Example Append
	RLList mylist = List(2,
		RL_VOIDFUNC , limitloop,
		RL_VOIDFUNC , limitloop2

	);
	IfaceThread tr = my_list.Exec_Async(3 , NULL);
	IfaceThread rt = my_list.Exec_Async(4 , NULL);

	RLUNUSED(tr); // unused variable

	// functions now works in the same time
	rt.Kill(tr.thread); // killing functionof tr interface

    return 0;
}
                

List Filter

filter method used to filter the list According to condition in callback function except void* parameter and return boolean
filter accept function call back , type for filter , and Filter_Flag
Filter_Flag :
ALL // (filtring all list)
ONLY // (filtring only type)


#define LIST_C
#include "raylist.h"


LBOOL for_filter(void* data)
{
	// filtring odd numbers
	if(*(int*)data % 2 != 0)	return true;
	return false;
}

int main() {
	// Example Append
	RLList mylist = List(0);
	for(int i = 0 ; i < 10 ; i++)
	{
		RLAppend(RL_INT , i);
	}
	mylist.List_Filter(for_filter , RL_INT , ONLY);
					       // now our list contains odd numbers
					       // if flag was ALL other types will be delete it

    return 0;
}
                

List Map

map method used to apply changes to the elemetn's in the list According to condition ,in callback function except void* parameter and return void*


#define LIST_C
#include "raylist.h"


void* for_map(void* data)
{
	if(*(int*)data % 2 != 0){
		// if data number is odd , change it to 100
		*(int*)data = 100;
	}
	return data;
}

int main() {
	// Example Append
	RLList mylist = List(0);
	for(int i = 0 ; i < 10 ; i++)
	{
		RLAppend(RL_INT , i);
	}
	mylist.List_Map(for_map , RL_INT);
					       // now all odd numbers is equale to 100

    return 0;
}
                

List Clear

clear method will free's all allocated data in list


#define LIST_C
#include "raylist.h"

int main() {
	// Example Append
	RLList mylist = List(0);
	for(int i = 0 ; i < 10 ; i++)
	{
		RLAppend(RL_INT , i);
	}
	mylist.List_Clear(); // len list == 0

    return 0;
}
                

Queue and Stack

both of thoes functions implements RLCollections interface this functions accept buffer limiter (can fix the size) and also you can put Buf_Disable parameter to make it dynamic RLCollections has macro RLPush this macro is generic like RLappend macro magic macros also work for this interface

RLCollections Interface

RLCollections Example :


#define LIST_C
#include "raylist.h"

int main() {
	// RLCollections interface
	/*
	 *	Max_Buffer() return true if buffer equal to fixed buffer else false
	 * */

	// 	LBOOL Max_Buffer(void);

	/*
	 *	return true if stack is empty else false
	 * */
	//	LBOOL Is_Empty(void);
	/*
	 *  return String if the error is set true (status > 0)
	 * */
	//	string Get_Error(void);
	/*
	 *	Push function will take the data and stored to the __list__ global variable
	 *
	 * 	Push(
	 *		Type : the data type
	 *		void*: data pointer point address of stored data
	 * 	)
	 *
	 *	NOTE : the append method works like push in stack algorithm
	 *
	 *	Example :
	 *		my_list.Push(RL_STR , "Hello World");
	 *
	 * */
	//	void Push(Type type, void* data);
	/*
	 *	Peek function return last value of the Stack (Stack)
	 *	Example :
	 *		void* value = my_list.Stack_Peek();
	 * */
	//	void* Peek(void);
	/*
	 *	Stack_Pop function will pop the last value from the list
	 *
	 *	Example :
	 *		void* value = my_list.Stack_Pop();
	 * */
	//	void* Pop(void);

	// clear Stack
	//	void Clear(void);


	RLCollections stack = Stack(Buf_Disable);

	RLDefer(stack.Clear); // clear will be called when function ends

	return 0;
}