forked from Telodendria/Telodendria
Jordan Bancino
461357b526
This makes it easier to build Cytoplasm as a component of another program (for example, Telodendria), or as a standalone system library.
188 lines
6.7 KiB
C
188 lines
6.7 KiB
C
/*
|
|
* Copyright (C) 2022-2024 Jordan Bancino <@jordan:bancino.net>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation files
|
|
* (the "Software"), to deal in the Software without restriction,
|
|
* including without limitation the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#ifndef CYTOPLASM_ARRAY_H
|
|
#define CYTOPLASM_ARRAY_H
|
|
|
|
/***
|
|
* @Nm Array
|
|
* @Nd A simple dynamic array data structure.
|
|
* @Dd November 24 2022
|
|
* @Xr HashMap Queue
|
|
*
|
|
* These functions implement a simple array data structure that is
|
|
* automatically resized as necessary when new values are added. This
|
|
* implementation does not actually store the values of the items in it;
|
|
* it only stores pointers to the data. As such, you will still have to
|
|
* manually maintain all your data. The advantage of this is that these
|
|
* functions don't have to copy data, and thus don't care how big the
|
|
* data is. Furthermore, arbitrary data can be stored in the array.
|
|
* .Pp
|
|
* This array implementation is optimized for storage space and
|
|
* appending. Deletions are expensive in that all the items of the list
|
|
* above a deletion are moved down to fill the hole where the deletion
|
|
* occurred. Insertions are also expensive in that all the elements
|
|
* above the given index must be shifted up to make room for the new
|
|
* element.
|
|
* .Pp
|
|
* Due to these design choices, this array implementation is best
|
|
* suited to linear writing, and then linear or random reading.
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
|
|
/**
|
|
* The functions in this API operate on an array structure which is
|
|
* opaque to the caller.
|
|
*/
|
|
typedef struct Array Array;
|
|
|
|
/**
|
|
* Allocate a new array. This function returns a pointer that can be
|
|
* used with the other functions in this API, or NULL if there was an
|
|
* error allocating memory for the array.
|
|
*/
|
|
extern Array *ArrayCreate(void);
|
|
|
|
/**
|
|
* Deallocate an array. Note that this function does not free any of
|
|
* the values stored in the array; it is the caller's job to manage the
|
|
* memory for each item. Typically, the caller would iterate over all
|
|
* the items in the array and free them before freeing the array.
|
|
*/
|
|
extern void ArrayFree(Array *);
|
|
|
|
/**
|
|
* Get the size, in number of elements, of the given array.
|
|
*/
|
|
extern size_t ArraySize(Array *);
|
|
|
|
/**
|
|
* Get the element at the specified index from the specified array.
|
|
* This function will return NULL if the array is NULL, or the index
|
|
* is out of bounds. Otherwise, it will return a pointer to a value
|
|
* put into the array using
|
|
* .Fn ArrayInsert
|
|
* or
|
|
* .Fn ArraySet .
|
|
*/
|
|
extern void *ArrayGet(Array *, size_t);
|
|
|
|
/**
|
|
* Insert the specified element at the specified index in the specified
|
|
* array. This function will shift the element currently at that index,
|
|
* and any elements after it before inserting the given element.
|
|
* .Pp
|
|
* This function returns a boolean value indicating whether or not it
|
|
* suceeded.
|
|
*/
|
|
extern bool ArrayInsert(Array *, size_t, void *);
|
|
|
|
/**
|
|
* Set the value at the specified index in the specified array to the
|
|
* specified value. This function will return the old value at that
|
|
* index, if any.
|
|
*/
|
|
extern void *ArraySet(Array *, size_t, void *);
|
|
|
|
/**
|
|
* Append the specified element to the end of the specified array. This
|
|
* function uses
|
|
* .Fn ArrayInsert
|
|
* under the hood to insert an element at the end. It thus has the same
|
|
* return value as
|
|
* .Fn ArrayInsert .
|
|
*/
|
|
extern bool ArrayAdd(Array *, void *);
|
|
|
|
/**
|
|
* Remove the element at the specified index from the specified array.
|
|
* This function returns the element removed, if any.
|
|
*/
|
|
extern void *ArrayDelete(Array *, size_t);
|
|
|
|
/**
|
|
* Sort the specified array using the specified sort function. The
|
|
* sort function compares two elements. It takes two void pointers as
|
|
* parameters, and returns an integer. The return value indicates to
|
|
* the sorting algorithm how the elements relate to each other. A
|
|
* return value of 0 indicates that the elements are identical. A
|
|
* return value greater than 0 indicates that the first item is
|
|
* ``bigger'' than the second item and should thus appear after it in
|
|
* the array. A return value less than 0 indicates the opposite: the
|
|
* second element should appear after the first in the array.
|
|
*/
|
|
extern void ArraySort(Array *, int (*) (void *, void *));
|
|
|
|
/**
|
|
* Remove all duplicates from an array by using the given comparison
|
|
* function to sort the array, then remove matching values. This
|
|
* function returns a new array with all duplicates removed. The
|
|
* original array is unaffected. Note that arrays only store pointers
|
|
* to values, usually values on the heap. Thus, it is possible to lose
|
|
* pointers to duplicate values and have them leak.
|
|
* .P
|
|
* This is a relatively expensive operation. The array must first be
|
|
* duplicated. Then it is sorted, then it is iterated from beginning
|
|
* to end to remove duplicate entries. Note that the comparison
|
|
* function is executed on each element at least twice.
|
|
*/
|
|
extern Array *ArrayUnique(Array *, int (*) (void *, void *));
|
|
|
|
|
|
/**
|
|
* Reverses the order of all elements in the array into a new array on
|
|
* the heap, to be freed using
|
|
* .Fn ArrayFree .
|
|
*/
|
|
extern Array *ArrayReverse(Array *);
|
|
|
|
/**
|
|
* If possible, reduce the amount of memory allocated to this array
|
|
* by calling
|
|
* .Fn Realloc
|
|
* on the internal structure to perfectly fit the elements in the
|
|
* array. This function is intended to be used by functions that return
|
|
* relatively read-only arrays that will be long-lived.
|
|
*/
|
|
extern bool ArrayTrim(Array *);
|
|
|
|
/**
|
|
* Convert a variadic arguments list into an Array. In most cases, the
|
|
* Array API is much easier to work with than
|
|
* .Fn va_arg
|
|
* and friends.
|
|
*/
|
|
extern Array *ArrayFromVarArgs(size_t, va_list);
|
|
|
|
/**
|
|
* Duplicate an existing array. Note that arrays only hold pointers to
|
|
* their data, not the data itself, so the duplicated array will point
|
|
* to the same places in memory as the original array.
|
|
*/
|
|
extern Array *ArrayDuplicate(Array *);
|
|
|
|
#endif /* CYTOPLASM_ARRAY_H */
|