ddn.var for a full-featured dynamic value type with richer semantics,
ddn.data.json5 for JSON5 parsing and serialization utilities.
Compact Dynamic Value Type
This module provides adam, a memory-efficient dynamic value type designed to match the semantics and API of ddn.var while minimizing memory footprint. It is suitable for applications where large numbers of dynamic values must be stored or transmitted with minimal overhead.
Features:
size_t word.bool, all D integer types, float, double, and dchar.adam[]) and objects (adam[string]) with JSON-like semantics.real → double, char/wchar → dchar to keep the tag space small.ddn.var operators, conversions, and serialization methods.Differences from ddn.var:
adam intentionally does not support DATE, TIME, DATETIME,
SYSTIME, or DURATION types. This is a deliberate design choice to maintain compactness and simplicity. Applications requiring temporal values should use ddn.var instead, or encode temporal values as strings or numeric timestamps.
real is stored as double, and char/wchar are stored as dchar,
reducing the number of type tags needed.
adam copies string data on assignment (via .idup) to ensure
memory safety, whereas some operations may differ from var.
Example:
import ddn.adam;
// Scalar values
adam i = 42;
adam d = 3.14;
adam s = "hello";
// Arrays
adam arr = [adam(1), adam(2), adam(3)];
assert(arr.length == 3);
// Objects
adam obj;
obj["name"] = "alice";
obj["age"] = 30;
assert(obj["name"].get!string == "alice");
// JSON serialization
string json = obj.toJSON();Platform Notes:
adam.sizeof == 16.adam.sizeof == 8, but array/string lengths are limited to 28 bits.ddn.var for a full-featured dynamic value type with richer semantics,
ddn.data.json5 for JSON5 parsing and serialization utilities.
ddn.adam — a compact dynamic value type.
This implementation aims to match ddn.var semantics and API shape as closely as possible, while keeping the value representation very small.
Representation:
_data)._lenTag) that packs the Type tag into the high bits and(for STRING and ARRAY) the length into the low bits.
Type normalization (to keep the tag space small):
real values are stored as Type.DOUBLE (converted to double).char and wchar values are stored as Type.DCHAR (converted to dchar).On 64-bit platforms (size_t.sizeof == 8):
adam.sizeof == 16 (payload 8 bytes + tagged-length 8 bytes).On 32-bit platforms (size_t.sizeof == 4):
TAG_BITS = 4, array/string lengths are limited to 28 bits(i.e., max length 2^28 - 1).
Important design rule:
is masked before use.
Data _datasize_t _lenTagprivate 4 TAG_BITSprivate size_t TAG_SHIFTprivate size_t LEN_MASKprivate size_t TAG_MASKprivate size_t LENGTH_BITSvoid _validateLength(size_t n) @safeValidate that a length value fits in the tagged-length representation.void _setLengthBits(size_t n) nothrow @nogc pure @safeSet the length bits in the tagged-length word.Type type() @property const nothrow @nogc pure @safeGet the current type tag (property form like `var.type`).adam opAssign(T)(T rhs) @safeT as(T)() const @trustedConvert to target type `T`. Returns `T.init` on failure (matches `var.as!T` behavior).Nullable!T tryAs(T)() const @safe`tryAs!T` returns a `Nullable!T` that is null when conversion fails.void opIndexAssign(T)(T rhs, size_t index) @safeAssign a value to an array element at the given index.adam opSlice(size_t start, size_t end) const @safeSlice an array and return a new ARRAY value (copies elements).void opOpAssign(string op, T)(T rhs) if (op == "~") @safebool insert(T)(size_t index, T rhs) @safeInsert `rhs` at position `index` (0..length). Returns false if index is out of range.int opApply(scope int delegate(ref adam) dg)Foreach support over arrays.ObjectBox * _ensureObjectBox(string op) @trustedPromote NULL -> OBJECT and ensure a box exists.void opIndexAssign(T)(T rhs, string key) @safebool remove(string key) @safeint opApply(scope int delegate(const string, ref adam) dg)Foreach support over map entries.adam merge(const adam other, bool deepMerge = false) ref return @safeMerge another object into this one (like `var.merge`).adam makeArray() @safeadam makeObject() @safethis(T arg)Construct from another value `arg` (mirrors `var.this(T)`).TypeObjectBoxBase exception type for ddn.adam runtime misuse.
this(string msg, string file = __FILE__, size_t line = __LINE__)Thrown when an operation requires a specific runtime adam.Type.
this(string op, adam.Type expected, adam.Type actual, string details = null,
string file = __FILE__, size_t line = __LINE__)Thrown when an object key is missing for an operation that requires it.
this(string op, string key, string file = __FILE__, size_t line = __LINE__)Thrown when an array index is out of range for an operation that requires it.
this(string op, size_t index, size_t length, string file = __FILE__, size_t line = __LINE__)