Compare commits

...

5 Commits

Author SHA1 Message Date
35f0d4cc10 Used typedef 2025-06-06 10:02:35 -05:00
8fb4ca0749 Using conventions of Makefile and seperate header / code files 2025-06-06 09:34:45 -05:00
6c08c28ae5 Extended Array Library 2025-04-04 01:22:48 -05:00
c23cdb9e1e Added license 2025-03-28 04:39:10 -05:00
065f5db5cf Changed compiler flags 2025-03-28 04:30:07 -05:00
8 changed files with 302 additions and 122 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
test test_array

26
LICENSE Normal file
View File

@ -0,0 +1,26 @@
MIT NON-AI License
Copyright (c) 2025, Seoxi Ryouko
Permission is hereby granted, free of charge, to any person obtaining a copy of the 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 substantial portions of the Software.
In addition, the following restrictions apply:
1. The Software and any modifications made to it may not be used for the purpose of training or improving machine learning algorithms,
including but not limited to artificial intelligence, natural language processing, or data mining. This condition applies to any derivatives,
modifications, or updates based on the Software code. Any usage of the Software in an AI-training dataset is considered a breach of this License.
2. The Software may not be included in any dataset used for training or improving machine learning algorithms,
including but not limited to artificial intelligence, natural language processing, or data mining.
3. Any person or organization found to be in violation of these restrictions will be subject to legal action and may be held liable
for any damages resulting from such use.
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.

5
Makefile Normal file
View File

@ -0,0 +1,5 @@
CC = clang
CFLAGS = -O2 -Wall -Wextra -Wno-c2x-extensions
test_array:
$(CC) $(CFLAGS) -o test_array test_array.c libkeke_array.c
./test_array

175
libkeke_array.c Normal file
View File

@ -0,0 +1,175 @@
#ifndef LIBKEKE_ARRAY
#define LIBKEKE_ARRAY
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "libkeke_utils.h"
#include "libkeke_array.h"
#define ARRAY_GET(array, i) ((array)->content + (array)->type_size * (i))
KekeArray *keke_array_alloc(size_t initial_len, size_t type_size) {
//if(initial_len == 0) initial_len = 1;
KekeArray *array = malloc(sizeof(*array));
array->len = initial_len;
size_t max_len = 1;
while(initial_len >>= 1) max_len <<= 1;
array->type_size = type_size;
array->max_len = max_len;
array->content = malloc(max_len * type_size);
memset(array->content, 0, max_len * type_size);
return array;
}
void keke_array_free(KekeArray *array) {
free(array->content);
free(array);
}
void keke_array_set(KekeArray *array, size_t index, const void *value) {
if(index >= array->max_len) {
array->content = realloc(array->content, (array->max_len << 1) * array->type_size);
memset(array->content + array->max_len * array->type_size, 0, array->max_len * array->type_size);
array->max_len <<= 1;
}
if(index >= array->len) array->len = index + 1;
memcpy(array->content + index * array->type_size, value, array->type_size);
}
void *keke_array_get(KekeArray *array, size_t index) {
if(index >= array->len) return NULL; // is ur fault
return ARRAY_GET(array, index);
}
int keke_array_copy(KekeArray *array, size_t index, void *value) {
if(index >= array->len) return -1; // is ur fault
memcpy(value, ARRAY_GET(array, index), array->type_size);
return 0;
}
void keke_array_set_len(KekeArray *array, size_t new_len) {
if(new_len >= array->max_len) {
size_t new_max_len = 1;
size_t len = new_len;
while(len >>= 1) new_max_len <<= 1;
array->content = realloc(array->content, new_max_len * array->type_size);
memset(array->content + array->max_len * array->type_size, 0, (new_max_len - array->max_len) * array->type_size);
array->max_len <<= 1;
} else if(new_len < array->len) {
memset(array->content + new_len * array->type_size, 0, (array->len - new_len) * array->type_size);
}
array->len = new_len;
}
void keke_array_insert(KekeArray *array, size_t index, const void *value) {
keke_array_set_len(array, array->len + 1);
memmove(array->content + ((index + 1) * array->type_size), array->content + (index * array->type_size), (array->len - index - 1) * array->type_size);
memcpy(array->content + index * array->type_size, value, array->type_size);
}
void keke_array_remove(KekeArray *array, size_t index, void *value) {
keke_array_set_len(array, array->len - 1);
memcpy(value, array->content + index * array->type_size, array->type_size);
memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size);
}
void keke_array_push(KekeArray *array, const void *value) {
keke_array_set(array, array->len, value);
}
void keke_array_pop(KekeArray *array, void *value) {
keke_array_remove(array, array->len - 1, value);
}
void keke_array_delete(KekeArray *array, size_t index) {
keke_array_set_len(array, array->len - 1);
memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size);
}
KekeArray *keke_array_yoink(KekeArray *array, size_t start_index, size_t len) {
if(start_index + len >= array->len) return NULL;
KekeArray *ret = keke_array_alloc(len, array->type_size);
memcpy(ret->content, array->content + start_index * array->type_size, len * array->type_size);
memmove(array->content + start_index * array->type_size, array->content + (start_index + len) * array->type_size, (array->len - len - start_index) * array->type_size);
keke_array_set_len(array, array->len - len);
return ret;
}
int keke_array_insert_data(KekeArray *array, size_t index, void *data, size_t len) {
if(index >= array->len) return -1;
size_t current_len = array->len;
keke_array_set_len(array, current_len + len);
memmove(array->content + (index + len) * array->type_size, array->content + index * array->type_size, (current_len - index) * array->type_size);
memcpy(array->content + index * array->type_size, data, len * array->type_size);
return 0;
}
int keke_array_plop(KekeArray *array, size_t index, KekeArray *array2) {
int ret = keke_array_insert_data(array, index, array2->content, array2->len);
if(ret) return ret;
keke_array_free(array2);
return 0;
}
typedef void (*Foreach_func)(void *, size_t, KekeArray *);
void keke_array_foreach(KekeArray *array, Foreach_func callback) {
for(size_t i = 0; i < array->len; i++) callback(ARRAY_GET(array, i), i, array);
}
KekeArray *keke_array_clone(KekeArray *array) {
KekeArray *ret = malloc(sizeof(*array));
memcpy(ret, array, sizeof(*array));
ret->content = malloc(array->max_len * array->type_size);
memcpy(ret->content, array->content, array->max_len * array->type_size);
return ret;
}
void keke_array_fill(KekeArray *array, const void *value) {
for(size_t i = 0; i < array->len; i++) memcpy(ARRAY_GET(array, i), value, array->type_size);
}
void keke_array_reverse(KekeArray *array) {
for(size_t i = 0; i < array->len / 2; i++) {
keke_swap(ARRAY_GET(array, i), array->content + array->type_size * (array->len - i - 1), array->type_size);
}
}
typedef bool (*Test_func)(void *, size_t, KekeArray *);
bool keke_array_some(KekeArray *array, Test_func test) {
bool ret = false;
for(size_t i = 0; i < array->len; i++) ret = ret || test(ARRAY_GET(array, i), i, array);
return ret;
}
bool keke_array_all(KekeArray *array, Test_func test) {
bool ret = true;
for(size_t i = 0; i < array->len; i++) ret = ret && test(ARRAY_GET(array, i), i, array);
return ret;
}
KekeArray *keke_array_filter(KekeArray *array, Test_func test) {
KekeArray *ret = keke_array_alloc(0, array->type_size);
for(size_t i = 0; i < array->len; i++) {
if(test(ARRAY_GET(array, i), i, array)) {
keke_array_push(ret, ARRAY_GET(array, i));
}
}
return ret;
}
typedef void (*B_func)(void *, void *);
void keke_array_reduce(KekeArray *array, B_func op, void *acc) {
for(size_t i = 0; i < array->len; i++) op(ARRAY_GET(array, i), acc);
}
#undef ARRAY_GET
#endif

View File

@ -2,133 +2,48 @@
#define LIBKEKE_ARRAY #define LIBKEKE_ARRAY
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdint.h>
#include <string.h> #include <stdbool.h>
struct KekeArray { typedef struct {
size_t type_size; size_t type_size;
size_t len; size_t len;
size_t max_len; size_t max_len;
void *content; void *content;
}; } KekeArray;
static void *keke_array_alloc(size_t initial_len, size_t type_size) { KekeArray *keke_array_alloc(size_t initial_len, size_t type_size);
if(initial_len == 0) initial_len = 1; void keke_array_free(KekeArray *array);
struct KekeArray *array = malloc(sizeof(*array));
array->len = initial_len;
size_t max_len = 1;
while(initial_len >>= 1) max_len <<= 1;
array->type_size = type_size; void keke_array_set(KekeArray *array, size_t index, const void *value);
array->max_len = max_len; void *keke_array_get(KekeArray *array, size_t index);
array->content = malloc(max_len * type_size);
memset(array->content, 0, max_len * type_size);
return array;
}
static void keke_array_free(struct KekeArray *array) { int keke_array_copy(KekeArray *array, size_t index, void *value);
free(array->content); void keke_array_set_len(KekeArray *array, size_t new_len);
free(array); void keke_array_insert(KekeArray *array, size_t index, const void *value);
} void keke_array_remove(KekeArray *array, size_t index, void *value);
void keke_array_push(KekeArray *array, const void *value);
void keke_array_pop(KekeArray *array, void *value);
void keke_array_delete(KekeArray *array, size_t index);
KekeArray *keke_array_yoink(KekeArray *array, size_t start_index, size_t len);
int keke_array_insert_data(KekeArray *array, size_t index, void *data, size_t len);
int keke_array_plop(KekeArray *array, size_t index, KekeArray *array2);
static void keke_array_set(struct KekeArray *array, size_t index, const void *value) { typedef void (*Foreach_func)(void *, size_t, KekeArray *);
if(index >= array->max_len) { void keke_array_foreach(KekeArray *array, Foreach_func callback);
array->content = realloc(array->content, (array->max_len << 1) * array->type_size); KekeArray *keke_array_clone(KekeArray *array);
memset(array->content + array->max_len * array->type_size, 0, array->max_len * array->type_size);
array->max_len <<= 1;
}
if(index >= array->len) array->len = index + 1;
memcpy(array->content + index * array->type_size, value, array->type_size);
}
static void *keke_array_get(struct KekeArray *array, size_t index) { void keke_array_fill(KekeArray *array, const void *value);
if(index >= array->len) return NULL; // is ur fault void keke_array_reverse(KekeArray *array);
return array->content + array->type_size * index;
}
static int keke_array_copy(struct KekeArray *array, size_t index, void *value) { typedef bool (*Test_func)(void *, size_t, KekeArray *);
if(index >= array->len) return -1; // is ur fault bool keke_array_some(KekeArray *array, Test_func test);
memcpy(value, array->content + array->type_size * index, array->type_size); bool keke_array_all(KekeArray *array, Test_func test);
return 0;
}
static void keke_array_set_len(struct KekeArray *array, size_t new_len) { KekeArray *keke_array_filter(KekeArray *array, Test_func test);
if(new_len >= array->max_len) {
size_t new_max_len = 1;
size_t len = new_len;
while(len >>= 1) new_max_len <<= 1;
array->content = realloc(array->content, new_max_len * array->type_size);
memset(array->content + array->max_len * array->type_size, 0, (new_max_len - array->max_len) * array->type_size);
array->max_len <<= 1;
} else if(new_len < array->len) {
memset(array->content + new_len * array->type_size, 0, (array->len - new_len) * array->type_size);
}
array->len = new_len;
}
static void keke_array_insert(struct KekeArray *array, size_t index, const void *value) { typedef void (*B_func)(void *, void *);
keke_array_set_len(array, array->len + 1); void keke_array_reduce(KekeArray *array, B_func op, void *acc);
memmove(array->content + ((index + 1) * array->type_size), array->content + (index * array->type_size), (array->len - index - 1) * array->type_size);
memcpy(array->content + index * array->type_size, value, array->type_size);
}
static void keke_array_remove(struct KekeArray *array, size_t index, void *value) {
keke_array_set_len(array, array->len - 1);
memcpy(value, array->content + index * array->type_size, array->type_size);
memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size);
}
static void keke_array_push(struct KekeArray *array, const void *value) {
keke_array_set(array, array->len, value);
}
static void keke_array_pop(struct KekeArray *array, void *value) {
keke_array_remove(array, array->len - 1, value);
}
static void keke_array_delete(struct KekeArray *array, size_t index) {
keke_array_set_len(array, array->len - 1);
memmove(array->content + (index * array->type_size), array->content + ((index + 1) * array->type_size), (array->len - index + 1) * array->type_size);
}
static struct KekeArray *keke_array_yoink(struct KekeArray *array, size_t start_index, size_t len) {
if(start_index + len >= array->len) return NULL;
struct KekeArray *ret = keke_array_alloc(len, array->type_size);
memcpy(ret->content, array->content + start_index * array->type_size, len * array->type_size);
memmove(array->content + start_index * array->type_size, array->content + (start_index + len) * array->type_size, (array->len - len - start_index) * array->type_size);
keke_array_set_len(array, array->len - len);
return ret;
}
static int keke_array_insert_data(struct KekeArray *array, size_t index, void *data, size_t len) {
if(index >= array->len) return -1;
size_t current_len = array->len;
keke_array_set_len(array, current_len + len);
memmove(array->content + (index + len) * array->type_size, array->content + index * array->type_size, (current_len - index) * array->type_size);
memcpy(array->content + index * array->type_size, data, len * array->type_size);
return 0;
}
static int keke_array_plop(struct KekeArray *array, size_t index, struct KekeArray *array2) {
int ret = keke_array_insert_data(array, index, array2->content, array2->len);
if(ret) return ret;
keke_array_free(array2);
return 0;
}
typedef void (*Callback_func)(void *, size_t, struct KekeArray *);
static void keke_array_foreach(struct KekeArray *array, Callback_func callback) {
for(size_t i = 0; i < array->len; i++) callback(keke_array_get(array, i), i, array);
}
static struct KekeArray *keke_array_clone(struct KekeArray *array) {
struct KekeArray *ret = malloc(sizeof(*array));
memcpy(ret, array, sizeof(*array));
ret->content = malloc(array->max_len * array->type_size);
memcpy(ret->content, array->content, array->max_len * array->type_size);
return ret;
}
#endif #endif

18
libkeke_utils.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef LIBKEKE_UTILS
#define LIBKEKE_UTILS
#include <stddef.h>
#define BOOL_PRETTY(b) (b ? "True" : "False")
static void keke_swap(void *a, void *b, size_t size) {
char *aa = a;
char *bb = b;
for(size_t i = 0; i < size; i++) {
aa[i] ^= bb[i];
bb[i] ^= aa[i];
aa[i] ^= bb[i];
}
}
#endif

View File

@ -1,6 +0,0 @@
#!/bin/bash
rm test
cc=clang
test "" = "$(which clang 2>&1)" && cc=gcc
$cc -Ofast -Wall -Wextra -o test test.c
./test

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "libkeke_array.h" #include "libkeke_array.h"
#include "libkeke_utils.h"
#define ARRAY_LEN 10 #define ARRAY_LEN 10
@ -14,10 +15,27 @@ void output(void *i, size_t, struct KekeArray *) {
printf("%d, ", *(int *)i); printf("%d, ", *(int *)i);
} }
void sub4(void *i, size_t, struct KekeArray *) {
*(int *)i -= 4;
}
bool heart(void *i, size_t, struct KekeArray *) {
return *(int *)i < 3;
}
void add(void *vx, void *vacc) {
int *x = (int *)vx;
int *acc = (int *)vacc;
*acc += *x;
}
int main(void) { int main(void) {
struct KekeArray *array = keke_array_alloc(ARRAY_LEN, sizeof(int)); struct KekeArray *array = keke_array_alloc(ARRAY_LEN, sizeof(int));
puts("Expected value:\n0");
printf("%d", *(int *)keke_array_get(array, 0)); //initialized to 0
puts("\n");
keke_array_foreach(array, set); keke_array_foreach(array, set);
puts("Expected value:\n9, 8, 7, 6, 5, 4, 3, 2, 1, 0,"); puts("Expected value:\n9, 8, 7, 6, 5, 4, 3, 2, 1, 0,");
keke_array_foreach(array, output); keke_array_foreach(array, output);
@ -77,9 +95,38 @@ int main(void) {
keke_array_foreach(array, output); keke_array_foreach(array, output);
puts("\n"); puts("\n");
keke_array_fill(array, &j);
puts("Expected value:\n6, 6, 6, 6, 6,");
keke_array_foreach(array, output);
puts("\n");
keke_array_reverse(array2);
puts("Expected value:\n6, 6, 5, 6, 7, 7,");
keke_array_foreach(array2, output);
puts("\n");
keke_array_foreach(array2, sub4);
puts("Expected value:\n2, 2, 1, 2, 3, 3,");
keke_array_foreach(array2, output);
puts("\n");
bool h = keke_array_some(array2, heart);
bool g = keke_array_all(array2, heart);
puts("Expected value:\nTrue, False");
printf("%s, %s\n\n", BOOL_PRETTY(h), BOOL_PRETTY(g));
struct KekeArray *array4 = keke_array_filter(array2, heart);
puts("Expected value:\n2, 2, 1, 2,");
keke_array_foreach(array4, output);
puts("\n");
j = 0;
keke_array_reduce(array4, add, &j);
printf("Expected value:\n7\n%d\n\n", j);
keke_array_free(array); keke_array_free(array);
keke_array_free(array2); keke_array_free(array2);
keke_array_free(array4);
puts("\n"); puts("\n");
return 0; return 0;
} }