summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 17:53:40 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-01-21 17:53:40 +0100
commit6cb22fd7f2c20be2cf268d6bcd236252d7847763 (patch)
tree10891dcea861e5b3a9d8af3114393e650cdaae1d /examples
downloadnonstd-6cb22fd7f2c20be2cf268d6bcd236252d7847763.tar.gz
Engage!
Diffstat (limited to 'examples')
-rw-r--r--examples/.gitignore8
-rw-r--r--examples/Makefile56
-rw-r--r--examples/arena.c59
-rw-r--r--examples/array.c158
-rw-r--r--examples/files.c52
-rw-r--r--examples/foreach.c68
-rw-r--r--examples/slice.c79
-rw-r--r--examples/stringb.c130
-rw-r--r--examples/stringv.c97
-rw-r--r--examples/test_basic.txt1
-rw-r--r--examples/test_sb.txt1
-rw-r--r--examples/test_sv.txt1
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!