const std = @import("std");
pub fn gpaExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var list = std.ArrayList(i32).init(allocator);
defer list.deinit();
try list.append(10);
try list.append(20);
try list.append(30);
std.debug.print("List items: ", .{});
for (list.items) |item| {
std.debug.print("{} ", .{item});
}
std.debug.print("\n", .{});
if (list.items.len > 0) {
std.debug.print("First: {}\n", .{list.items[0]});
}
const last = list.pop();
std.debug.print("Popped: {}\n", .{last});
}
pub fn arenaExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var arena = std.heap.ArenaAllocator.init(gpa.allocator());
defer arena.deinit();
const allocator = arena.allocator();
const str1 = try allocator.dupe(u8, "Hello");
const str2 = try allocator.dupe(u8, "World");
const nums = try allocator.alloc(i32, 100);
std.debug.print("{s} {s}, allocated {} numbers\n", .{ str1, str2, nums.len });
}
pub fn fixedBufferExample() void {
var buffer: [1024]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buffer);
const allocator = fba.allocator();
const small_slice = allocator.alloc(u8, 100) catch {
std.debug.print("Allocation failed\n", .{});
return;
};
defer allocator.free(small_slice);
small_slice[0] = 'A';
std.debug.print("Fixed buffer byte: {}\n", .{small_slice[0]});
}
pub fn pageExample() !void {
const allocator = std.heap.page_allocator;
const big_slice = try allocator.alloc(u8, 1024 * 1024);
defer allocator.free(big_slice);
std.debug.print("Allocated {} bytes from page allocator\n", .{big_slice.len});
}
type LoggedAllocator = struct {
allocator: std.mem.Allocator,
bytes_allocated: usize,
};
fn loggedAlloc(ptr: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
const self = @ptrCast(*LoggedAllocator, @alignCast(ptr));
self.bytes_allocated += len;
std.debug.print("Allocated {} bytes (total: {})\n", .{ len, self.bytes_allocated });
return std.heap.page_allocator.vtable.alloc(ptr, len, ptr_align, ret_addr);
}
pub fn stringMapExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var map = std.StringHashMap(i32).init(allocator);
defer map.deinit();
try map.put("apple", 100);
try map.put("banana", 200);
try map.put("cherry", 300);
if (map.get("banana")) |value| {
std.debug.print("Banana price: {}\n", .{value});
}
var iter = map.iterator();
while (iter.next()) |entry| {
std.debug.print("{s}: {}\n", .{ entry.key_ptr.*, entry.value_ptr.* });
}
_ = map.remove("apple");
}
pub fn hashMapExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var map = std.AutoHashMap(u32, []const u8).init(allocator);
defer map.deinit();
try map.put(1, "one");
try map.put(2, "two");
try map.put(3, "three");
if (map.getPtr(2)) |ptr| {
ptr.* = "TWO";
}
std.debug.print("Entry count: {}\n", .{map.count()});
}
pub fn boundedArrayExample() void {
var arr = std.BoundedArray(i32, 10){};
arr.append(1) catch unreachable;
arr.append(2) catch unreachable;
arr.append(3) catch unreachable;
std.debug.print("Bounded array: ", .{});
for (arr.slice()) |item| {
std.debug.print("{} ", .{item});
}
std.debug.print("(len={}, capacity={})\n", .{ arr.len, arr.capacity() });
}
const Particle = struct {
x: f32,
y: f32,
vx: f32,
vy: f32,
active: bool,
};
pub fn multiArrayListExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var particles = std.MultiArrayList(Particle){};
defer particles.deinit(allocator);
try particles.append(allocator, .{ .x = 0, .y = 0, .vx = 1, .vy = 1, .active = true });
try particles.append(allocator, .{ .x = 10, .y = 5, .vx = -1, .vy = 0, .active = true });
try particles.append(allocator, .{ .x = 20, .y = 20, .vx = 0, .vy = -1, .active = false });
const slice = particles.slice();
for (slice.items(.x), slice.items(.y), slice.items(.active)) |x, y, active| {
std.debug.print("Particle at ({}, {}) active={}\n", .{ x, y, active });
}
}
pub fn linkedListExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var list = std.SinglyLinkedList(i32){};
var node1 = try allocator.create(std.SinglyLinkedList(i32).Node);
defer allocator.destroy(node1);
node1.data = 10;
var node2 = try allocator.create(std.SinglyLinkedList(i32).Node);
defer allocator.destroy(node2);
node2.data = 20;
list.prepend(node2);
list.prepend(node1);
var it = list.first;
while (it) |node| : (it = node.next) {
std.debug.print("Node: {}\n", .{node.data});
}
}
pub fn memoryPoolExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const Node = struct { value: i32, next: ?*@This() };
var pool = std.heap.MemoryPool(Node).init(allocator);
defer pool.deinit();
const n1 = try pool.create();
n1.* = .{ .value = 1, .next = null };
const n2 = try pool.create();
n2.* = .{ .value = 2, .next = n1 };
std.debug.print("Pool node: {}\n", .{n2.value});
pool.destroy(n1);
pool.destroy(n2);
}
pub fn main() !void {
try gpaExample();
try arenaExample();
fixedBufferExample();
try pageExample();
try stringMapExample();
try hashMapExample();
boundedArrayExample();
try multiArrayListExample();
try linkedListExample();
try memoryPoolExample();
}