tiny.preserves.Value
Defined in value.
Returns the tagged union of all values whose embedded values have type D.
Source
Source: lib/preserves/src/value.zig:116
zig
/// Returns the tagged union of all values whose embedded values have type `D`. Every program that/// stores Preserves data calls it once for the type of its embedded values, as the text codec does/// with `AnyEmbedded`. The function stops compilation unless `D` meets `assertIsDomain`. Whether/// atom bytes are borrowed or copied depends on the constructor: `initString`, `initByteString` and/// `initSymbol` copy, and the root's `string` and `symbol` borrow. A value owns a compound's slice/// only when its creator hands the slice over and later calls `deinit` with the same allocator./// Every decoder copies the bytes it reads, so a decoded value owns every byte and `deinit` frees/// it.pub fn Value(comptime D: type) type { domain_mod.assertIsDomain(D); return union(enum) { pub const Self = @This(); /// The type of the embedded values, `D`. Generic code reads it to recover the type of the /// embedded values from a value type. `text.decode` and the binary `decode` take that type /// as their first parameter, so `Value.Domain` fills it. pub const Domain = D; /// A slice of values, the storage of a sequence and of a record's fields. Code that builds /// a record's fields or a sequence names the slice with this type. pub const Sequence = []Self; /// A slice of values, the storage of a set, holding each element once in any order. Code /// that builds a set names the slice with this type. Equality, order and hash read it in /// ascending order under `compare`. pub const Set = []Self; /// One key and value pair of a dictionary. Code that builds a dictionary names each entry /// with this type, as the constructors and the JSON reader do. pub const DictionaryEntry = struct { /// The entry's key, which appears once in its dictionary. key: Self, /// The value the key maps to. value: Self, }; /// A slice of entries, the storage of a dictionary, in any order. Code that builds a /// dictionary names the slice with this type. Equality, order and hash read the entries in /// ascending order of key, then value, under `compare`. pub const Dictionary = []DictionaryEntry; /// The parts of a record: a label and its fields. Code that reads a record names its parts /// with this type. pub const Record = struct { /// A pointer to the label value, kept in its own cell so a record can have any value as /// its label. Records compare their labels first. label: *Self, /// The record's fields, in order. Records with equal labels compare their fields in /// order, and a shorter list that matches ranks first. fields: Sequence, }; /// The parts of a bind: a name and the pattern it names. Code that reads a bind names its /// parts with this type. pub const Bind = struct { /// The bind's name. Two binds are equal only when their names are equal byte for byte. /// `deinit` frees the name, and `freeValue` and `freeValueDeep` leave it. name: []const u8, /// A pointer to the pattern the bind names, in its own cell. pattern: *Self, }; /// The parts of a rest pattern: patterns for the first items of a sequence and one pattern /// for the items after them. Code that reads a rest pattern names its parts with this type. pub const RestPattern = struct { /// The patterns for the first items, in order. prefix: []Self, /// A pointer to the pattern for the items after the prefix, in its own cell. rest: *Self, }; /// A boolean. `false` orders before `true`. boolean: bool, /// A 64-bit double. Doubles are equal when their bits are equal, and they order by a total /// order over their bits, so `0.0` and `-0.0` differ and a `NaN` has one place. double: f64, /// An integer of any size. `deinit` frees its heap digits when it has any. signed_integer: SignedInteger, /// The string's bytes. The text reader rejects invalid UTF-8 bytes. Strings compare byte by /// byte. string: []const u8, /// The byte string's bytes, compared byte by byte. byte_string: []const u8, /// The symbol's name bytes, compared byte by byte. symbol: []const u8, /// A record: a label and its fields. record: Record, /// A sequence: values in order, compared item by item. sequence: Sequence, /// A set: each element once, stored in any order. Equality, order and hash read it in /// ascending order under `compare`, whatever the order of its storage. set: Set, /// A dictionary: each key once, mapped to a value, stored in any order. Equality, order and /// hash read it in ascending order of key, then value, whatever the order of its storage. dictionary: Dictionary, /// An embedded value of the type `D`, which supplies its equality, order, freeing and /// copying. embedded: D, /// The discard pattern carries no data. All discards are equal. discard: void, /// A capture: a pointer to its inner pattern, in its own cell. capture: *Self, /// A bind: a name and the pattern it names. bind: Bind, /// A rest pattern: patterns for a sequence's first items and one pattern for the rest. rest_pattern: RestPattern, /// Returns the value's kind: its group and which member of the group. Code that switches on /// a value's kind calls it. pub fn kind(self: Self) ValueKind { return switch (self) { .boolean => .{ .atomic = .boolean }, .double => .{ .atomic = .double }, .signed_integer => .{ .atomic = .signed_integer }, .string => .{ .atomic = .string }, .byte_string => .{ .atomic = .byte_string }, .symbol => .{ .atomic = .symbol }, .record => .{ .compound = .record }, .sequence => .{ .compound = .sequence }, .set => .{ .compound = .set }, .dictionary => .{ .compound = .dictionary }, .embedded => .embedded, .discard => .{ .pattern = .discard }, .capture => .{ .pattern = .capture }, .bind => .{ .pattern = .bind }, .rest_pattern => .{ .pattern = .rest_pattern }, }; } /// Returns the atom kind of an atom, and `null` for any other value. Code that handles /// atoms calls it to test for one and learn which. pub fn atomClass(self: Self) ?AtomClass { return switch (self.kind()) { .atomic => |a| a, else => null, }; } /// Returns the compound kind of a compound, and `null` for any other value. Code that /// handles compounds calls it to test for one and learn which. pub fn compoundClass(self: Self) ?CompoundClass { return switch (self.kind()) { .compound => |c| c, else => null, }; } /// Returns the kind of pattern, and `null` for any other value. Code that handles patterns /// calls it to test for one and learn which. pub fn patternClass(self: Self) ?PatternFormClass { return switch (self.kind()) { .pattern => |p| p, else => null, }; } /// Makes a boolean value from `v`, with no allocation. Readers and tests call it for a /// boolean value. pub fn initBoolean(v: bool) Self { return .{ .boolean = v }; } /// Makes a double value from `v`, with no allocation. The binary and text readers call it /// for a double value. pub fn initDouble(v: f64) Self { return .{ .double = v }; } /// Makes an integer value from `v`, with no allocation. Readers and constructors call it /// for an integer value. pub fn initI128(v: i128) Self { return .{ .signed_integer = SignedInteger.fromI128(v) }; } /// Makes an integer value from `v`, stored in 128 signed bits when it fits there, with no /// allocation. Code that holds a number above the 128-bit signed range calls it, as the /// tests of `text.encode` do. pub fn initU128(v: u128) Self { return .{ .signed_integer = SignedInteger.fromU128(v) }; } /// Makes an integer value from `v`. The readers call it for an integer they already parsed. /// The value takes `v`'s heap digits, so `deinit` on the value frees them. pub fn initSignedInteger(v: SignedInteger) Self { return .{ .signed_integer = v }; } /// Makes a string value holding a copy of `bytes` from `allocator`. Code that builds a /// string it must own calls it, as `cloneValueDeep` does. `deinit` with the same allocator /// frees the copy. pub fn initString(allocator: Allocator, bytes: []const u8) !Self { return .{ .string = try allocator.dupe(u8, bytes) }; } /// Makes a byte-string value holding a copy of `bytes` from `allocator`. Code that builds a /// byte string it must own calls it. `deinit` with the same allocator frees the copy. pub fn initByteString(allocator: Allocator, bytes: []const u8) !Self { return .{ .byte_string = try allocator.dupe(u8, bytes) }; } /// Makes a symbol value holding a copy of `bytes` from `allocator`. Code that builds a /// symbol it must own calls it, as the record builders and `cloneValueDeep` do. `deinit` /// with the same allocator frees the copy. pub fn initSymbol(allocator: Allocator, bytes: []const u8) !Self { return .{ .symbol = try allocator.dupe(u8, bytes) }; } /// Makes a record from `label` and `fields`, allocating one cell for the label from /// `allocator`. The binary and text readers and `cloneValueDeep` call it for a record whose /// parts they own. The record takes `fields` as given, with no copy, so `deinit` with the /// same allocator frees the slice, the label and every field. On `error.OutOfMemory` /// nothing is allocated, and the caller still owns `label` and `fields`. pub fn initRecord(allocator: Allocator, label: Self, fields: Sequence) !Self { const label_ptr = try allocator.create(Self); errdefer allocator.destroy(label_ptr); label_ptr.* = label; return .{ .record = .{ .label = label_ptr, .fields = fields } }; } /// Makes a sequence that takes `items` as given, with no copy and no allocation. /// `cloneValueDeep` and the embedded copy function call it for a sequence whose slice they /// own. pub fn initSequence(items: Sequence) Self { return .{ .sequence = items }; } /// Makes a set that takes `items` as given, with no copy, no sort and no allocation. /// `cloneValueDeep` and the embedded copy function call it for a copy of a set already held /// as a value, so no second check runs. The call does not check for equal elements, so a /// caller who has not checked calls `setElementsDistinct` first or uses the `set` /// constructor. pub fn initSet(items: Set) Self { return .{ .set = items }; } /// Makes a dictionary that takes `entries` as given, with no copy, no sort and no /// allocation. `cloneValueDeep` and the embedded copy function call it for a copy of a /// dictionary already held as a value, so no second check runs. The call does not check for /// equal keys, so a caller who has not checked calls `dictionaryKeysDistinct` first or uses /// the `dictionary` constructor. pub fn initDictionary(entries: Dictionary) Self { return .{ .dictionary = entries }; } /// Returns whether some item of `items` equals `needle` under `eql`. The binary and text /// readers call it with the elements read so far, so each new element that repeats one is /// rejected. The call scans every item and allocates nothing. pub fn setContainsElement(items: []const Self, needle: Self) bool { for (items) |item| { if (item.eql(needle)) return true; } return false; } /// Returns whether some entry of `entries` has a key equal to `needle` under `eql`. The /// binary and text readers call it with the keys read so far, so each new key that repeats /// one is rejected. The call scans every entry and allocates nothing. pub fn dictionaryContainsKey( entries: []const DictionaryEntry, needle: Self, ) bool { for (entries) |entry| { if (entry.key.eql(needle)) return true; } return false; } /// Returns whether no two items of `items` are equal. The `set` constructor and the binary, /// text and JSON writers call it to reject duplicate set elements. The call compares each /// item with every item before it, so its cost grows with the square of the slice's length, /// and it allocates nothing. pub fn setElementsDistinct(items: []const Self) bool { for (items, 0..) |item, index| { if (setContainsElement(items[0..index], item)) return false; } return true; } /// Returns whether no two entries of `entries` have equal keys. The `dictionary` /// constructor and the binary, text and JSON writers call it to reject duplicate keys. The /// call compares each key with every key before it, so its cost grows with the square of /// the slice's length, and it allocates nothing. pub fn dictionaryKeysDistinct(entries: []const DictionaryEntry) bool { for (entries, 0..) |entry, index| { if (dictionaryContainsKey(entries[0..index], entry.key)) return false; } return true; } /// Makes a value holding the embedded value `d`, with no allocation. The text reader and /// `cloneValueDeep` call it for an embedded value they built. `deinit` frees `d` through /// the type's `deinit`. pub fn initEmbedded(d: D) Self { return .{ .embedded = d }; } /// Returns a borrowed copy of the value's atom, and `null` for any other value. Code that /// takes one atom out of a value calls it for a copy that records who owns the bytes. The /// copy points at the value's own bytes, so the value has to outlive it. pub fn asAtom(self: *const Self) ?Atom { return switch (self.*) { .boolean => |v| Atom.fromBool(v), .double => |v| Atom.fromDouble(v), .signed_integer => |v| Atom.fromSignedIntegerBorrowed(v), .string => |v| Atom.fromStringBorrowed(v), .byte_string => |v| Atom.fromByteStringBorrowed(v), .symbol => |v| Atom.fromSymbolBorrowed(v), .record, .sequence, .set, .dictionary, .embedded => null, .discard, .capture, .bind, .rest_pattern => null, }; } /// Frees everything the value points to with `allocator`: atom bytes, integer digits, /// compound storage, the cells and names of patterns, and embedded values through the /// type's `deinit`. Code that decoded a value, or owns every byte of one, calls it when /// done with it. Every byte has to come from `allocator`, so a value that borrows any bytes /// goes to `freeValue` or `freeValueDeep`. Copies from `cloneValueDeep` own every byte. The /// value is undefined afterward. pub fn deinit(self: *Self, allocator: Allocator) void { switch (self.*) { .boolean, .double => {}, .signed_integer => |*si| si.deinit(allocator), .string => |s| allocator.free(s), .byte_string => |s| allocator.free(s), .symbol => |s| allocator.free(s), .record => |*r| { r.label.deinit(allocator); allocator.destroy(r.label); for (r.fields) |*f| f.deinit(allocator); allocator.free(r.fields); }, .sequence => |s| { for (s) |*item| item.deinit(allocator); allocator.free(s); }, .set => |s| { for (s) |*item| item.deinit(allocator); allocator.free(s); }, .dictionary => |d| { for (d) |*entry| { entry.key.deinit(allocator); entry.value.deinit(allocator); } allocator.free(d); }, .embedded => |*e| D.deinit(e, allocator), .discard => {}, .capture => |p| { p.deinit(allocator); allocator.destroy(p); }, .bind => |*bp| { bp.pattern.deinit(allocator); allocator.destroy(bp.pattern); allocator.free(bp.name); }, .rest_pattern => |*rp| { for (rp.prefix) |*item| item.deinit(allocator); allocator.free(rp.prefix); rp.rest.deinit(allocator); allocator.destroy(rp.rest); }, } self.* = undefined; } /// Returns whether two values are equal: same kind and equal contents. Hash maps, sets and /// every duplicate check call it for value equality. Sets and dictionaries are equal when /// they hold the same elements or entries, each as many times, whatever their storage /// order. Doubles compare by bits, binds by name and pattern, and embedded values through /// the type's `eql`. The call allocates nothing, and its cost on two sets grows with the /// square of their size. pub fn eql(a: Self, b: Self) bool { if (!a.kind().eql(b.kind())) return false; return switch (a) { .boolean => |v| v == b.boolean, .double => |v| @as(u64, @bitCast(v)) == @as(u64, @bitCast(b.double)), .signed_integer => |v| v.eql(b.signed_integer), .string => |v| std.mem.eql(u8, v, b.string), .byte_string => |v| std.mem.eql(u8, v, b.byte_string), .symbol => |v| std.mem.eql(u8, v, b.symbol), .record => |v| v.label.*.eql(b.record.label.*) and sequenceEql(v.fields, b.record.fields), .sequence => |v| sequenceEql(v, b.sequence), .set => |v| setEql(v, b.set), .dictionary => |v| dictionaryEql(v, b.dictionary), .embedded => |v| D.eql(v, b.embedded), .discard => true, .capture => |p| p.eql(b.capture.*), .bind => |bp| std.mem.eql(u8, bp.name, b.bind.name) and bp.pattern.eql(b.bind.pattern.*), .rest_pattern => |rp| sequenceEql(rp.prefix, b.rest_pattern.prefix) and rp.rest.eql(b.rest_pattern.rest.*), }; } fn sequenceEql(a: []const Self, b: []const Self) bool { if (a.len != b.len) return false; for (a, b) |av, bv| if (!av.eql(bv)) return false; return true; } fn setEql(a: Set, b: Set) bool { if (a.len != b.len) return false; for (a, 0..) |candidate, i| { if (countSetMatches(a[0..i], candidate) != 0) continue; if (countSetMatches(a, candidate) != countSetMatches(b, candidate)) return false; } return true; } fn countSetMatches(items: []const Self, needle: Self) usize { var count: usize = 0; for (items) |item| { if (item.eql(needle)) count += 1; } return count; } fn dictionaryEql(a: Dictionary, b: Dictionary) bool { if (a.len != b.len) return false; for (a, 0..) |candidate, i| { if (countDictionaryEntryMatches(a[0..i], candidate) != 0) continue; if (countDictionaryEntryMatches(a, candidate) != countDictionaryEntryMatches(b, candidate)) return false; } return true; } fn countDictionaryEntryMatches(entries: Dictionary, needle: DictionaryEntry) usize { var count: usize = 0; for (entries) |entry| { if (entry.key.eql(needle.key) and entry.value.eql(needle.value)) count += 1; } return count; } /// Returns the order of `a` against `b`, a total order over all values. Sorting /// constructors and writers call it for the package's one total order. Kinds rank booleans, /// doubles, integers, strings, byte strings, symbols, records, sequences, sets, /// dictionaries, embedded values, then the four kinds of pattern. Within a kind, records /// compare label then fields, sequences item by item, and sets and dictionaries through /// their elements in ascending order, with a shorter list that matches ranking first. /// Embedded values order through the type's `order`. The call allocates nothing, and its /// cost on two sets grows with the square of their size. pub fn compare(a: Self, b: Self) std.math.Order { const ra = typeRank(a); const rb = typeRank(b); if (ra != rb) return std.math.order(ra, rb); return switch (a) { .boolean => |va| std.math.order(@intFromBool(va), @intFromBool(b.boolean)), .double => |va| floatTotalOrder(va, b.double), .signed_integer => |va| va.order(b.signed_integer), .string => |va| std.mem.order(u8, va, b.string), .byte_string => |va| std.mem.order(u8, va, b.byte_string), .symbol => |va| std.mem.order(u8, va, b.symbol), .record => |va| recordCompare(va, b.record), .sequence => |va| sliceCompare(va, b.sequence), .set => |va| setCompare(va, b.set), .dictionary => |va| dictionaryCompare(va, b.dictionary), .embedded => |va| D.order(va, b.embedded), .discard => .eq, .capture => |va| va.compare(b.capture.*), .bind => |va| bindCompare(va, b.bind), .rest_pattern => |va| restPatternCompare(va, b.rest_pattern), }; } fn typeRank(v: Self) u8 { return switch (v) { .boolean => 0, .double => 1, .signed_integer => 2, .string => 3, .byte_string => 4, .symbol => 5, .record => 6, .sequence => 7, .set => 8, .dictionary => 9, .embedded => 10, .discard => 11, .capture => 12, .bind => 13, .rest_pattern => 14, }; } fn recordCompare(a: Record, b: Record) std.math.Order { const label_ord = a.label.compare(b.label.*); if (label_ord != .eq) return label_ord; return sliceCompare(a.fields, b.fields); } const ValueCursor = struct { items: []const Self, after: ?Self = null, current: ?Self = null, remaining: usize = 0, fn next(cursor: *@This()) Self { if (cursor.remaining == 0) { const run = nextValueRun(cursor.items, cursor.after).?; cursor.current = run.value; cursor.after = run.value; cursor.remaining = run.count; } cursor.remaining -= 1; return cursor.current.?; } }; const ValueRun = struct { value: Self, count: usize, }; fn nextValueRun(items: []const Self, after: ?Self) ?ValueRun { var candidate: ?Self = null; for (items) |item| { if (after) |previous| { if (item.compare(previous) != .gt) continue; } if (candidate == null or item.compare(candidate.?) == .lt) { candidate = item; } } const value = candidate orelse return null; var count: usize = 0; for (items) |item| { if (item.compare(value) == .eq) count += 1; } return .{ .value = value, .count = count }; } fn setCompare(a: Set, b: Set) std.math.Order { var a_cursor = ValueCursor{ .items = a }; var b_cursor = ValueCursor{ .items = b }; for (0..@min(a.len, b.len)) |_| { const order = a_cursor.next().compare(b_cursor.next()); if (order != .eq) return order; } return std.math.order(a.len, b.len); } const DictionaryCursor = struct { entries: Dictionary, after: ?DictionaryEntry = null, current: ?DictionaryEntry = null, remaining: usize = 0, fn next(cursor: *@This()) DictionaryEntry { if (cursor.remaining == 0) { const run = nextDictionaryRun(cursor.entries, cursor.after).?; cursor.current = run.entry; cursor.after = run.entry; cursor.remaining = run.count; } cursor.remaining -= 1; return cursor.current.?; } }; const DictionaryRun = struct { entry: DictionaryEntry, count: usize, }; fn dictionaryEntryCompare(a: DictionaryEntry, b: DictionaryEntry) std.math.Order { const key_order = a.key.compare(b.key); if (key_order != .eq) return key_order; return a.value.compare(b.value); } fn nextDictionaryRun(entries: Dictionary, after: ?DictionaryEntry) ?DictionaryRun { var candidate: ?DictionaryEntry = null; for (entries) |entry| { if (after) |previous| { if (dictionaryEntryCompare(entry, previous) != .gt) continue; } if (candidate == null or dictionaryEntryCompare(entry, candidate.?) == .lt) { candidate = entry; } } const selected = candidate orelse return null; var count: usize = 0; for (entries) |entry| { if (dictionaryEntryCompare(entry, selected) == .eq) count += 1; } return .{ .entry = selected, .count = count }; } fn dictionaryCompare(a: Dictionary, b: Dictionary) std.math.Order { var a_cursor = DictionaryCursor{ .entries = a }; var b_cursor = DictionaryCursor{ .entries = b }; for (0..@min(a.len, b.len)) |_| { const order = dictionaryEntryCompare(a_cursor.next(), b_cursor.next()); if (order != .eq) return order; } return std.math.order(a.len, b.len); } fn bindCompare(a: Bind, b: Bind) std.math.Order { const no = std.mem.order(u8, a.name, b.name); if (no != .eq) return no; return a.pattern.compare(b.pattern.*); } fn restPatternCompare(a: RestPattern, b: RestPattern) std.math.Order { const po = sliceCompare(a.prefix, b.prefix); if (po != .eq) return po; return a.rest.compare(b.rest.*); } fn sliceCompare(a: []const Self, b: []const Self) std.math.Order { const len = @min(a.len, b.len); for (a[0..len], b[0..len]) |ia, ib| { const o = ia.compare(ib); if (o != .eq) return o; } return std.math.order(a.len, b.len); } fn floatTotalOrder(a: f64, b: f64) std.math.Order { const bits_a = @as(u64, @bitCast(a)); const bits_b = @as(u64, @bitCast(b)); const sign_a = bits_a >> 63; const sign_b = bits_b >> 63; if (sign_a != sign_b) return if (sign_a > sign_b) .lt else .gt; if (sign_a == 1) return std.math.order(bits_b, bits_a); return std.math.order(bits_a, bits_b); } /// Returns a 64-bit Wyhash, seed 0, of the value's kind and contents. Hash maps call it. /// Sets and dictionaries feed their elements in ascending order under `compare`, so equal /// values hash alike whatever their storage order. An embedded value adds its type's `hash` /// when the type declares one, and nothing otherwise. The call allocates nothing, and its /// cost on a set grows with the square of the set's size. pub fn hash(self: Self) u64 { var hasher = std.hash.Wyhash.init(0); hashInto(&hasher, self); return hasher.final(); } fn hashInto(hasher: *std.hash.Wyhash, v: Self) void { const tag: u8 = typeRank(v); hasher.update(&.{tag}); switch (v) { .boolean => |b| hasher.update(&.{@intFromBool(b)}), .double => |f| { const bits: u64 = @bitCast(f); hasher.update(std.mem.asBytes(&bits)); }, .signed_integer => |si| hashSignedInteger(hasher, si), .string => |s| hasher.update(s), .byte_string => |b| hasher.update(b), .symbol => |s| hasher.update(s), .record => |r| { hashInto(hasher, r.label.*); for (r.fields) |field| hashInto(hasher, field); }, .sequence => |s| for (s) |item| hashInto(hasher, item), .set => |s| { var cursor = ValueCursor{ .items = s }; for (0..s.len) |_| hashInto(hasher, cursor.next()); }, .dictionary => |d| { var cursor = DictionaryCursor{ .entries = d }; for (0..d.len) |_| { const entry = cursor.next(); hashInto(hasher, entry.key); hashInto(hasher, entry.value); } }, .embedded => |e| { if (@hasDecl(D, "hash")) { const h: u64 = D.hash(e); hasher.update(std.mem.asBytes(&h)); } }, .discard => {}, .capture => |p| hashInto(hasher, p.*), .bind => |bp| { hasher.update(bp.name); hashInto(hasher, bp.pattern.*); }, .rest_pattern => |rp| { for (rp.prefix) |item| hashInto(hasher, item); hashInto(hasher, rp.rest.*); }, } } fn hashSignedInteger(hasher: *std.hash.Wyhash, si: SignedInteger) void { switch (si.repr) { .i128 => |iv| { hasher.update(&.{0}); hasher.update(std.mem.asBytes(&iv)); }, .u128 => |uv| { hasher.update(&.{1}); hasher.update(std.mem.asBytes(&uv)); }, .big => |b| { hasher.update(&.{2}); hasher.update(b); }, } } };}Source: lib/preserves/src/root.zig:140
zig
pub const Value = value.Value;Also reachable as
constructors_mod.Value, ownership.Value, patterns_mod.Value, predicates.Value, records_mod.Value.
Complete caller list
8 direct callers.
lib.preserves.src.value.test_Value(NoEmbedded)_atoms_round-trip_through_kind[function] — test source atlib/preserves/src/value.zig:809in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value(NoEmbedded)_compound_smoke[function] — test source atlib/preserves/src/value.zig:816in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value.asAtom_produces_a_borrowed_view[function] — test source atlib/preserves/src/value.zig:834in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value.compare_total-orders_across_kind_ranks[function] — test source atlib/preserves/src/value.zig:928in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value.eql_distinguishes_duplicate-bearing_dictionaries[function] — test source atlib/preserves/src/value.zig:863in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value.eql_distinguishes_duplicate-bearing_sets[function] — test source atlib/preserves/src/value.zig:844in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value.hash_respects_equality_for_canonical_values[function] — test source atlib/preserves/src/value.zig:947in nearest public ownertiny.preserves.valuelib.preserves.src.value.test_Value_pattern-form_variants_surface_their_class[function] — test source atlib/preserves/src/value.zig:894in nearest public ownertiny.preserves.value
Complete call list
9 direct calls.
tiny.preserves.Atom.fromBool[function] atlib/preserves/src/atom.zig:157tiny.preserves.Atom.fromByteStringBorrowed[function] atlib/preserves/src/atom.zig:192tiny.preserves.Atom.fromDouble[function] atlib/preserves/src/atom.zig:162tiny.preserves.Atom.fromSignedIntegerBorrowed[function] atlib/preserves/src/atom.zig:168tiny.preserves.Atom.fromStringBorrowed[function] atlib/preserves/src/atom.zig:180tiny.preserves.Atom.fromSymbolBorrowed[function] atlib/preserves/src/atom.zig:204tiny.preserves.SignedInteger.fromI128[function] atlib/preserves/src/integer.zig:72tiny.preserves.SignedInteger.fromU128[function] atlib/preserves/src/integer.zig:78lib.python.src.object.value.hashInto[function] — private source atlib/python/src/object/value.zig:539in nearest public ownertiny.python.object.value
Audit
| Definitions | 1 |
|---|---|
| Public names | 7 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |