Skip to documentation
SLOP

tiny.preserves.containers

Reference tiny.preserves containers

Defined in tiny.preserves.

A hash map and a hash set keyed by the package's values.

API (4)

Actions

Public operations.

No direct callersNo direct callstiny.preservescontainers
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callscontainersValueHashMapcontainersValueSetcontainersValueContext
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallstest sourcelib.preserves.src.containerstest: ValueHashMap finds permutation-...test sourcelib.preserves.src.containerstest: ValueHashMap stores and looks u...containersValueContextcontainersValueHashMap
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.preserves.src.containerstest: ValueSet tracks presencecontainersValueContextcontainersValueSet
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.preserves.src.containerstest: valueEqual freestanding wrapper...containersvalueEqual
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/preserves/src/containers.zig

zig
//! A hash map and a hash set keyed by the package's values. A lookup has to find a key whenever the//! key it is given is an equal value, including a set or dictionary that stores its items in//! another order. Two equal sets can store their items in different orders, and so can two equal//! dictionaries. A hash over the stored order would put such equal keys in different buckets.//!//! `ValueContext` gives the standard hash map the value's own hash and equality, which ignore the//! order in which a set or dictionary stores its items. `ValueHashMap` and `ValueSet` are the//! standard unmanaged hash map with that context, so every call that allocates takes the allocator//! as an argument. The map stores each key and value as given and frees only its own table, so the//! caller keeps every value's memory alive while it sits in the map.const std = @import("std");const value_mod = @import("value.zig");/// Returns the hashing context for `Value(D)` that the standard hash map expects. `ValueHashMap`/// and `ValueSet` pass it to Zig's standard hash map, so the map finds keys by value equality. The/// context holds no state, so every instance behaves the same.pub fn ValueContext(comptime D: type) type {    return struct {        /// Returns the hash of `v`, the same number `v.hash()` returns. Equal values get equal        /// hashes, whatever order a set or dictionary stores its items in.        pub fn hash(_: @This(), v: value_mod.Value(D)) u64 {            return v.hash();        }        /// Returns true when `a` and `b` are equal values, the same answer `a.eql(b)` gives.        pub fn eql(_: @This(), a: value_mod.Value(D), b: value_mod.Value(D)) bool {            return a.eql(b);        }    };}/// Returns the standard unmanaged hash map type from `Value(D)` keys to `Value(D)` values, keyed/// through `ValueContext(D)`. Code that maps one Preserves value to another declares one, for/// lookups by value equality. The map grows once it is 80 percent full. A lookup with a set key/// finds an entry stored under an equal set in another order, and the same holds for dictionaries./// The map copies no value memory, and `deinit` frees only the map's table.pub fn ValueHashMap(comptime D: type) type {    return std.HashMapUnmanaged(value_mod.Value(D), value_mod.Value(D), ValueContext(D), 80);}/// Returns the standard unmanaged hash map type with `Value(D)` keys and `void` values, keyed/// through `ValueContext(D)`. Code that tracks which values it has seen declares one of these. The/// set grows once it is 80 percent full. Adding an equal value a second time leaves the count/// unchanged. The set copies no value memory, and `deinit` frees only its table.pub fn ValueSet(comptime D: type) type {    return std.HashMapUnmanaged(value_mod.Value(D), void, ValueContext(D), 80);}/// Returns true when `a` and `b` are equal values, the same answer `a.eql(b)` gives. Generic code/// that passes equality as a function value calls it, for the method's answer in function form. The/// package root's `valueEqual` is a separate function with the same answer for values whose/// embedded values hold any pointer.pub fn valueEqual(comptime D: type, a: value_mod.Value(D), b: value_mod.Value(D)) bool {    return a.eql(b);}test "ValueHashMap stores and looks up by value" {    const NoEmbedded = @import("domain.zig").NoEmbedded;    const V = value_mod.Value(NoEmbedded);    const Map = ValueHashMap(NoEmbedded);    const allocator = std.testing.allocator;    var map: Map = .{};    defer map.deinit(allocator);    const k1 = V.initI128(1);    const k2 = V.initI128(2);    const v1 = V.initBoolean(true);    const v2 = V.initBoolean(false);    try map.put(allocator, k1, v1);    try map.put(allocator, k2, v2);    try std.testing.expectEqual(@as(usize, 2), map.count());    const got1 = map.get(V.initI128(1)).?;    try std.testing.expect(got1.eql(v1));    const got2 = map.get(V.initI128(2)).?;    try std.testing.expect(got2.eql(v2));    try std.testing.expect(map.get(V.initI128(99)) == null);}test "ValueHashMap finds permutation-equivalent unordered keys" {    const NoEmbedded = @import("domain.zig").NoEmbedded;    const V = value_mod.Value(NoEmbedded);    const Map = ValueHashMap(NoEmbedded);    const allocator = std.testing.allocator;    var map: Map = .{};    defer map.deinit(allocator);    var set_items_a = [_]V{ V.initI128(1), V.initI128(2) };    var set_items_b = [_]V{ V.initI128(2), V.initI128(1) };    const set_a = V.initSet(&set_items_a);    const set_b = V.initSet(&set_items_b);    try std.testing.expect(set_a.eql(set_b));    try std.testing.expectEqual(std.math.Order.eq, set_a.compare(set_b));    try std.testing.expectEqual(set_a.hash(), set_b.hash());    try map.put(allocator, set_a, V.initBoolean(true));    try std.testing.expect(map.get(set_b) != null);    var entries_a = [_]V.DictionaryEntry{        .{ .key = V.initI128(1), .value = V.initBoolean(true) },        .{ .key = V.initI128(2), .value = V.initBoolean(false) },    };    var entries_b = [_]V.DictionaryEntry{        .{ .key = V.initI128(2), .value = V.initBoolean(false) },        .{ .key = V.initI128(1), .value = V.initBoolean(true) },    };    const dictionary_a = V.initDictionary(&entries_a);    const dictionary_b = V.initDictionary(&entries_b);    try std.testing.expect(dictionary_a.eql(dictionary_b));    try std.testing.expectEqual(std.math.Order.eq, dictionary_a.compare(dictionary_b));    try std.testing.expectEqual(dictionary_a.hash(), dictionary_b.hash());    try map.put(allocator, dictionary_a, V.initBoolean(false));    try std.testing.expect(map.get(dictionary_b) != null);}test "ValueSet tracks presence" {    const NoEmbedded = @import("domain.zig").NoEmbedded;    const V = value_mod.Value(NoEmbedded);    const Set = ValueSet(NoEmbedded);    const allocator = std.testing.allocator;    var set: Set = .{};    defer set.deinit(allocator);    try set.put(allocator, V.initI128(1), {});    try set.put(allocator, V.initI128(2), {});    try set.put(allocator, V.initI128(1), {});    try std.testing.expectEqual(@as(usize, 2), set.count());    try std.testing.expect(set.contains(V.initI128(1)));    try std.testing.expect(!set.contains(V.initI128(7)));}test "valueEqual freestanding wrapper matches method form" {    const NoEmbedded = @import("domain.zig").NoEmbedded;    const V = value_mod.Value(NoEmbedded);    try std.testing.expect(valueEqual(NoEmbedded, V.initI128(1), V.initI128(1)));    try std.testing.expect(!valueEqual(NoEmbedded, V.initI128(1), V.initI128(2)));}

Source: lib/preserves/src/root.zig:111

zig
pub const containers = @import("containers.zig");

Audit

Definitions5
Public names5
Members0
Version26.7.0
Revisiondaab053ee433