diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 17:53:40 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 17:53:40 +0100 |
| commit | 6cb22fd7f2c20be2cf268d6bcd236252d7847763 (patch) | |
| tree | 10891dcea861e5b3a9d8af3114393e650cdaae1d /examples | |
| download | nonstd-6cb22fd7f2c20be2cf268d6bcd236252d7847763.tar.gz | |
Engage!
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/.gitignore | 8 | ||||
| -rw-r--r-- | examples/Makefile | 56 | ||||
| -rw-r--r-- | examples/arena.c | 59 | ||||
| -rw-r--r-- | examples/array.c | 158 | ||||
| -rw-r--r-- | examples/files.c | 52 | ||||
| -rw-r--r-- | examples/foreach.c | 68 | ||||
| -rw-r--r-- | examples/slice.c | 79 | ||||
| -rw-r--r-- | examples/stringb.c | 130 | ||||
| -rw-r--r-- | examples/stringv.c | 97 | ||||
| -rw-r--r-- | examples/test_basic.txt | 1 | ||||
| -rw-r--r-- | examples/test_sb.txt | 1 | ||||
| -rw-r--r-- | examples/test_sv.txt | 1 |
12 files changed, 710 insertions, 0 deletions
diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..0707ee1 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,8 @@ +stringv +stringb +foreach +array +slice +arena +files + diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..a614627 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,56 @@ +# Makefile for nonstd.h examples + +CC = clang +CFLAGS = -Wall -Wextra -std=c99 -fsanitize=address -g -O0 +LDFLAGS = + +# Example targets +EXAMPLES = foreach stringv stringb array slice arena files + +# Default target +all: $(EXAMPLES) + +# Build individual examples +foreach: foreach.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +stringv: stringv.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +stringb: stringb.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +array: array.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +slice: slice.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +arena: arena.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +files: files.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +# Run all examples +run: all + @echo "\n=== Running stringv ===\n" + @./stringv + @echo "\n=== Running stringb ===\n" + @./stringb + @echo "\n=== Running foreach ===\n" + @./foreach + @echo "\n=== Running array ===\n" + @./array + @echo "\n=== Running slice ===\n" + @./slice + @echo "\n=== Running arena ===\n" + @./arena + @echo "\n=== Running files ===\n" + @./files + +# Clean build artifacts +clean: + rm -f $(EXAMPLES) + +.PHONY: all run clean diff --git a/examples/arena.c b/examples/arena.c new file mode 100644 index 0000000..32f9d77 --- /dev/null +++ b/examples/arena.c @@ -0,0 +1,59 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +typedef struct { + int id; + char *name; +} User; + +int main(void) { + // Initialize the arena + Arena a = arena_make(); + + // Allocate some structs + User *u1 = arena_alloc(&a, sizeof(User)); + u1->id = 1; + // Use string builder for name, but we can't easily alloc string builder + // internal buffer on arena yet unless we make a custom allocator for it. + // For now, let's just use arena_alloc for a string. + char *name1 = arena_alloc(&a, 10); + strcpy(name1, "Alice"); + u1->name = name1; + + User *u2 = arena_alloc(&a, sizeof(User)); + u2->id = 2; + char *name2 = arena_alloc(&a, 10); + strcpy(name2, "Bob"); + u2->name = name2; + + printf("User 1: %d, %s\n", u1->id, u1->name); + printf("User 2: %d, %s\n", u2->id, u2->name); + + // Creating a linked list using arena + struct Node { + int val; + struct Node *next; + }; + + struct Node *head = NULL; + for (int i = 0; i < 5; i++) { + struct Node *node = arena_alloc(&a, sizeof(struct Node)); + node->val = i; + node->next = head; + head = node; + } + + printf("List: "); + for (struct Node *n = head; n; n = n->next) { + printf("%d ", n->val); + } + printf("\n"); + + // Free everything at once + arena_free(&a); + printf("Arena freed.\n"); + + return 0; +} diff --git a/examples/array.c b/examples/array.c new file mode 100644 index 0000000..4275fd7 --- /dev/null +++ b/examples/array.c @@ -0,0 +1,158 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +// Example struct to demonstrate arrays of complex types +typedef struct { + int id; + const char *name; +} Person; + +int main(void) { + // Example 1: Basic integer array + printf("Example 1: Basic integer array\n"); + array(int) numbers; + array_init(numbers); + + // Push some numbers + for (int i = 1; i <= 5; i++) { + array_push(numbers, i * 10); + } + + printf(" Array length: %zu\n", numbers.length); + printf(" Array capacity: %zu\n", numbers.capacity); + printf(" Contents: "); + for (size_t i = 0; i < numbers.length; i++) { + printf("%d ", numbers.data[i]); + } + printf("\n\n"); + + // Example 2: Pop elements + printf("Example 2: Pop elements\n"); + int last = array_pop(numbers); + printf(" Popped: %d\n", last); + printf(" After pop: "); + for (size_t i = 0; i < numbers.length; i++) { + printf("%d ", numbers.data[i]); + } + printf("\n\n"); + + // Example 3: Insert and remove + printf("Example 3: Insert and remove\n"); + array_insert(numbers, 2, 999); // Insert 999 at index 2 + printf(" After insert at index 2: "); + for (size_t i = 0; i < numbers.length; i++) { + printf("%d ", numbers.data[i]); + } + printf("\n"); + + array_remove(numbers, 1); // Remove element at index 1 + printf(" After remove index 1: "); + for (size_t i = 0; i < numbers.length; i++) { + printf("%d ", numbers.data[i]); + } + printf("\n\n"); + + // Example 4: Get and set + printf("Example 4: Get and set\n"); + int value = array_get(numbers, 0); + printf(" Value at index 0: %d\n", value); + array_set(numbers, 0, 777); + printf(" After setting index 0 to 777: "); + for (size_t i = 0; i < numbers.length; i++) { + printf("%d ", numbers.data[i]); + } + printf("\n\n"); + + array_free(numbers); + + // Example 5: Array with initial capacity + printf("Example 5: Array with initial capacity\n"); + array(int) preallocated; + array_init_cap(preallocated, 100); + printf(" Initial capacity: %zu\n", preallocated.capacity); + printf(" Initial length: %zu\n", preallocated.length); + array_free(preallocated); + printf("\n"); + + // Example 6: foreach iteration + printf("Example 6: foreach iteration\n"); + array(int) values; + array_init(values); + for (int i = 0; i < 10; i++) { + array_push(values, i * i); // Push squares + } + + printf(" Using array_foreach: "); + int val; + array_foreach(values, val) { printf("%d ", val); } + printf("\n"); + + printf(" Using array_foreach_i: "); + array_foreach_i(values, val, idx) { printf("[%zu]=%d ", idx, val); } + printf("\n\n"); + + array_free(values); + + // Example 7: Array of strings + printf("Example 7: Array of strings\n"); + array(const char *) words; + array_init(words); + + array_push(words, "Hello"); + array_push(words, "World"); + array_push(words, "from"); + array_push(words, "C"); + + printf(" Words: "); + const char *word; + array_foreach(words, word) { printf("%s ", word); } + printf("\n\n"); + + array_free(words); + + // Example 8: Array of structs + printf("Example 8: Array of structs\n"); + array(Person) people; + array_init(people); + + array_push(people, ((Person){1, "Alice"})); + array_push(people, ((Person){2, "Bob"})); + array_push(people, ((Person){3, "Charlie"})); + + printf(" People:\n"); + Person person; + array_foreach(people, person) { printf(" ID: %d, Name: %s\n", person.id, person.name); } + printf("\n"); + + array_free(people); + + // Example 9: Reserve capacity + printf("Example 9: Reserve capacity\n"); + array(double) measurements; + array_init(measurements); + printf(" Initial capacity: %zu\n", measurements.capacity); + + array_reserve(measurements, 1000); + printf(" After reserve(1000): %zu\n", measurements.capacity); + + array_free(measurements); + printf("\n"); + + // Example 10: Clear array + printf("Example 10: Clear array\n"); + array(int) temp; + array_init(temp); + for (int i = 0; i < 5; i++) { + array_push(temp, i); + } + printf(" Length before clear: %zu\n", temp.length); + array_clear(temp); + printf(" Length after clear: %zu\n", temp.length); + printf(" Capacity after clear: %zu\n", temp.capacity); + + array_free(temp); + + return 0; +} diff --git a/examples/files.c b/examples/files.c new file mode 100644 index 0000000..663bbf9 --- /dev/null +++ b/examples/files.c @@ -0,0 +1,52 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +int main(void) { + // 1. Basic usage + const char *msg = "Hello, World!\n"; + if (write_entire_file("test_basic.txt", msg, strlen(msg))) { + printf("Written test_basic.txt\n"); + } + + size_t sz; + char *content = read_entire_file("test_basic.txt", &sz); + if (content) { + printf("Read: %.*s", (int)sz, content); + FREE(content); + } + + // 2. usage with string view + stringv sv = sv_from_cstr("Hello from String View!\n"); + if (write_file_sv("test_sv.txt", sv)) { + printf("Written test_sv.txt\n"); + } + + stringv sv_read = read_entire_file_sv("test_sv.txt"); + if (sv_read.data) { + printf("Read sv: %.*s", (int)sv_read.length, sv_read.data); + free((char *)sv_read.data); + } + + // 3. usage with string builder + stringb sb; + sb_init(&sb, 0); + sb_append_cstr(&sb, "Hello from "); + sb_append_cstr(&sb, "String Builder!\n"); + + if (write_file_sb("test_sb.txt", &sb)) { + printf("Written test_sb.txt\n"); + } + + // Read into stringb + stringb sb2 = read_entire_file_sb("test_sb.txt"); + if (sb2.data) { + printf("Read into sb: %s", sb2.data); + sb_free(&sb2); + } + + sb_free(&sb); + + return 0; +} diff --git a/examples/foreach.c b/examples/foreach.c new file mode 100644 index 0000000..628c993 --- /dev/null +++ b/examples/foreach.c @@ -0,0 +1,68 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +int main(void) { + // Example 1: Iterate over an array of integers + int numbers[] = {10, 20, 30, 40, 50}; + int num; // Declare the loop variable + + static_foreach(int, num, numbers) { printf(" Number: %d\n", num); } + printf("\n"); + + // Example 2: Iterate over an array of floats + float prices[] = {9.99f, 19.99f, 29.99f, 49.99f}; + float price; // Declare the loop variable + + static_foreach(float, price, prices) { printf(" Price: $%.2f\n", price); } + printf("\n"); + + // Example 3: Iterate over an array of strings + const char *fruits[] = {"Apple", "Banana", "Cherry", "Date", "Elderberry"}; + const char *fruit; // Declare the loop variable + + static_foreach(const char *, fruit, fruits) { printf(" Fruit: %s\n", fruit); } + printf("\n"); + + // Example 4: Perform calculations with static_foreach + int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int sum = 0; + int val; // Declare the loop variable + + static_foreach(int, val, values) { sum += val; } + printf(" Sum of values: %d\n", sum); + printf("\n"); + + // Example 5: Iterate over struct array + typedef struct { + const char *name; + int age; + } Person; + + Person people[] = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}}; + Person person; // Declare the loop variable + + static_foreach(Person, person, people) { printf(" %s is %d years old\n", person.name, person.age); } + printf("\n"); + + // Example 6: Modify array elements in place + int nums[] = {1, 2, 3, 4, 5}; + int n; // Declare the loop variable + + printf(" Before: "); + static_foreach(int, n, nums) { printf("%d ", n); } + printf("\n"); + + // Note: static_foreach creates a copy of each element by default + // To modify elements, use a traditional for loop with array indexing + for (size_t i = 0; i < countof(nums); i++) { + nums[i] *= 2; + } + + printf(" After doubling: "); + static_foreach(int, n, nums) { printf("%d ", n); } + printf("\n"); + + return 0; +} diff --git a/examples/slice.c b/examples/slice.c new file mode 100644 index 0000000..a5f4945 --- /dev/null +++ b/examples/slice.c @@ -0,0 +1,79 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +SLICE_DEF(int); + +// Example function that accepts a slice of integers +void print_int_slice(slice(int) s) { + printf(" Slice (len=%zu): [", s.length); + for (size_t i = 0; i < s.length; i++) { + printf("%d%s", s.data[i], i < s.length - 1 ? ", " : ""); + } + printf("]\n"); +} + +int main(void) { + // Example 1: Slice from static array + printf("Example 1: Slice from static C array\n"); + int static_nums[] = {10, 20, 30, 40, 50}; + + // Create full slice + slice(int) s1 = make_slice(int, static_nums, countof(static_nums)); + print_int_slice(s1); + + // Create partial slice (subset) + slice(int) s2 = make_slice(int, static_nums + 1, 3); // 20, 30, 40 + print_int_slice(s2); + printf("\n"); + + // Example 2: Slice from dynamic array + printf("Example 2: Slice from dynamic array\n"); + array(int) dyn_arr; + array_init(dyn_arr); + for (int i = 1; i <= 5; i++) + array_push(dyn_arr, i * 100); + + // Convert entire array to slice + slice(int) s3 = array_as_slice(int, dyn_arr); + print_int_slice(s3); + + // Create slice from dynamic array data manually + slice(int) s4 = make_slice(int, dyn_arr.data + 2, 2); // 300, 400 + print_int_slice(s4); + + array_free(dyn_arr); + printf(" (Dynamic array freed)\n\n"); + + // Example 3: Modifying data through slice + printf("Example 3: Modifying data through slice\n"); + int values[] = {1, 1, 1, 1, 1}; + slice(int) s5 = make_slice(int, values, 5); + + print_int_slice(s5); + + // Modify middle elements + s5.data[2] = 99; + s5.data[3] = 99; + + printf(" After modification:\n"); + print_int_slice(s5); + printf("\n"); + + // Example 4: Slice of strings + printf("Example 4: Slice of strings\n"); + typedef const char *cstr; + SLICE_DEF(cstr); + + cstr names[] = {"Alice", "Bob", "Charlie"}; + slice(cstr) name_slice = make_slice(cstr, names, 3); + + printf(" Names: "); + for (size_t i = 0; i < name_slice.length; i++) { + printf("%s ", name_slice.data[i]); + } + printf("\n"); + + return 0; +} diff --git a/examples/stringb.c b/examples/stringb.c new file mode 100644 index 0000000..443f2ae --- /dev/null +++ b/examples/stringb.c @@ -0,0 +1,130 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +// Helper function to print string builder content +void print_sb(const char *label, const stringb *sb) { + printf("%s (len=%zu, cap=%zu): \"%s\"\n", label, sb->length, sb->capacity, sb->data); +} + +int main(void) { + // Example 1: Basic string building + stringb sb1; + sb_init(&sb1, 0); // 0 means use default capacity (16) + + sb_append_cstr(&sb1, "Hello"); + sb_append_cstr(&sb1, ", "); + sb_append_cstr(&sb1, "World"); + sb_append_char(&sb1, '!'); + + print_sb(" sb1", &sb1); + sb_free(&sb1); + printf("\n"); + + // Example 2: Building with initial capacity + stringb sb2; + sb_init(&sb2, 100); // Start with larger capacity to avoid reallocations + + print_sb(" Initial", &sb2); + + sb_append_cstr(&sb2, "This is a longer string that benefits from pre-allocation"); + print_sb(" After append", &sb2); + + sb_free(&sb2); + printf("\n"); + + // Example 3: Appending string views + stringb sb3; + sb_init(&sb3, 0); + + const char *text = "The quick brown fox"; + stringv word = sv_from_parts(text + 4, 5); // "quick" + + sb_append_cstr(&sb3, "Extracted: "); + sb_append_sv(&sb3, word); + sb_append_cstr(&sb3, " (from a view)"); + + print_sb(" sb3", &sb3); + sb_free(&sb3); + printf("\n"); + + // Example 4: Converting builder to view for reading + stringb sb4; + sb_init(&sb4, 0); + + sb_append_cstr(&sb4, "Builder content"); + + // Get a read-only view of the builder + stringv view = sb_as_sv(&sb4); + printf(" Builder as view (len=%zu): \"", view.length); + fwrite(view.data, 1, view.length, stdout); + printf("\"\n"); + + // You can use all string view operations on it + stringv prefix = sv_from_cstr("Builder"); + printf(" Starts with 'Builder': %s\n", sv_starts_with(view, prefix) ? "yes" : "no"); + + sb_free(&sb4); + printf("\n"); + + // Example 5: Building a formatted message + stringb sb5; + sb_init(&sb5, 0); + + const char *names[] = {"Alice", "Bob", "Charlie"}; + int ages[] = {25, 30, 35}; + + sb_append_cstr(&sb5, "People:\n"); + for (size_t i = 0; i < countof(names); i++) { + sb_append_cstr(&sb5, " - "); + sb_append_cstr(&sb5, names[i]); + sb_append_cstr(&sb5, " (age "); + + // Note: For numbers, you'd typically use sprintf with a temp buffer + char age_buf[32]; + snprintf(age_buf, sizeof(age_buf), "%d", ages[i]); + sb_append_cstr(&sb5, age_buf); + + sb_append_cstr(&sb5, ")\n"); + } + + printf("%s", sb5.data); + sb_free(&sb5); + printf("\n"); + + // Example 6: Building CSV data + stringb csv; + sb_init(&csv, 64); + + sb_append_cstr(&csv, "Name,Age,City\n"); + sb_append_cstr(&csv, "Alice,25,NYC\n"); + sb_append_cstr(&csv, "Bob,30,LA\n"); + sb_append_cstr(&csv, "Charlie,35,Chicago\n"); + + printf(" CSV output:\n%s", csv.data); + sb_free(&csv); + printf("\n"); + + // Example 7: Practical use case - building a SQL query + stringb query; + sb_init(&query, 128); + + sb_append_cstr(&query, "SELECT * FROM users WHERE "); + + const char *conditions[] = {"age > 18", "active = 1", "country = 'US'"}; + for (size_t i = 0; i < countof(conditions); i++) { + if (i > 0) { + sb_append_cstr(&query, " AND "); + } + sb_append_cstr(&query, conditions[i]); + } + + sb_append_char(&query, ';'); + + print_sb(" Query", &query); + sb_free(&query); + printf("\n"); + + return 0; +} diff --git a/examples/stringv.c b/examples/stringv.c new file mode 100644 index 0000000..ff5d376 --- /dev/null +++ b/examples/stringv.c @@ -0,0 +1,97 @@ +#define NONSTD_IMPLEMENTATION +#include "../nonstd.h" + +#include <stdio.h> + +// Helper function to print a string view +void print_sv(const char *label, stringv sv) { + printf("%s (len=%zu): \"", label, sv.length); + fwrite(sv.data, 1, sv.length, stdout); + printf("\"\n"); +} + +int main(void) { + // Example 1: Create string view from C string + const char *hello = "Hello, World!"; + stringv sv1 = sv_from_cstr(hello); + print_sv(" sv1", sv1); + printf("\n"); + + // Example 2: Create view from pointer and length + const char *text = "Programming in C"; + stringv sv2 = sv_from_parts(text, 11); // Only "Programming" + print_sv(" sv2", sv2); + printf("\n"); + + // Example 3: Slicing - extract substrings without copying + stringv original = sv_from_cstr("The quick brown fox"); + + stringv word1 = sv_slice(original, 0, 3); // "The" + stringv word2 = sv_slice(original, 4, 9); // "quick" + stringv word3 = sv_slice(original, 10, 15); // "brown" + + print_sv(" Original", original); + print_sv(" Word 1", word1); + print_sv(" Word 2", word2); + print_sv(" Word 3", word3); + printf("\n"); + + // Example 4: Comparing string views + stringv str_a = sv_from_cstr("hello"); + stringv str_b = sv_from_cstr("hello"); + stringv str_c = sv_from_cstr("world"); + + printf(" str_a == str_b: %s\n", sv_equals(str_a, str_b) ? "true" : "false"); + printf(" str_a == str_c: %s\n", sv_equals(str_a, str_c) ? "true" : "false"); + printf("\n"); + + // Example 5: Prefix and suffix checking + stringv filename = sv_from_cstr("document.txt"); + stringv prefix = sv_from_cstr("doc"); + stringv suffix = sv_from_cstr(".txt"); + stringv wrong_suffix = sv_from_cstr(".pdf"); + + print_sv(" Filename", filename); + printf(" Starts with 'doc': %s\n", sv_starts_with(filename, prefix) ? "yes" : "no"); + printf(" Ends with '.txt': %s\n", sv_ends_with(filename, suffix) ? "yes" : "no"); + printf(" Ends with '.pdf': %s\n", sv_ends_with(filename, wrong_suffix) ? "yes" : "no"); + printf("\n"); + + // Example 6: Parsing a path (practical use case) + const char *path = "/home/user/documents/report.pdf"; + stringv path_sv = sv_from_cstr(path); + + // Find the last '/' to extract filename + size_t last_slash = 0; + for (size_t i = 0; i < path_sv.length; i++) { + if (path_sv.data[i] == '/') { + last_slash = i + 1; + } + } + + stringv directory = sv_slice(path_sv, 0, last_slash); + stringv filename2 = sv_slice(path_sv, last_slash, path_sv.length); + + print_sv(" Full path", path_sv); + print_sv(" Directory", directory); + print_sv(" Filename", filename2); + printf("\n"); + + // Example 7: Tokenizing without allocation + const char *sentence = "one two three four"; + stringv sent_sv = sv_from_cstr(sentence); + + size_t start = 0; + for (size_t i = 0; i <= sent_sv.length; i++) { + if (i == sent_sv.length || sent_sv.data[i] == ' ') { + if (i > start) { + stringv token = sv_slice(sent_sv, start, i); + print_sv(" Token", token); + } + start = i + 1; + } + } + printf("\n"); + + return 0; +} diff --git a/examples/test_basic.txt b/examples/test_basic.txt new file mode 100644 index 0000000..8ab686e --- /dev/null +++ b/examples/test_basic.txt @@ -0,0 +1 @@ +Hello, World! diff --git a/examples/test_sb.txt b/examples/test_sb.txt new file mode 100644 index 0000000..4ed02a4 --- /dev/null +++ b/examples/test_sb.txt @@ -0,0 +1 @@ +Hello from String Builder! diff --git a/examples/test_sv.txt b/examples/test_sv.txt new file mode 100644 index 0000000..f4b8e86 --- /dev/null +++ b/examples/test_sv.txt @@ -0,0 +1 @@ +Hello from String View! |
