rewritten Array and List, changed str.size -> .len

This commit is contained in:
2025-11-25 14:13:25 +05:00
parent b557881168
commit 82bd234d08
48 changed files with 389 additions and 227 deletions

View File

@@ -1,57 +1,62 @@
#pragma once
#include "../std.h"
#define Array(T) Array_
/*
Pointer and length.
Can be initialized with {0}.
*/
typedef struct Array_ {
void* data;
u32 size;
} Array_;
#define Array(T) Array_##T
/// creates Array_ from self const array
#define ARRAY(T, A...) Array_construct_size(((T[])A), sizeof((T[])A))
/// create Array(T) from array initializer list ({ a, b, c })
#define ARRAY(T, A...) ((Array(T)){ .data = ((T[])A), .len = sizeof((T[])A) / sizeof(T) })
#define Array_construct(DATA, T, COUNT) Array_construct_size(DATA, (COUNT) * sizeof(T))
#define Array_construct_size(DATA, LEN) ((Array_){ .data = (DATA), .size = (LEN) })
#define Array_declare(T) \
typedef struct Array(T) { \
T* data; \
u32 len; \
} Array(T); \
\
static inline Array(T) Array_##T##_construct(T* data, u32 len) { \
return (Array(T)){ .data = data, .len = len }; \
} \
\
static inline Array(T) Array_##T##_alloc(u32 len){ \
if(len == 0) \
return Array_##T##_construct(NULL, 0); \
return Array_##T##_construct(malloc(len * sizeof(T)), len); \
} \
\
static inline void Array_##T##_realloc(Array(T)* self, u32 new_len){ \
self->data = (T*)realloc(self->data, new_len * sizeof(T)); \
self->len = new_len; \
} \
\
static inline Array(T) Array_##T##_copy(const Array(T) src){ \
Array(T) copy = Array_##T##_alloc(src.len); \
if(copy.data != NULL) \
memcpy(copy.data, src.data, src.len * sizeof(T)); \
return copy; \
} \
\
static inline void Array_##T##_destroy(Array(T)* self){ \
if(!self) \
return; \
free(self->data); \
} \
\
static inline void Array_##T##_memset(Array(T)* self, u32 value){ \
memset(self->data, value, self->len * sizeof(T)); \
} \
\
/* @return self[0..i-1] */ \
static inline Array(T) Array_##T##_sliceTo(const Array(T) src, u32 i){ \
return Array_##T##_construct(src.data, i); \
} \
\
/* @return self[i...] */ \
static inline Array(T) Array_##T##_sliceFrom(const Array(T) src, u32 i){ \
return Array_##T##_construct(src.data + i, src.len - i); \
} \
#define Array_null Array_construct_size(NULL, 0)
#define Array_alloc(T, COUNT) Array_alloc_size((COUNT) * sizeof(T))
static inline Array_ Array_alloc_size(u32 size){
if(size == 0)
return Array_null;
return Array_construct_size(malloc(size), size);
}
#define Array_realloc(SELF, T, COUNT) Array_realloc_size(SELF, (COUNT) * sizeof(T))
static inline void Array_realloc_size(Array_* self, u32 new_size){
self->data = realloc(self->data, new_size);
self->size = new_size;
}
static inline Array_ Array_copy(const Array_ self){
Array_ copy = Array_alloc_size(self.size);
if(copy.data != NULL)
memcpy(copy.data, self.data, self.size);
return copy;
}
static inline void Array_free(Array_ self){
free(self.data);
}
#define Array_len(SELF, T) (SELF.size / sizeof(T))
#define Array_memset(SELF, VAL) memset(SELF.data, VAL, SELF.size)
#define struct_castTo_Array(STRUCT_PTR) Array_construct_size((STRUCT_PTR), sizeof(*STRUCT_PTR))
///@return self[0..i-1]
static inline Array(u8) Array_sliceTo(const Array(u8) self, u32 i){
return Array_construct_size(self.data, i);
}
///@return self[i...]
static inline Array(u8) Array_sliceFrom(const Array(u8) self, u32 i){
return Array_construct_size((u8*)self.data + i, self.size - i);
}
#define struct_castTo_Array_u8(STRUCT_PTR) Array_u8_construct((void*)(STRUCT_PTR), sizeof(*STRUCT_PTR))

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(char);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(f32);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(f64);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(i16);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(i32);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(i64);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(i8);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(u16);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(u32);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(u64);

View File

@@ -0,0 +1,2 @@
#pragma once
Array_declare(u8);

View File

@@ -1,7 +1,6 @@
#pragma once
#include "../std.h"
#include "../string/str.h"
#include "Array.h"
#include "List.h"
typedef struct HashMapKeyHash {
@@ -9,9 +8,11 @@ typedef struct HashMapKeyHash {
u32 hash;
} HashMapKeyHash;
List_declare(HashMapKeyHash);
typedef struct HashMapBucket {
List(HashMapKeyHash) key_hash_list;
List(T) value_list;
List_ value_list;
} HashMapBucket;
#define HashMap(T) HashMap_

View File

@@ -2,7 +2,8 @@
#include "../std.h"
/*
Doubly linked list
Doubly linked list.
Can be initialized with {0}.
*/
#define LLNode(T) LLNode_##T

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(char);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(f32);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(f64);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(i16);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(i32);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(i64);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(i8);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(u16);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(u32);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(u64);

View File

@@ -0,0 +1,2 @@
#pragma once
LList_declare(u8);

View File

@@ -1,44 +1,89 @@
#pragma once
#include "../std.h"
#define List(T) List_
/*
Dynamic array.
CAN NOT be initialized with {0}.
*/
#define List(T) List_##T
#define List_declare(T) \
typedef struct List(T) { \
T* data; \
u32 len; \
u32 capacity; \
u32 elem_t_size; \
} List(T); \
\
static inline List(T) List_##T##_construct(T* data_ptr, u32 occupied_len, u32 capacity) { \
return (List(T)){ \
.data = data_ptr, \
.len = occupied_len, \
.capacity = capacity, \
.elem_t_size = sizeof(T) \
}; \
} \
\
static inline List(T) List_##T##_alloc(u32 initial_capacity) { \
List_ l = _List_alloc(initial_capacity, sizeof(T)); \
return *(List(T)*)(void*)&l; \
} \
\
static inline List(T) List_##T##_copy(const List(T)* src) { \
List_ l = _List_copy((void*)src); \
return *(List(T)*)(void*)&l; \
} \
\
static inline void List_##T##_destroy(List(T)* self) { _List_destroy((void*)self); } \
\
static inline void List_##T##_push(List(T)* self, T value) { \
T* empty_cell = (T*)(_List_expand((void*)self, 1)); \
*empty_cell = value; \
} \
\
static inline void List_##T##_pushMany(List(T)* self, T* values_ptr, u32 len) { \
_List_push((void*)self, values_ptr, len); \
} \
\
/* alloc bigger buffer if size + len_to_add won't fit in current */ \
static inline void List_##T##_increaseCapacity(List(T)* self, u32 len_to_add){ \
_List_increaseCapacity((void*)self, len_to_add); \
} \
\
static inline bool List_##T##_tryRemoveAt(List(T)* self, u32 i, u32 remove_len) ATTRIBUTE_WARN_UNUSED_RESULT; \
static inline bool List_##T##_tryRemoveAt(List(T)* self, u32 i, u32 remove_len) { \
return _List_tryRemoveAt((void*)self, i, remove_len); \
} \
typedef struct List_ {
void* data;
u32 size;
u32 allocated_size;
u32 len;
u32 capacity;
u32 elem_t_size;
} List_;
#define List_construct(T, DATA_PTR, OCCUPIED_COUNT, ALLOCATED_COUNT) \
List_construct_size(DATA_PTR, (OCCUPIED_COUNT) * sizeof(T), (ALLOCATED_COUNT) * sizeof(T))
static inline List_ List_construct_size(void* data_ptr, u32 occupied_size, u32 allocated_size) {
return (List_){ .data = data_ptr, .size = occupied_size, .allocated_size = allocated_size };
static inline List_ _List_construct(void* data_ptr, u32 len, u32 capacity, u32 elem_t_size) {
return (List_){
.data = data_ptr,
.len = len,
.capacity = capacity,
.elem_t_size = elem_t_size
};
}
#define List_null List_construct_size(NULL, 0, 0)
#define List_alloc(T, INITIAL_COUNT) List_alloc_size((INITIAL_COUNT) * sizeof(T))
List_ List_alloc_size(u32 initial_size);
static inline void List_destroy(List_* self){
static inline void _List_destroy(List_* self){
if(!self)
return;
free(self->data);
}
List_ List_copy(List_ src);
// alloc bigger buffer if size + size_to_add won't fit in current
void List_increaseCapacity_size(List_* self, u32 size_to_add);
void* List_expand_size(List_* self, u32 size_to_add);
#define List_push(SELF, T, VALUE) *(T*)(List_expand_size(SELF, sizeof(T))) = VALUE
#define List_pushMany(SELF, T, VALUES_PTR, COUNT) List_push_size(SELF, VALUES_PTR, (COUNT) * sizeof(T))
void List_push_size(List_* self, void* values, u32 size);
#define List_removeAt(SELF, T, I, COUNT) List_removeAt_size(SELF, (I)*sizeof(T), (COUNT) * sizeof(T))
bool List_removeAt_size(List_* self, u32 i, u32 remove_size);
#define List_len(SELF, T) (SELF.size / sizeof(T))
#define List_index(SELF, T, I) (((T*)SELF.data)[I])
#define List_castTo_Array(SELF) Array_construct_size(SELF.data, SELF.size)
List_ _List_alloc(u32 initial_capacity, u32 elem_t_size);
List_ _List_copy(const List_* src);
/* alloc bigger buffer if size + len_to_add won't fit in current */
void _List_increaseCapacity(List_* self, u32 len_to_add);
void* _List_expand(List_* self, u32 len_to_add);
void _List_push(List_* self, void* values, u32 len);
bool _List_tryRemoveAt(List_* self, u32 i, u32 remove_len) ATTRIBUTE_WARN_UNUSED_RESULT;

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(char);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(f32);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(f64);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(i16);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(i32);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(i64);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(i8);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(u16);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(u32);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(u64);

View File

@@ -0,0 +1,2 @@
#pragma once
List_declare(u8);

View File

@@ -9,12 +9,15 @@ typedef struct ErrorCallPos {
cstr file;
cstr func;
} ErrorCallPos;
#define ErrorCallPos_here() (ErrorCallPos){\
.line = __LINE__,\
.file = __FILE__,\
.func = __func__\
}
List_declare(ErrorCallPos);
typedef struct Error {
str msg;
bool is_msg_on_heap;

View File

@@ -4,6 +4,7 @@
#include "errors.h"
#include "string/str.h"
#include "collections/Array.h"
#include "collections/Array_impl/Array_u8.h"
#if !defined(TLIBC_FS_USE_WINDOWS_H)
#if defined(_WIN64) || defined(_WIN32)
@@ -93,7 +94,7 @@ static inline Result(void) file_writeBytes(FILE* f, const void* src, u64 size){
}
static inline Result(void) file_writeBytesArray(FILE* f, Array(u8) src){
return file_writeStructs(f, src.data, src.size, 1);
return file_writeStructs(f, src.data, src.len, 1);
}
@@ -112,10 +113,10 @@ static inline Result(u64) file_readBytes(FILE* f, void* dst, u64 max_count){
return file_readStructs(f, dst, 1, max_count);
}
/// @param dst array where .size is the maximum number of bytes to read
/// @param dst array where .len is the maximum number of bytes to read
/// @return number of bytes that were read (<=max_count)
static inline Result(u64) file_readBytesArray(FILE* f, Array(u8) dst){
return file_readStructs(f, dst.data, 1, dst.size);
return file_readStructs(f, dst.data, 1, dst.len);
}
@@ -127,9 +128,9 @@ static inline Result(void) file_readBytesExactly(FILE* f, void* dst, u64 exact_c
return file_readStructsExactly(f, dst, 1, exact_count);
}
/// @param dst array where .size is the exact number of bytes to read
/// @param dst array where .len is the exact number of bytes to read
static inline Result(void) file_readBytesArrayExactly(FILE* f, Array(u8) dst){
return file_readStructsExactly(f, dst.data, 1, dst.size);
return file_readStructsExactly(f, dst.data, 1, dst.len);
}
/// @brief allocates array of size equal `file_getSize()` and reads whole file

View File

@@ -1,7 +1,7 @@
#pragma once
#include "../collections/List.h"
#include "../collections/Array.h"
#include "../collections/List_impl/List_char.h"
#include "str.h"
typedef struct StringBuilder {
@@ -9,17 +9,17 @@ typedef struct StringBuilder {
} StringBuilder;
static inline StringBuilder StringBuilder_alloc(u32 initial_size) {
return (StringBuilder){ .buffer = List_alloc_size(initial_size) };
return (StringBuilder){ .buffer = List_char_alloc(initial_size) };
}
void StringBuilder_destroy(StringBuilder* b);
static inline StringBuilder StringBuilder_copy(const StringBuilder* b){
return (StringBuilder) { .buffer = List_copy(b->buffer) };
return (StringBuilder) { .buffer = List_char_copy(&b->buffer) };
}
// alloc bigger buffer if size + size_to_add won't fit in current
static inline void StringBuilder_increaseCapacity(StringBuilder* b, u32 size_to_add){
List_increaseCapacity_size(&b->buffer, size_to_add);
// alloc bigger buffer if size + len_to_add won't fit in current
static inline void StringBuilder_increaseCapacity(StringBuilder* b, u32 len_to_add){
List_char_increaseCapacity(&b->buffer, len_to_add);
}

View File

@@ -4,10 +4,12 @@
#include "char.h"
#include "cstr.h"
#include "../collections/Array.h"
#include "../collections/Array_impl/Array_char.h"
#include "../collections/Array_impl/Array_u8.h"
typedef struct str {
char* data;
u32 size; // size of data in bytes without \0
u32 len; // size of data in bytes without \0
bool isZeroTerminated;
} str;
@@ -16,7 +18,7 @@ typedef struct str {
/// creates str from a string literal
#define STR(LITERAL) str_construct(LITERAL, ARRAY_LEN(LITERAL) - 1, true)
#define str_construct(DATA, LEN, ZERO_TERMINATED) ((str){ .data = DATA, .size = LEN, .isZeroTerminated = ZERO_TERMINATED })
#define str_construct(DATA, LEN, ZERO_TERMINATED) ((str){ .data = DATA, .len = LEN, .isZeroTerminated = ZERO_TERMINATED })
static inline str str_from_cstr(cstr s_ptr){
return str_construct((void*)s_ptr, strlen(s_ptr), true);
@@ -26,12 +28,18 @@ static inline void str_free(str s){
free(s.data);
}
static inline Array_ str_castTo_Array(str s) {
return Array_construct_size(s.data, s.size);
static inline Array(char) str_castTo_Array_char(str s) {
return Array_char_construct(s.data, s.len);
}
static inline Array(u8) str_castTo_Array_u8(str s) {
return Array_u8_construct((void*)s.data, s.len);
}
static inline str Array_castTo_str(Array_ a, bool isZeroTerminated) {
return str_construct(a.data, a.size, isZeroTerminated);
static inline str Array_char_castTo_str(Array(char) a, bool isZeroTerminated) {
return str_construct(a.data, a.len, isZeroTerminated);
}
static inline str Array_u8_castTo_str(Array(u8) a, bool isZeroTerminated) {
return str_construct((void*)a.data, a.len, isZeroTerminated);
}
static const str str_null = str_construct(NULL, 0, 0);
@@ -74,5 +82,5 @@ static inline str str_sliceBefore(str s, u32 n){
///@return s[n...]
static inline str str_sliceAfter(str s, u32 n){
return str_construct(s.data + n, s.size - n, s.isZeroTerminated);
return str_construct(s.data + n, s.len - n, s.isZeroTerminated);
}