Skip to content

use case: comptime allocator #1291

@andrewrk

Description

@andrewrk

Here's an implementation of the Allocator interface at compile-time:

const std = @import("std");
const Allocator = std.mem.Allocator;
const Alignment = std.mem.Alignment;

pub const panic = std.debug.no_panic;

comptime {
    var map = std.AutoArrayHashMap(i32, i32).init(comptime_allocator);
    map.put(12, 34) catch unreachable;
}

pub const comptime_allocator: Allocator = .{
    .ptr = undefined,
    .vtable = &.{
        .alloc = comptimeAlloc,
        .resize = comptimeResize,
        .remap = comptimeRemap,
        .free = comptimeFree,
    },
};

fn comptimeAlloc(
    context: *anyopaque,
    len: usize,
    alignment: Alignment,
    return_address: usize,
) ?[*]u8 {
    _ = context;
    _ = return_address;
    if (!@inComptime()) unreachable;
    var bytes: [len]u8 align(alignment.toByteUnits()) = undefined;
    return &bytes;
}

fn comptimeResize(
    context: *anyopaque,
    memory: []u8,
    alignment: Alignment,
    new_len: usize,
    return_address: usize,
) bool {
    _ = memory;
    _ = context;
    _ = alignment;
    _ = return_address;
    _ = new_len;
    // Always returning false here ensures that callsites make new allocations that fit
    // better, avoiding wasted .cdata and .data memory.
    return false;
}

fn comptimeRemap(
    context: *anyopaque,
    memory: []u8,
    alignment: Alignment,
    new_len: usize,
    return_address: usize,
) ?[*]u8 {
    _ = context;
    _ = memory;
    _ = alignment;
    _ = new_len;
    _ = return_address;
    // Always returning false here ensures that callsites make new allocations that fit
    // better, avoiding wasted .cdata and .data memory.
    return null;
}

fn comptimeFree(
    context: *anyopaque,
    memory: []u8,
    alignment: Alignment,
    return_address: usize,
) void {
    _ = context;
    _ = memory;
    _ = alignment;
    _ = return_address;
    // Global variables are garbage-collected by the linker.
}

It works, with a caveat mentioned below by @mlugg.

This issue can be closed when:

  • It is added to the std lib, with test coverage
  • The caveat about auto-layout types is fixed

Related:

Metadata

Metadata

Assignees

No one assigned

    Labels

    use caseDescribes a real use case that is difficult or impossible, but does not propose a solution.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions