• Container Types
• Vector Operations
• Unordered Map Operations
• Stack Operations
• Queue Operations
• Set Operations
• Priority Queue Operations
• Deque Operations
• Linked List Operations
• Sorting Algorithms
• Searching Algorithms
• Utility Algorithms
• String Utilities
• Random Utilities
• Timer Utilities
• Math Utilities
• Memory Utilities
• Comparator Helpers
// Vector - Dynamic array
vector v;
vector_init(&v, sizeof(int));
// Unordered Map - Key-value store
unordered_map m;
map_init(&m);
// Stack - LIFO container
stack s;
stack_init(&s, sizeof(int));
// Queue - FIFO container
queue q;
queue_init(&q, sizeof(int));
// Set - Unique element collection
set s;
set_init(&s, sizeof(int), compare_int);
// Priority Queue - Max heap
priority_queue pq;
priority_queue_init(&pq, sizeof(int), compare_int);
// Deque - Double-ended queue
deque dq;
deque_init(&dq, sizeof(int));
// Linked List - Doubly linked list
list l;
list_init(&l, sizeof(int));
// Pair - Key-value pair
pair p = make_pair(&key, &value);// Initialization
vector v;
vector_init(&v, sizeof(int));
// Adding elements
int value = 42;
vector_push_back(&v, &value);
// Accessing elements
int* elem = (int*)vector_get(&v, index);
int* elem_safe = (int*)vector_at(&v, index); // Bounds-checked
// Front and back
int* first = (int*)vector_front(&v);
int* last = (int*)vector_back(&v);
// Insertion and deletion
vector_insert(&v, index, &new_value);
vector_erase(&v, index);
vector_pop_back(&v);
// Capacity management
vector_reserve(&v, new_capacity);
vector_resize(&v, new_size, &default_value);
vector_shrink_to_fit(&v);
// Information
size_t size = vector_size(&v);
size_t capacity = vector_capacity(&v);
bool empty = vector_empty(&v);
// Cleanup
vector_clear(&v);
vector_free(&v);// Initialization
unordered_map m;
map_init(&m);
map_init_with_capacity(&m, 64);
// Insertion
int value = 100;
map_insert(&m, "key1", &value, sizeof(int));
// Access
int* retrieved = (int*)map_get(&m, "key1");
// Operations
bool exists = map_contains(&m, "key1");
bool removed = map_erase(&m, "key1");
size_t map_size = map_size(&m);
bool is_empty = map_empty(&m);
// Cleanup
map_clear(&m);
map_free(&m);// Initialization
stack s;
stack_init(&s, sizeof(int));
// Push and pop
int value = 10;
stack_push(&s, &value);
stack_pop(&s);
// Access top
int* top = (int*)stack_top(&s);
// Information
size_t stack_size = stack_size(&s);
bool stack_empty = stack_empty(&s);
// Management
stack_clear(&s);
stack_free(&s);// Initialization
queue q;
queue_init(&q, sizeof(int));
// Enqueue and dequeue
int value = 20;
queue_enqueue(&q, &value);
queue_dequeue(&q);
// Access
int* front = (int*)queue_front(&q);
int* back = (int*)queue_back(&q);
// Information
size_t queue_size = queue_size(&q);
bool queue_empty = queue_empty(&q);
// Management
queue_clear(&q);
queue_free(&q);// Initialization (requires comparator)
set s;
set_init(&s, sizeof(int), compare_int);
// Insertion and lookup
int value = 30;
set_insert(&s, &value);
bool contains = set_contains(&s, &value);
// Removal
bool removed = set_erase(&s, &value);
// Information
size_t set_size = set_size(&s);
bool set_empty = set_empty(&s);
// Cleanup
set_clear(&s);
set_free(&s);// Initialization (requires comparator)
priority_queue pq;
priority_queue_init(&pq, sizeof(int), compare_int);
// Push and pop
int values[] = {5, 2, 8, 1};
for (int i = 0; i < 4; i++) {
priority_queue_push(&pq, &values[i]);
}
priority_queue_pop(&pq);
// Access top
int* top = (int*)priority_queue_top(&pq);
// Information
size_t pq_size = priority_queue_size(&pq);
bool pq_empty = priority_queue_empty(&pq);
// Cleanup
priority_queue_free(&pq);// Initialization
deque dq;
deque_init(&dq, sizeof(int));
// Push operations
int value = 15;
deque_push_front(&dq, &value);
deque_push_back(&dq, &value);
// Pop operations
deque_pop_front(&dq);
deque_pop_back(&dq);
// Access
int* front = (int*)deque_front(&dq);
int* back = (int*)deque_back(&dq);
// Information
size_t deque_size = deque_size(&dq);
bool deque_empty = deque_empty(&dq);
// Cleanup
deque_free(&dq);// Initialization
list l;
list_init(&l, sizeof(int));
// Push operations
int value = 25;
list_push_front(&l, &value);
list_push_back(&l, &value);
// Pop operations
list_pop_front(&l);
list_pop_back(&l);
// Insertion and deletion
list_insert(&l, index, &value);
list_erase(&l, index);
// Access
int* front = (int*)list_front(&l);
int* back = (int*)list_back(&l);
// Information
size_t list_size = list_size(&l);
bool list_empty = list_empty(&l);
// Cleanup
list_free(&l);int arr[] = {5, 2, 8, 1, 9};
size_t length = 5;
// Bubble Sort
bubble_sort(arr, sizeof(int), length, compare_int);
// Insertion Sort
insertion_sort(arr, sizeof(int), length, compare_int);
// Selection Sort
selection_sort(arr, sizeof(int), length, compare_int);
// Merge Sort
merge_sort(arr, sizeof(int), length, compare_int);
// Quick Sort
quick_sort(arr, sizeof(int), length, compare_int);
// Heap Sort
heap_sort(arr, sizeof(int), length, compare_int);
// Counting Sort (integer arrays only)
counting_sort(arr, length);
// Radix Sort (integer arrays only)
radix_sort(arr, length);
// Check if sorted
bool sorted = is_sorted(arr, sizeof(int), length, compare_int);int arr[] = {1, 2, 3, 4, 5, 5, 6};
size_t length = 7;
int key = 5;
// Linear Search
int index = linear_search(arr, sizeof(int), length, &key, compare_int);
// Binary Search (requires sorted array)
int bin_index = binary_search(arr, sizeof(int), length, &key, compare_int);
// Binary Search First Occurrence
int first_index = binary_search_first(arr, sizeof(int), length, &key, compare_int);
// Binary Search Last Occurrence
int last_index = binary_search_last(arr, sizeof(int), length, &key, compare_int);
// Exponential Search
int exp_index = exponential_search(arr, sizeof(int), length, &key, compare_int);
// Jump Search
int jump_index = jump_search(arr, sizeof(int), length, &key, compare_int);
// Interpolation Search (integer arrays only)
int interp_index = interpolation_search(arr, length, key);int arr[] = {1, 2, 3, 2, 4, 2, 5};
size_t length = 7;
int target = 2;
// Finding elements
int found_index = find(arr, sizeof(int), length, &target, compare_int);
int found_if_index = find_if(arr, sizeof(int), length, is_even_predicate);
// Counting elements
int count = count(arr, sizeof(int), length, &target, compare_int);
int count_if_result = count_if(arr, sizeof(int), length, is_even_predicate);
// Min/Max elements
int* min_elem = (int*)min_element(arr, sizeof(int), length, compare_int);
int* max_elem = (int*)max_element(arr, sizeof(int), length, compare_int);
// Accumulation
int sum = 0;
accumulate(arr, sizeof(int), length, &sum, add_elements);
// For Each
for_each(arr, sizeof(int), length, print_element);
// Copying
int dest[7];
copy(arr, dest, sizeof(int), length);
// Conditional Copy
size_t copied_count;
copy_if(arr, dest, sizeof(int), length, is_even_predicate, &copied_count);
// Filling
int fill_value = 0;
fill(arr, sizeof(int), length, &fill_value);
// Transformation
transform(src, dest, sizeof(int), length, square_element);
// Partitioning
size_t partition_idx;
partition(arr, sizeof(int), length, is_even_predicate, &partition_idx);
// Rotation
rotate(arr, sizeof(int), length, 2); // Rotate left by 2 positions
// Unique elements
size_t new_length;
unique(arr, sizeof(int), length, compare_int, &new_length);
// Nth element (partial sort)
nth_element(arr, sizeof(int), length, 3, compare_int); // 4th smallest element
// Permutation check
bool is_perm = is_permutation(arr1, arr2, sizeof(int), length, compare_int);// Splitting strings
int count;
char** tokens = string_split("hello,world,test", ",", &count);
// Use tokens...
for (int i = 0; i < count; i++) free(tokens[i]);
free(tokens);
// Joining strings
char* arr[] = {"hello", "world", "test"};
char* joined = string_join(arr, 3, ", ");
// Use joined...
free(joined);
// Trimming
char* trimmed = string_trim(" hello world ");
// Use trimmed...
free(trimmed);
// Case conversion
char* upper = string_to_upper("Hello");
char* lower = string_to_lower("Hello");
// Use upper/lower...
free(upper);
free(lower);
// Replacement
char* replaced = string_replace("hello world", "world", "there");
// Use replaced...
free(replaced);
// Checks
bool starts = string_starts_with("hello world", "hello");
bool ends = string_ends_with("hello world", "world");
bool contains = string_contains("hello world", "lo wo");
// Reverse
char* reversed = string_reverse("hello");
// Use reversed...
free(reversed);
// Case-insensitive comparison
int cmp = string_compare_nocase("Hello", "hello"); // Returns 0
// Duplication
char* dup = string_duplicate("hello");
// Use dup...
free(dup);// Seeding
random_seed((unsigned int)time(NULL));
// Random numbers
int rand_int = random_int(1, 100);
double rand_float = random_float(0.0, 1.0);
// Shuffling arrays
int arr[] = {1, 2, 3, 4, 5};
shuffle(arr, sizeof(int), 5);
// Random choice
int* choice = (int*)random_choice(arr, sizeof(int), 5);// Timing code execution
clock_t start;
double start_time = timer_start(&start);
// Code to time...
for (int i = 0; i < 1000000; i++) { }
double elapsed = timer_end(start);
printf("Elapsed time: %f seconds\n", elapsed);
// Sleep
sleep_ms(1000); // Sleep for 1 second// Comparisons
int a = 5, b = 10;
int* min_val = (int*)min(&a, &b, compare_int);
int* max_val = (int*)max(&a, &b, compare_int);
// Clamping
int value = 15, low = 0, high = 10;
clamp(&value, &low, &high, sizeof(int), compare_int);
// value is now 10
// Basic math
int absolute = abs_val(-5); // 5
long long gcd_val = gcd(48, 18); // 6
long long lcm_val = lcm(12, 18); // 36
bool prime = is_prime(17); // true
long long power_val = power(2, 8); // 256// Safe memory allocation
int* arr = (int*)safe_malloc(10 * sizeof(int));
arr = (int*)safe_realloc(arr, 20 * sizeof(int));
int* zero_arr = (int*)safe_calloc(10, sizeof(int));
// Don't forget to free!
free(arr);
free(zero_arr);// Built-in comparators
int cmp_int = compare_int(&a, &b);
int cmp_float = compare_float(&f1, &f2);
int cmp_str = compare_string(&str1, &str2);
// Reverse comparator
int (*reverse_cmp)(const void*, const void*) =
(int (*)(const void*, const void*))compare_reverse;
int rev_cmp = reverse_cmp(&a, &b, compare_int);
// Example predicate functions
bool is_even_predicate(void* element) {
int* value = (int*)element;
return *value % 2 == 0;
}
void add_elements(void* result, void* element) {
int* sum = (int*)result;
int* value = (int*)element;
*sum += *value;
}
void print_element(void* element) {
int* value = (int*)element;
printf("%d ", *value);
}
void square_element(void* src, void* dest) {
int* src_val = (int*)src;
int* dest_val = (int*)dest;
*dest_val = (*src_val) * (*src_val);
}#include "cstl.h"
#include <stdio.h>
int main() {
// Vector example
vector v;
vector_init(&v, sizeof(int));
for (int i = 0; i < 10; i++) {
vector_push_back(&v, &i);
}
printf("Vector size: %zu\n", vector_size(&v));
for (size_t i = 0; i < vector_size(&v); i++) {
int* elem = (int*)vector_get(&v, i);
printf("%d ", *elem);
}
printf("\n");
vector_free(&v);
// Map example
unordered_map m;
map_init(&m);
int values[] = {100, 200, 300};
map_insert(&m, "key1", &values[0], sizeof(int));
map_insert(&m, "key2", &values[1], sizeof(int));
int* retrieved = (int*)map_get(&m, "key1");
if (retrieved) {
printf("Value for key1: %d\n", *retrieved);
}
map_free(&m);
// Sorting example
int arr[] = {5, 2, 8, 1, 9};
size_t len = 5;
quick_sort(arr, sizeof(int), len, compare_int);
printf("Sorted array: ");
for (size_t i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}- This comprehensive C STL library provides type-safe, generic containers and algorithms similar to C++ STL, making data structure manipulation in C much more convenient and safe.
Table of Contents
• Basic Data Types
• Structures and Custom Types
• String Operations
• Complex Data Structures
• Mixed Type Examples
#include "cstl.h"
#include <stdio.h>
void integer_examples() {
printf("=== INTEGER EXAMPLES ===\n");
// Vector of integers
vector int_vec;
vector_init(&int_vec, sizeof(int));
int numbers[] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
vector_push_back(&int_vec, &numbers[i]);
}
printf("Integer vector: ");
for (size_t i = 0; i < vector_size(&int_vec); i++) {
int* val = (int*)vector_get(&int_vec, i);
printf("%d ", *val);
}
printf("\n");
// Map with integer values
unordered_map int_map;
map_init(&int_map);
int map_values[] = {100, 200, 300};
map_insert(&int_map, "age", &map_values[0], sizeof(int));
map_insert(&int_map, "score", &map_values[1], sizeof(int));
map_insert(&int_map, "count", &map_values[2], sizeof(int));
int* age = (int*)map_get(&int_map, "age");
if (age) {
printf("Age from map: %d\n", *age);
}
// Set of integers
set int_set;
set_init(&int_set, sizeof(int), compare_int);
int set_values[] = {1, 2, 3, 2, 1, 4, 5};
for (int i = 0; i < 7; i++) {
set_insert(&int_set, &set_values[i]);
}
printf("Integer set (unique values): ");
for (size_t i = 0; i < set_size(&int_set); i++) {
int* val = (int*)vector_get((vector*)&int_set, i);
printf("%d ", *val);
}
printf("\n");
// Sorting integers
int sort_arr[] = {64, 34, 25, 12, 22, 11, 90};
size_t sort_len = 7;
quick_sort(sort_arr, sizeof(int), sort_len, compare_int);
printf("Sorted integers: ");
for (size_t i = 0; i < sort_len; i++) {
printf("%d ", sort_arr[i]);
}
printf("\n");
// Cleanup
vector_free(&int_vec);
map_free(&int_map);
set_free(&int_set);
}void float_examples() {
printf("\n=== FLOAT/DOUBLE EXAMPLES ===\n");
// Vector of doubles
vector double_vec;
vector_init(&double_vec, sizeof(double));
double temperatures[] = {23.5, 18.7, 32.1, 15.3, 27.8};
for (int i = 0; i < 5; i++) {
vector_push_back(&double_vec, &temperatures[i]);
}
printf("Double vector: ");
for (size_t i = 0; i < vector_size(&double_vec); i++) {
double* val = (double*)vector_get(&double_vec, i);
printf("%.1f ", *val);
}
printf("\n");
// Map with float values
unordered_map float_map;
map_init(&float_map);
float prices[] = {19.99f, 29.99f, 9.99f};
map_insert(&float_map, "book", &prices[0], sizeof(float));
map_insert(&float_map, "shirt", &prices[1], sizeof(float));
map_insert(&float_map, "coffee", &prices[2], sizeof(float));
float* book_price = (float*)map_get(&float_map, "book");
if (book_price) {
printf("Book price: $%.2f\n", *book_price);
}
// Sorting doubles
double double_arr[] = {3.14, 2.71, 1.41, 1.73, 0.57};
size_t double_len = 5;
bubble_sort(double_arr, sizeof(double), double_len, compare_float);
printf("Sorted doubles: ");
for (size_t i = 0; i < double_len; i++) {
printf("%.2f ", double_arr[i]);
}
printf("\n");
// Priority queue with doubles
priority_queue double_pq;
priority_queue_init(&double_pq, sizeof(double), compare_float);
double pq_values[] = {5.5, 2.2, 8.8, 1.1, 9.9};
for (int i = 0; i < 5; i++) {
priority_queue_push(&double_pq, &pq_values[i]);
}
printf("Priority queue (max first): ");
while (!priority_queue_empty(&double_pq)) {
double* top = (double*)priority_queue_top(&double_pq);
printf("%.1f ", *top);
priority_queue_pop(&double_pq);
}
printf("\n");
// Cleanup
vector_free(&double_vec);
map_free(&float_map);
priority_queue_free(&double_pq);
}void char_examples() {
printf("\n=== CHARACTER EXAMPLES ===\n");
// Vector of characters
vector char_vec;
vector_init(&char_vec, sizeof(char));
char letters[] = {'A', 'B', 'C', 'D', 'E'};
for (int i = 0; i < 5; i++) {
vector_push_back(&char_vec, &letters[i]);
}
printf("Character vector: ");
for (size_t i = 0; i < vector_size(&char_vec); i++) {
char* val = (char*)vector_get(&char_vec, i);
printf("%c ", *val);
}
printf("\n");
// Set of characters
set char_set;
set_init(&char_set, sizeof(char), compare_int); // chars are integers
char set_chars[] = {'a', 'b', 'c', 'a', 'b', 'd'};
for (int i = 0; i < 6; i++) {
set_insert(&char_set, &set_chars[i]);
}
printf("Character set (unique): ");
for (size_t i = 0; i < set_size(&char_set); i++) {
char* val = (char*)vector_get((vector*)&char_set, i);
printf("%c ", *val);
}
printf("\n");
// Stack of characters
stack char_stack;
stack_init(&char_stack, sizeof(char));
char stack_chars[] = {'X', 'Y', 'Z'};
for (int i = 0; i < 3; i++) {
stack_push(&char_stack, &stack_chars[i]);
}
printf("Stack pop order: ");
while (!stack_empty(&char_stack)) {
char* top = (char*)stack_top(&char_stack);
printf("%c ", *top);
stack_pop(&char_stack);
}
printf("\n");
// Cleanup
vector_free(&char_vec);
set_free(&char_set);
stack_free(&char_stack);
}void bool_examples() {
printf("\n=== BOOLEAN EXAMPLES ===\n");
// Vector of booleans
vector bool_vec;
vector_init(&bool_vec, sizeof(bool));
bool flags[] = {true, false, true, true, false};
for (int i = 0; i < 5; i++) {
vector_push_back(&bool_vec, &flags[i]);
}
printf("Boolean vector: ");
for (size_t i = 0; i < vector_size(&bool_vec); i++) {
bool* val = (bool*)vector_get(&bool_vec, i);
printf("%s ", *val ? "true" : "false");
}
printf("\n");
// Count true values using count_if
int true_count = count_if(bool_vec.data, sizeof(bool), vector_size(&bool_vec),
[](void* elem) { return *(bool*)elem; });
printf("Number of true values: %d\n", true_count);
// Queue of booleans
queue bool_queue;
queue_init(&bool_queue, sizeof(bool));
bool queue_bools[] = {true, false, true};
for (int i = 0; i < 3; i++) {
queue_enqueue(&bool_queue, &queue_bools[i]);
}
printf("Queue values: ");
while (!queue_empty(&bool_queue)) {
bool* front = (bool*)queue_front(&bool_queue);
printf("%s ", *front ? "true" : "false");
queue_dequeue(&bool_queue);
}
printf("\n");
// Cleanup
vector_free(&bool_vec);
queue_free(&bool_queue);
}typedef struct {
char name[50];
int age;
double salary;
} Person;
// Comparator for Person by age
int compare_person_by_age(const void* a, const void* b) {
const Person* p1 = (const Person*)a;
const Person* p2 = (const Person*)b;
return (p1->age > p2->age) - (p1->age < p2->age);
}
// Comparator for Person by salary
int compare_person_by_salary(const void* a, const void* b) {
const Person* p1 = (const Person*)a;
const Person* p2 = (const Person*)b;
return (p1->salary > p2->salary) - (p1->salary < p2->salary);
}
// Comparator for Person by name
int compare_person_by_name(const void* a, const void* b) {
const Person* p1 = (const Person*)a;
const Person* p2 = (const Person*)b;
return strcmp(p1->name, p2->name);
}
void person_examples() {
printf("\n=== PERSON STRUCTURE EXAMPLES ===\n");
// Vector of Person structures
vector person_vec;
vector_init(&person_vec, sizeof(Person));
Person people[] = {
{"Alice", 30, 50000.0},
{"Bob", 25, 45000.0},
{"Charlie", 35, 60000.0},
{"Diana", 28, 52000.0}
};
for (int i = 0; i < 4; i++) {
vector_push_back(&person_vec, &people[i]);
}
printf("People vector:\n");
for (size_t i = 0; i < vector_size(&person_vec); i++) {
Person* p = (Person*)vector_get(&person_vec, i);
printf(" %s, Age: %d, Salary: $%.2f\n", p->name, p->age, p->salary);
}
// Sort by age
quick_sort(person_vec.data, sizeof(Person), vector_size(&person_vec),
compare_person_by_age);
printf("\nSorted by age:\n");
for (size_t i = 0; i < vector_size(&person_vec); i++) {
Person* p = (Person*)vector_get(&person_vec, i);
printf(" %s, Age: %d\n", p->name, p->age);
}
// Sort by salary
quick_sort(person_vec.data, sizeof(Person), vector_size(&person_vec),
compare_person_by_salary);
printf("\nSorted by salary:\n");
for (size_t i = 0; i < vector_size(&person_vec); i++) {
Person* p = (Person*)vector_get(&person_vec, i);
printf(" %s, Salary: $%.2f\n", p->name, p->salary);
}
// Map with Person values
unordered_map person_map;
map_init(&person_map);
Person bob = {"Bob Smith", 40, 75000.0};
Person alice = {"Alice Johnson", 35, 80000.0};
map_insert(&person_map, "employee1", &bob, sizeof(Person));
map_insert(&person_map, "employee2", &alice, sizeof(Person));
Person* retrieved = (Person*)map_get(&person_map, "employee1");
if (retrieved) {
printf("\nRetrieved employee: %s, Age: %d\n", retrieved->name, retrieved->age);
}
// Set of Person (by name)
set person_set;
set_init(&person_set, sizeof(Person), compare_person_by_name);
Person unique_people[] = {
{"John", 25, 40000.0},
{"Jane", 30, 50000.0},
{"John", 35, 60000.0} // Duplicate name
};
for (int i = 0; i < 3; i++) {
set_insert(&person_set, &unique_people[i]);
}
printf("\nUnique people by name (set size: %zu):\n", set_size(&person_set));
for (size_t i = 0; i < set_size(&person_set); i++) {
Person* p = (Person*)vector_get((vector*)&person_set, i);
printf(" %s, Age: %d\n", p->name, p->age);
}
// Cleanup
vector_free(&person_vec);
map_free(&person_map);
set_free(&person_set);
}typedef struct {
int x;
int y;
} Point;
// Comparator for Point by x coordinate
int compare_point_by_x(const void* a, const void* b) {
const Point* p1 = (const Point*)a;
const Point* p2 = (const Point*)b;
return (p1->x > p2->x) - (p1->x < p2->x);
}
// Comparator for Point by y coordinate
int compare_point_by_y(const void* a, const void* b) {
const Point* p1 = (const Point*)a;
const Point* p2 = (const Point*)b;
return (p1->y > p2->y) - (p1->y < p2->y);
}
// Distance from origin comparator
int compare_point_by_distance(const void* a, const void* b) {
const Point* p1 = (const Point*)a;
const Point* p2 = (const Point*)b;
double dist1 = sqrt(p1->x * p1->x + p1->y * p1->y);
double dist2 = sqrt(p2->x * p2->x + p2->y * p2->y);
return (dist1 > dist2) - (dist1 < dist2);
}
void point_examples() {
printf("\n=== POINT STRUCTURE EXAMPLES ===\n");
// Vector of Points
vector point_vec;
vector_init(&point_vec, sizeof(Point));
Point points[] = {
{1, 2}, {3, 4}, {5, 1}, {2, 7}, {4, 3}
};
for (int i = 0; i < 5; i++) {
vector_push_back(&point_vec, &points[i]);
}
printf("Points vector:\n");
for (size_t i = 0; i < vector_size(&point_vec); i++) {
Point* p = (Point*)vector_get(&point_vec, i);
printf(" (%d, %d)\n", p->x, p->y);
}
// Sort by x coordinate
quick_sort(point_vec.data, sizeof(Point), vector_size(&point_vec),
compare_point_by_x);
printf("\nSorted by x coordinate:\n");
for (size_t i = 0; i < vector_size(&point_vec); i++) {
Point* p = (Point*)vector_get(&point_vec, i);
printf(" (%d, %d)\n", p->x, p->y);
}
// Sort by distance from origin
quick_sort(point_vec.data, sizeof(Point), vector_size(&point_vec),
compare_point_by_distance);
printf("\nSorted by distance from origin:\n");
for (size_t i = 0; i < vector_size(&point_vec); i++) {
Point* p = (Point*)vector_get(&point_vec, i);
double dist = sqrt(p->x * p->x + p->y * p->y);
printf(" (%d, %d) - distance: %.2f\n", p->x, p->y, dist);
}
// Deque of Points
deque point_deque;
deque_init(&point_deque, sizeof(Point));
Point front_point = {0, 0};
Point back_point = {10, 10};
deque_push_front(&point_deque, &front_point);
deque_push_back(&point_deque, &back_point);
printf("\nDeque front: (%d, %d)\n",
((Point*)deque_front(&point_deque))->x,
((Point*)deque_front(&point_deque))->y);
printf("Deque back: (%d, %d)\n",
((Point*)deque_back(&point_deque))->x,
((Point*)deque_back(&point_deque))->y);
// Cleanup
vector_free(&point_vec);
deque_free(&point_deque);
}void string_examples() {
printf("\n=== STRING OPERATIONS ===\n");
// Vector of strings (char*)
vector str_vec;
vector_init(&str_vec, sizeof(char*));
char* names[] = {"Alice", "Bob", "Charlie", "Diana", "Eve"};
for (int i = 0; i < 5; i++) {
char* name_copy = string_duplicate(names[i]);
vector_push_back(&str_vec, &name_copy);
}
printf("String vector: ");
for (size_t i = 0; i < vector_size(&str_vec); i++) {
char** name_ptr = (char**)vector_get(&str_vec, i);
printf("%s ", *name_ptr);
}
printf("\n");
// Sort strings
quick_sort(str_vec.data, sizeof(char*), vector_size(&str_vec), compare_string);
printf("Sorted strings: ");
for (size_t i = 0; i < vector_size(&str_vec); i++) {
char** name_ptr = (char**)vector_get(&str_vec, i);
printf("%s ", *name_ptr);
}
printf("\n");
// Map with string keys and values
unordered_map str_map;
map_init(&str_map);
char* capitals[] = {"France", "Germany", "Italy"};
char* cities[] = {"Paris", "Berlin", "Rome"};
for (int i = 0; i < 3; i++) {
map_insert(&str_map, capitals[i], &cities[i], sizeof(char*));
}
char** capital = (char**)map_get(&str_map, "France");
if (capital) {
printf("Capital of France: %s\n", *capital);
}
// String splitting and joining
char* text = "apple,banana,cherry,date";
int token_count;
char** tokens = string_split(text, ",", &token_count);
printf("Split tokens (%d): ", token_count);
for (int i = 0; i < token_count; i++) {
printf("%s ", tokens[i]);
}
printf("\n");
char* joined = string_join(tokens, token_count, " | ");
printf("Joined string: %s\n", joined);
// String transformations
char* original = " Hello World! ";
char* trimmed = string_trim(original);
char* upper = string_to_upper(trimmed);
char* lower = string_to_lower(trimmed);
printf("Original: '%s'\n", original);
printf("Trimmed: '%s'\n", trimmed);
printf("Upper: '%s'\n", upper);
printf("Lower: '%s'\n", lower);
// String replacement
char* sentence = "I like cats and cats like me";
char* replaced = string_replace(sentence, "cats", "dogs");
printf("Replaced: %s\n", replaced);
// Cleanup
for (size_t i = 0; i < vector_size(&str_vec); i++) {
char** name_ptr = (char**)vector_get(&str_vec, i);
free(*name_ptr);
}
vector_free(&str_vec);
map_free(&str_map);
for (int i = 0; i < token_count; i++) {
free(tokens[i]);
}
free(tokens);
free(joined);
free(trimmed);
free(upper);
free(lower);
free(replaced);
}typedef struct {
char title[100];
char author[50];
int year;
double price;
} Book;
typedef struct {
char name[100];
vector books; // vector of Book
} Library;
int compare_book_by_title(const void* a, const void* b) {
const Book* b1 = (const Book*)a;
const Book* b2 = (const Book*)b;
return strcmp(b1->title, b2->title);
}
int compare_book_by_year(const void* a, const void* b) {
const Book* b1 = (const Book*)a;
const Book* b2 = (const Book*)b;
return (b1->year > b2->year) - (b1->year < b2->year);
}
void library_examples() {
printf("\n=== LIBRARY (NESTED STRUCTURES) EXAMPLE ===\n");
// Create books
Book book1 = {"The Great Gatsby", "F. Scott Fitzgerald", 1925, 12.99};
Book book2 = {"1984", "George Orwell", 1949, 10.99};
Book book3 = {"To Kill a Mockingbird", "Harper Lee", 1960, 11.99};
Book book4 = {"Pride and Prejudice", "Jane Austen", 1813, 9.99};
// Create library
Library library;
strcpy(library.name, "City Central Library");
vector_init(&library.books, sizeof(Book));
// Add books to library
vector_push_back(&library.books, &book1);
vector_push_back(&library.books, &book2);
vector_push_back(&library.books, &book3);
vector_push_back(&library.books, &book4);
printf("Library: %s\n", library.name);
printf("Books (%zu):\n", vector_size(&library.books));
for (size_t i = 0; i < vector_size(&library.books); i++) {
Book* book = (Book*)vector_get(&library.books, i);
printf(" '%s' by %s (%d) - $%.2f\n",
book->title, book->author, book->year, book->price);
}
// Sort books by title
quick_sort(library.books.data, sizeof(Book), vector_size(&library.books),
compare_book_by_title);
printf("\nBooks sorted by title:\n");
for (size_t i = 0; i < vector_size(&library.books); i++) {
Book* book = (Book*)vector_get(&library.books, i);
printf(" %s\n", book->title);
}
// Sort books by year
quick_sort(library.books.data, sizeof(Book), vector_size(&library.books),
compare_book_by_year);
printf("\nBooks sorted by year:\n");
for (size_t i = 0; i < vector_size(&library.books); i++) {
Book* book = (Book*)vector_get(&library.books, i);
printf(" %s (%d)\n", book->title, book->year);
}
// Find books after 1950
printf("\nBooks published after 1950:\n");
for (size_t i = 0; i < vector_size(&library.books); i++) {
Book* book = (Book*)vector_get(&library.books, i);
if (book->year > 1950) {
printf(" %s (%d)\n", book->title, book->year);
}
}
// Cleanup
vector_free(&library.books);
}typedef enum { INT_TYPE, DOUBLE_TYPE, STRING_TYPE } DataType;
typedef struct {
DataType type;
union {
int int_value;
double double_value;
char* string_value;
};
} Variant;
int compare_variant(const void* a, const void* b) {
const Variant* v1 = (const Variant*)a;
const Variant* v2 = (const Variant*)b;
if (v1->type != v2->type) {
return v1->type - v2->type;
}
switch (v1->type) {
case INT_TYPE:
return compare_int(&v1->int_value, &v2->int_value);
case DOUBLE_TYPE:
return compare_float(&v1->double_value, &v2->double_value);
case STRING_TYPE:
return compare_string(&v1->string_value, &v2->string_value);
default:
return 0;
}
}
void variant_examples() {
printf("\n=== VARIANT (MIXED TYPES) EXAMPLE ===\n");
vector variant_vec;
vector_init(&variant_vec, sizeof(Variant));
// Add different types
Variant v1 = {INT_TYPE, .int_value = 42};
Variant v2 = {DOUBLE_TYPE, .double_value = 3.14159};
Variant v3 = {STRING_TYPE, .string_value = string_duplicate("Hello")};
Variant v4 = {INT_TYPE, .int_value = 100};
Variant v5 = {DOUBLE_TYPE, .double_value = 2.71828};
vector_push_back(&variant_vec, &v1);
vector_push_back(&variant_vec, &v2);
vector_push_back(&variant_vec, &v3);
vector_push_back(&variant_vec, &v4);
vector_push_back(&variant_vec, &v5);
printf("Variant vector:\n");
for (size_t i = 0; i < vector_size(&variant_vec); i++) {
Variant* v = (Variant*)vector_get(&variant_vec, i);
switch (v->type) {
case INT_TYPE:
printf(" INT: %d\n", v->int_value);
break;
case DOUBLE_TYPE:
printf(" DOUBLE: %.5f\n", v->double_value);
break;
case STRING_TYPE:
printf(" STRING: %s\n", v->string_value);
break;
}
}
// Sort variants
quick_sort(variant_vec.data, sizeof(Variant), vector_size(&variant_vec),
compare_variant);
printf("\nSorted variants:\n");
for (size_t i = 0; i < vector_size(&variant_vec); i++) {
Variant* v = (Variant*)vector_get(&variant_vec, i);
switch (v->type) {
case INT_TYPE:
printf(" INT: %d\n", v->int_value);
break;
case DOUBLE_TYPE:
printf(" DOUBLE: %.5f\n", v->double_value);
break;
case STRING_TYPE:
printf(" STRING: %s\n", v->string_value);
break;
}
}
// Cleanup
for (size_t i = 0; i < vector_size(&variant_vec); i++) {
Variant* v = (Variant*)vector_get(&variant_vec, i);
if (v->type == STRING_TYPE) {
free(v->string_value);
}
}
vector_free(&variant_vec);
}void comprehensive_example() {
printf("\n=== COMPREHENSIVE EXAMPLE ===\n");
// 1. Vector of different types
vector int_vec, double_vec, str_vec;
vector_init(&int_vec, sizeof(int));
vector_init(&double_vec, sizeof(double));
vector_init(&str_vec, sizeof(char*));
// 2. Map with different value types
unordered_map mixed_map;
map_init(&mixed_map);
// 3. Set of integers
set int_set;
set_init(&int_set, sizeof(int), compare_int);
// 4. Stack and Queue
stack int_stack;
queue int_queue;
stack_init(&int_stack, sizeof(int));
queue_init(&int_queue, sizeof(int));
// 5. Priority Queue
priority_queue int_pq;
priority_queue_init(&int_pq, sizeof(int), compare_int);
// Populate data
printf("Populating containers...\n");
// Vector data
for (int i = 1; i <= 5; i++) {
vector_push_back(&int_vec, &i);
double d = i * 1.1;
vector_push_back(&double_vec, &d);
char str[20];
sprintf(str, "String%d", i);
char* str_copy = string_duplicate(str);
vector_push_back(&str_vec, &str_copy);
}
// Map data
int age = 25;
double salary = 50000.0;
char* name = "John Doe";
map_insert(&mixed_map, "age", &age, sizeof(int));
map_insert(&mixed_map, "salary", &salary, sizeof(double));
map_insert(&mixed_map, "name", &name, sizeof(char*));
// Set data
int set_values[] = {1, 2, 3, 2, 1, 4, 5};
for (int i = 0; i < 7; i++) {
set_insert(&int_set, &set_values[i]);
}
// Stack and Queue data
for (int i = 1; i <= 3; i++) {
stack_push(&int_stack, &i);
queue_enqueue(&int_queue, &i);
}
// Priority Queue data
int pq_values[] = {5, 2, 8, 1, 9};
for (int i = 0; i < 5; i++) {
priority_queue_push(&int_pq, &pq_values[i]);
}
// Display all data
printf("\n=== DISPLAYING ALL CONTAINERS ===\n");
printf("Integer Vector: ");
for (size_t i = 0; i < vector_size(&int_vec); i++) {
printf("%d ", *(int*)vector_get(&int_vec, i));
}
printf("\n");
printf("Double Vector: ");
for (size_t i = 0; i < vector_size(&double_vec); i++) {
printf("%.1f ", *(double*)vector_get(&double_vec, i));
}
printf("\n");
printf("String Vector: ");
for (size_t i = 0; i < vector_size(&str_vec); i++) {
printf("%s ", *(char**)vector_get(&str_vec, i));
}
printf("\n");
printf("Mixed Map:\n");
int* map_age = (int*)map_get(&mixed_map, "age");
double* map_salary = (double*)map_get(&mixed_map, "salary");
char** map_name = (char**)map_get(&mixed_map, "name");
if (map_age) printf(" Age: %d\n", *map_age);
if (map_salary) printf(" Salary: $%.2f\n", *map_salary);
if (map_name) printf(" Name: %s\n", *map_name);
printf("Integer Set: ");
for (size_t i = 0; i < set_size(&int_set); i++) {
printf("%d ", *(int*)vector_get((vector*)&int_set, i));
}
printf("\n");
printf("Stack (LIFO): ");
while (!stack_empty(&int_stack)) {
printf("%d ", *(int*)stack_top(&int_stack));
stack_pop(&int_stack);
}
printf("\n");
printf("Queue (FIFO): ");
while (!queue_empty(&int_queue)) {
printf("%d ", *(int*)queue_front(&int_queue));
queue_dequeue(&int_queue);
}
printf("\n");
printf("Priority Queue: ");
while (!priority_queue_empty(&int_pq)) {
printf("%d ", *(int*)priority_queue_top(&int_pq));
priority_queue_pop(&int_pq);
}
printf("\n");
// Cleanup everything
printf("\nCleaning up...\n");
vector_free(&int_vec);
vector_free(&double_vec);
// Free string vector elements
for (size_t i = 0; i < vector_size(&str_vec); i++) {
char** str_ptr = (char**)vector_get(&str_vec, i);
free(*str_ptr);
}
vector_free(&str_vec);
map_free(&mixed_map);
set_free(&int_set);
stack_free(&int_stack);
queue_free(&int_queue);
priority_queue_free(&int_pq);
printf("All containers cleaned up successfully!\n");
}#include "cstl.h"
vector numbers;
vector_init(&numbers, sizeof(int));
// Add some data
for (int i = 1; i <= 5; i++) {
vector_push_back(&numbers, &i);
}
// METHOD 1: Regular for loop
printf("Method 1 - Regular for loop:\n");
for (size_t i = 0; i < vector_size(&numbers); i++) {
int* num = (int*)vector_get(&numbers, i);
printf("numbers[%zu] = %d\n", i, *num);
}
// METHOD 2: While loop
printf("\nMethod 2 - While loop:\n");
size_t index = 0;
while (index < vector_size(&numbers)) {
int* num = (int*)vector_get(&numbers, index);
printf("numbers[%zu] = %d\n", index, *num);
index++;
}
vector_free(&numbers);#include "cstl.h"
unordered_map config;
map_init(&config);
// Add data
int port = 8080;
char* name = "Server";
map_insert(&config, "port", &port, sizeof(int));
map_insert(&config, "name", &name, sizeof(char*));
// Loop through known keys
printf("Map contents:\n");
const char* keys[] = {"port", "name"};
for (int i = 0; i < 2; i++) {
void* value = map_get(&config, keys[i]);
if (value) {
if (strcmp(keys[i], "port") == 0) {
printf(" %s: %d\n", keys[i], *(int*)value);
} else {
printf(" %s: %s\n", keys[i], *(char**)value);
}
}
}
map_free(&config);#include "cstl.h"
stack s;
stack_init(&s, sizeof(int));
// Add data
for (int i = 1; i <= 3; i++) {
stack_push(&s, &i);
}
// Loop through stack (destroys it)
printf("Stack contents (LIFO order):\n");
while (!stack_empty(&s)) {
int* top = (int*)stack_top(&s);
printf(" %d\n", *top);
stack_pop(&s); // This removes the element
}
stack_free(&s);#include "cstl.h"
queue q;
queue_init(&q, sizeof(int));
// Add data
for (int i = 1; i <= 3; i++) {
queue_enqueue(&q, &i);
}
// Loop through queue (destroys it)
printf("Queue contents (FIFO order):\n");
while (!queue_empty(&q)) {
int* front = (int*)queue_front(&q);
printf(" %d\n", *front);
queue_dequeue(&q); // This removes the element
}
queue_free(&q);#include "cstl.h"
vector names;
vector_init(&names, sizeof(char*));
// Add strings
char* name1 = "Alice";
char* name2 = "Bob";
char* name3 = "Charlie";
vector_push_back(&names, &name1);
vector_push_back(&names, &name2);
vector_push_back(&names, &name3);
// Loop through strings
printf("Names:\n");
for (size_t i = 0; i < vector_size(&names); i++) {
char** name_ptr = (char**)vector_get(&names, i);
printf(" %s\n", *name_ptr);
}
vector_free(&names);#include "cstl.h"
typedef struct {
char name[50];
int age;
} Person;
vector people;
vector_init(&people, sizeof(Person));
// Add people
Person p1 = {"Alice", 25};
Person p2 = {"Bob", 30};
Person p3 = {"Charlie", 35};
vector_push_back(&people, &p1);
vector_push_back(&people, &p2);
vector_push_back(&people, &p3);
// Loop through structures
printf("People:\n");
for (size_t i = 0; i < vector_size(&people); i++) {
Person* person = (Person*)vector_get(&people, i);
printf(" %s, %d years old\n", person->name, person->age);
}
vector_free(&people);#include "cstl.h"
// Non-destructive stack loop by using temporary stack
void print_stack_non_destructive(stack* s) {
stack temp;
stack_init(&temp, s->elementSize);
printf("Stack contents (non-destructive):\n");
// Copy to temp stack (reverses order)
while (!stack_empty(s)) {
void* top = stack_top(s);
stack_push(&temp, top);
stack_pop(s);
}
// Print and restore original stack
while (!stack_empty(&temp)) {
void* top = stack_top(&temp);
int* value = (int*)top;
printf(" %d\n", *value);
stack_push(s, top);
stack_pop(&temp);
}
stack_free(&temp);
}
// Usage
stack s;
stack_init(&s, sizeof(int));
int values[] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
stack_push(&s, &values[i]);
}
print_stack_non_destructive(&s);
printf("Original stack preserved, size: %zu\n", stack_size(&s));
stack_free(&s);#include <stdio.h>
#include "cstl.h"
int main() {
printf("=== STL CONTAINER LOOPS ===\n\n");
// Vector loop example
vector nums;
vector_init(&nums, sizeof(int));
for (int i = 10; i <= 50; i += 10) {
vector_push_back(&nums, &i);
}
printf("Vector loop:\n");
for (size_t i = 0; i < vector_size(&nums); i++) {
int* num = (int*)vector_get(&nums, i);
printf(" nums[%zu] = %d\n", i, *num);
}
// Modify elements in loop
printf("\nModified vector:\n");
for (size_t i = 0; i < vector_size(&nums); i++) {
int* num = (int*)vector_get(&nums, i);
*num *= 2; // Double each value
printf(" nums[%zu] = %d\n", i, *num);
}
vector_free(&nums);
return 0;
}1. Vectors: Use for (size_t i = 0; i < vector_size(&v); i++)
2. Maps: Need to know keys in advance (limitation of current implementation)
3. Stack/Queue: Loops are destructive by default
4. Always cast: (int*)vector_get(&v, i) or (char**) for strings
5. Modify in place: You can change values directly through pointers
int main() {
printf("C STL LIBRARY - COMPLETE DATA TYPE EXAMPLES\n");
printf("===========================================\n");
integer_examples();
float_examples();
char_examples();
bool_examples();
person_examples();
point_examples();
string_examples();
library_examples();
variant_examples();
comprehensive_example();
printf("\nAll examples completed successfully!\n");
return 0;
}1. All Basic Types: int, float, double, char, bool
2. Complex Structures: Person, Point, Book, Library
3. String Operations: C-strings with dynamic allocation
4. Mixed Types: Variant type using unions
5. All Containers: vector, map, set, stack, queue, priority_queue, deque, list
6. All Algorithms: Sorting, searching, utility functions
7. Memory Management: Proper allocation and cleanup
8. Type Safety: Generic containers with type-specific comparators
- This comprehensive example suite demonstrates that the C STL library can handle virtually any data type you might need in real-world applications