ddn.var — a compact, dynamic value type.
Error handling strategy:
- By default, wrong-type use of container APIs throws exceptions (e.g. indexing a non-object or using array APIs on non-arrays). This is enforced in both debug and
-release builds. - If compiled with
version(DDN_VAR_TYPE_COERCE), var becomes permissive: - Mutating/ref-returning array/object APIs will auto-coerce the value to the required container type (overwriting the previous value).
- Read-only accessors return neutral values on mismatch (no hidden mutation).
- In
debug builds, coercions emit warnings on stderr. - No I/O is performed inside this module except the documented debug-only coercion warnings on
stderr under version(DDN_VAR_TYPE_COERCE); formatting is provided by toString().
Thread-safety notes:
var itself does not perform any internal synchronization. Concurrent mutation of the same instance from multiple threads is a data race and is not supported.- Independent copies may be used in different threads; however, keep in mind that
string is immutable (safe to share) while arrays/maps inside var are reference-backed containers owned by each var instance. Note
copying/assignment of var values is shallow for Type.ARRAY and Type.OBJECT (it aliases the underlying containers). Use dup() / idup() when you need an independent deep copy.
- Recommended patterns: message passing of
var values; publishing immutable(var) snapshots; or guarding shared access with user-provided synchronization (e.g., a Mutex).
Fields
private Data _data
private NativeQual _qual
private DecimalCap _decap
private size_t _MAX_JSON_DEPTHMaximum recursion depth for JSON-like formatting to avoid runaway recursion.
private size_t _VAR_MAX_SIZESize and layout notes:
Methods
private inout(E[]) _nativeArrayRef(E)() ref return @trusted inoutRef access to the native-array union member for element type `E`. private string _nativeKindName(ElementType k) static @safe pure nothrow @nogcHuman-readable name for a native element kind (diagnostics only). private size_t _nativeLength() const @safe nothrow @nogcNumber of elements in a native-array value. private void _putNativeElements(Sink)(ref Sink sink) const @safeWrites the native-array contents in the boxed-ARRAY text form (`[elem, elem, ...]`); `real` elements render via their `double` value, matching the scalar `REAL` precedent. Character elements render... private string _nativeToStringImpl() const @safeBuilds the `toString` form of a native-array value. private bool _nativeEqualsImpl(const scope var rhs) const @trustedStructural equality for two native-array values of the same element kind. Floating elements mirror the scalar rules (NaN equals NaN); `real` elements compare at native precision. private size_t _nativeHashImpl(size_t h) const @safeHash of a native-array value: folds the element kind and per-element scalar hashes (mirroring the scalar hashing rules); `real` elements hash via their `double` value, so equal values always hash e... private string _fdToString() const @safe pureExact decimal text of a `FIXED_DECIMAL` value (stored capacity). private FixedDecimal!(Int128) _fdAsWide() const @safe pure nothrowWide (38-digit) form of a `FIXED_DECIMAL` value: shared by equality, hashing, ordering and truthiness. `widen()` is exact and nothrow, and the standalone canonical semantics keep results cross-capa... private auto _fdVisit(R, handlers...)() const @safe`visit` dispatch for decimals: the stored capacity's instantiation. private auto _fdVisitNogc(handlers...)() const @safe @nogc`visitNogc` dispatch for decimals, mirroring `nativeVisitNogc`: exact parameter match, then implicit conversions, then `R.init` (no `var` fallback in `@nogc` dispatch). private auto _nativeVisit(R, handlers...)() scope const @safe`visit` dispatch for native arrays: handlers may accept `const(E)[]` for the active element kind. A `const(var)` fallback receives this value itself (no boxing, no allocation); a mutable `var` fall... private auto _nativeVisitNogc(handlers...)() scope const @safe @nogc`visitNogc` dispatch for native arrays, mirroring `visit`'s matching rules (exact parameter type first, then implicit conversions). No `var`/`const(var)` fallback is provided here to keep the path ... private void _nativeAssignElement(T)(T rhs, size_t index) @safeStores one element into a native array via `v[index] = value`. private void _trustedStoreString(ref var dst, scope string src) static @trustedStores a string payload into a mutable `var`. private void _trustedShallowAssign(ref var dst,
ref scope const var src) static @trustedStores a shallow copy of a qualified `var`'s raw data union into a mutable `var`. private Target _trustedDataCopyAs(Target, Q)(ref scope Q src) static @trustedReturns a copy of a qualified `var`'s raw data union. var opAssign(T)(scope T rhs) @safeAssign from an arbitrary value `rhs`, setting the internal type and payload accordingly.var opIndex(string key) ref @safeAccess a child value by key, turning this instance into a map on first use.const(var) opIndex(string key) ref const @safeConst overload of `opIndex` for read-only map access.void opIndexAssign(T)(T rhs, string key) @safeAssign a value to a child by key (map-style assignment).void opIndexAssign(T)(T rhs, size_t index) @safeAssign a value to an array element by index.bool remove(string key) @safeRemove a child by key from the map.void clear() @safeReset this `var` to `Type.NULL`, releasing any held resources.var dup() scope const @safeCreate a deep copy of this `var`.private var _dupImpl(size_t depth) scope const @safe private var[string] _dupObjectMap() const @safeBuild a fresh mutable map whose values are deep copies of the stored OBJECT payload. var idup() const @safeCreate an independent deep copy of this `var` under an `idup`-style name.var merge(const var other, bool deepMerge = false) ref return @safe Merge another object into this one. This method combines the key-value pairs from `other` into this `var`. It only works when both `this` and `other` are objects (Type.OBJECT). Conflict resol...private var _mergeImpl(const var other, bool deepMerge, size_t depth) ref return @safe var opDispatch(string name)() ref @safeDynamic field access for map values via D's `opDispatch`.const(var) opDispatch(string name)() ref const @safeConst overload of `opDispatch` for read-only access (no insertion).private string _typeName(Type t) static @safe pure nothrowGet a human-readable name for a Type value. private void _warnCoercion(string op, Type from, Type to, string details = null) static @safeEmit a debug-only warning for semantic-changing coercions. private const(var) _nullConstRef() static ref @safe nothrowA shared `NULL` value returned by reference for safe "neutral" `ref const(var)` APIs. private void _requireType(string op, Type expected, string details = null) const @safe private void _requireArray(string op, string details = null) const @safe private void _requireObject(string op, string details = null) const @safe var getField(T)(const string key, T defaultValue) const @safeSafely get a field value with a default fallback.var get(const string key) const @safeSafely get a field value, returning NULL if missing.var path(const string[] pathParts) const @safeAccess a nested value using an array of path components.var path(const string pathStr) const @safeAccess a nested value using dot-notation or slash-notation path string.ElementRange byElement() @safeGet a forward range over the elements of this array.ConstElementRange byElement() scope const @safeConst overload: get a forward range over the elements of this array.KeyRange byKey() @safeGet a forward range over the keys of this object.ValueRange byValue() @safeGet a forward range over the values of this object.PairRange byPair() @safeGet a forward range over the key-value pairs of this object.string toStringRoundTrip() const @safeShortest text that parses back to the exact stored floating-point value.string toString() const @safeConvert the stored value to a human-readable string.void toStringTo(Sink)(ref Sink sink) if (is(typeof(sink.put("test"))) || is(typeof(sink.put('c')))) const @safeWrite the string representation of this value to an output range.private void _toStringSink(Sink)(ref Sink sink, size_t depth) if (is(typeof(sink.put("test"))) && is(typeof(sink.put('c')))) const @safeInternal sink-based string formatter with depth tracking. private void _toJSONStringSink(Sink)(ref Sink sink, size_t depth) if (is(typeof(sink.put("test"))) && is(typeof(sink.put('c')))) const @safeInternal JSON sink formatter for arrays and objects. private void _toJSONElementSink(Sink)(ref Sink sink, size_t depth) if (is(typeof(sink.put("test"))) && is(typeof(sink.put('c')))) const @safeInternal JSON element sink formatter (quotes strings). private T _extractDecimal(T)() if (_isFDInst!T) const @safe Convert the stored value to type `T`. Conversion rules: - If the current type is `Type.NULL`, this returns `T.init`. - Scalars and strings convert via `std.conv.to`. - If the current type is ... private T _fpToI64Checked(T)(double v) static @safeChecked float-to-64-bit-integer conversion for `as` / `tryAs`. Nullable!T tryAs(T)() const @safe Attempt to convert the stored value to type `T`, returning a `Nullable!T`. `as!T` reports failures two different ways — wrong-kind container mismatches generally return `T.init` (indistinguis...T opCall(T)() const @safeConvenience call operator that forwards to `as!T()`.private string _escapeJSONString(const string s) static @safeEscape a string for inclusion into JSON-like output. private var _arrayElemAt(size_t index) ref @trustedReturn a reference to the array element at `index` from the union (trusted boundary). var opIndex(size_t index) ref @safeIndex into the array payload and return a reference to the element.const(var) opIndex(size_t index) ref const @safeConst overload of `opIndex` for read-only array access.size_t opDollar() @property const @safeSupport `$` in slice expressions for arrays.var opSlice(size_t start, size_t end) const @safeSlice an array to create a new `var` containing a subrange of elements.size_t length() @property const @safeGet the number of elements when the value holds an array.bool isNativeArray() @property scope const nothrow @nogc pure @safeTrue when this value is a compact native-array value (`typedArray`).bool isNativeArrayOf(E)() if (_nativeKindOf!E != ElementType.NONE) scope const nothrow @nogc pure @safeTrue when this value is a native array of element type `E`.bool isUuid() @property const nothrow @nogc pure @safeTrue when this value is a UUID payload (`std.uuid.UUID`).bool isFixedDecimal() @property const nothrow @nogc pure @safeTrue when this value is a fixed-point decimal (`FIXED_DECIMAL`).var element(size_t index) const @safeBoxes a single element of a native array into a `var`.E[] nativeSlice(E)() if (_nativeKindOf!E != ElementType.NONE) @safe Returns the shared mutable slice of a native array. Only valid when the stored buffer carries the mutable qualifier: `typedArray` from a mutable slice, or `dup()`/`idup()` of a mutable-qualifi...void append(T)(T rhs) @safeAppend a value to the array. Converts `Type.NULL` to an empty array on first use.void extend(T)(T rhs) @safeExtend this array with elements from another array (flat concatenation).void opOpAssign(string op, T)(T rhs) if (op == "~" || op == "+" || op == "-" || op == "*" || op == "/" || op == "%") @safeOperator `~=` for append or string concatenation.bool contains(const string key) const @safeCheck whether the map contains `key`.var get(TDefault)(const string key, TDefault defaultValue) const @safeGet the value for `key` or return `defaultValue` if missing.string[] keys() @property const @safeReturn an array of keys. For `Type.NULL`, returns an empty array.var[] values() @property const @safeReturn an array of values. For `Type.NULL`, returns an empty array.size_t count() @property const @safeNumber of key/value pairs stored. Returns 0 for `Type.NULL`.int opApply(scope int delegate(const string, ref var) dg)Iterate over map entries as `(key, ref value)` pairs. For non-map types, iteration yields zero elements.int opApply(scope int delegate(const string, ref var) @safe dg) @safe@safe counterpart of opApply for @safe loop bodies.int opApply(scope int delegate(const string, ref const(var)) @safe dg) const @safeConst iteration over map entries as `(key, ref const value)` pairs.bool insert(T)(size_t index, T rhs) @safeInsert `rhs` at position `index` (0..length). Converts `Type.NULL` to empty array. Returns `true` on success, `false` if index is out of range.bool removeAt(size_t index) @safeRemove the element at `index`. Returns `true` if removed, `false` if `index` is out of range or the value is `Type.NULL`. Throws a `VarTypeException` if the current type is neither `NULL` nor `ARRAY`.int opApply(scope int delegate(ref var) dg)Foreach iteration support over array elements.int opApply(scope int delegate(ref var) @safe dg) @safe@safe counterpart for @safe loop bodies.int opApply(scope int delegate(ref const(var)) @safe dg) const @safeConst foreach iteration over array elements.int opApply(scope int delegate(size_t, ref var) dg)Foreach iteration with index over array elements.int opApply(scope int delegate(size_t, ref var) @safe dg) @safe@safe counterpart for @safe loop bodies.int opApply(scope int delegate(size_t, ref const(var)) @safe dg) const @safeConst foreach iteration with index over array elements.bool opEquals(const scope var rhs) const @trustedStructural equality.private bool _equalsImpl(const scope var rhs, size_t depth) const @trusted var opBinary(string op)(const var rhs) if (op == "+" || op == "-" || op == "*" || op == "/" || op == "%") const @safe Binary arithmetic operators for `var`. Supported operators: `+`, `-`, ``, `/`, `%` Type promotion rules: - If either operand is `DOUBLE`, `FLOAT`, or `REAL`, the result is `DOUBLE`. - If eit...var opBinary(string op)(const var rhs) if (op == "~") const @safeString concatenation operator for `var`.var opUnary(string op)() if (op == "-" || op == "!") const @safeUnary operators for `var`.private bool _isNumericType(Type t) static @safe pure nothrow @nogcCheck if a type is numeric (integer or floating point). private bool _isFloatingType(Type t) static @safe pure nothrow @nogcCheck if a type is floating point. private double _toDouble() const @safeConvert the stored value to double for arithmetic. private long _toLong() const @safeConvert the stored value to long for arithmetic. private bool _tryToLong(out long outValue) const @safeAttempt to convert an integer value to `long` without overflow. private bool _tryToUlong(out ulong outValue) const @safeAttempt to convert an integer value to `ulong` without wrapping. private ulong _toUlong() const @safeConvert the stored value to `ulong` for arithmetic. private bool _toBool() const @safeConvert the stored value to bool for logical operations. private var _decimalArith(string op)(const var rhs) const @safeDecimal arithmetic path for `+ - * /` with at least one `FIXED_DECIMAL` operand (design record D7): both operands become the wide runtime form (`Int128` storage; integral operands convert exactly â... private T _applyOp(string op, T)(T a, T b) static @safe pure nothrow @nogcApply a binary arithmetic operation. private int _cmpUlongVsDouble(ulong u, double d) static @safe pure nothrow @nogcExact ordering between a non-negative `ulong` magnitude and a positive finite `double`. private int _cmpIntDouble(const var iv, double d) static @safeExact ordering between an integer `var` and a `double` value. int opCmp(const var rhs) const @safe Three-way comparison operator for `var`. Enables use of `<`, `<=`, `>`, `>=` operators between `var` values. Comparison rules: - *Numeric types: Compared by numeric value with automatic type ...private int _cmpImpl(const var rhs, size_t depth) const @safe private dchar _toCodePoint(const var v) static @safeHelper to extract code point from char types. size_t toHash() const @safeCompute a structural hash value consistent with `opEquals`.private bool _floatEqual(float a, float b) static @safeCompare two floats for structural equality: NaN equals NaN; +0.0 and -0.0 are distinguished via bit patterns (consistent with opEquals). private bool _doubleEqual(double a, double b) static @safeCompare two doubles for structural equality: NaN equals NaN; +0.0 and -0.0 are distinguished via bit patterns (consistent with opEquals). private size_t _hashCombine(size_t h, size_t v) static @safe pure nothrow @nogcMix `v` into hash `h` (boost::hash_combine-style) and return the result. private size_t _hashString(const string s) static @safe pure nothrow @nogcFNV-style byte hash of `s`. private size_t _hashFloat(float a) static @trusted pure nothrow @nogcHash a float, canonicalizing NaN to a single quiet-NaN pattern. private size_t _hashDouble(double a) static @trusted pure nothrow @nogcHash a double (high/low bits folded), canonicalizing NaN to a single pattern. private uint _floatBits(float a) static @trusted pure nothrow @nogcRaw IEEE-754 bit pattern of `a` (used to distinguish signed zeros). private ulong _doubleBits(double a) static @trusted pure nothrow @nogcRaw IEEE-754 bit pattern of `a` (used to distinguish signed zeros). private bool _getBool() @trusted scope const pure nothrow @nogcRead the `bool` union field (trusted boundary). private byte _getByte() @trusted scope const pure nothrow @nogcRead the `byte` union field (trusted boundary). private ubyte _getUbyte() @trusted scope const pure nothrow @nogcRead the `ubyte` union field (trusted boundary). private short _getShort() @trusted scope const pure nothrow @nogcRead the `short` union field (trusted boundary). private ushort _getUshort() @trusted scope const pure nothrow @nogcRead the `ushort` union field (trusted boundary). private int _getInt() @trusted scope const pure nothrow @nogcRead the `int` union field (trusted boundary). private uint _getUint() @trusted scope const pure nothrow @nogcRead the `uint` union field (trusted boundary). private long _getLong() @trusted scope const pure nothrow @nogcRead the `long` union field (trusted boundary). private ulong _getUlong() @trusted scope const pure nothrow @nogcRead the `ulong` union field (trusted boundary). private float _getFloat() @trusted scope const pure nothrow @nogcRead the `float` union field (trusted boundary). private double _getDouble() @trusted scope const pure nothrow @nogcRead the `double` union field (trusted boundary). private double _getReal() @trusted scope const pure nothrow @nogcRead the `real` union field (trusted boundary). private char _getChar() @trusted scope const pure nothrow @nogcRead the `char` union field (trusted boundary). private wchar _getWchar() @trusted scope const pure nothrow @nogcRead the `wchar` union field (trusted boundary). private dchar _getDchar() @trusted scope const pure nothrow @nogcRead the `dchar` union field (trusted boundary). private void _setBool(bool v) @trustedWrite the `bool` union field (trusted boundary). private void _setByte(byte v) @trustedWrite the `byte` union field (trusted boundary). private void _setUbyte(ubyte v) @trustedWrite the `ubyte` union field (trusted boundary). private void _setShort(short v) @trustedWrite the `short` union field (trusted boundary). private void _setUshort(ushort v) @trustedWrite the `ushort` union field (trusted boundary). private void _setInt(int v) @trustedWrite the `int` union field (trusted boundary). private void _setUint(uint v) @trustedWrite the `uint` union field (trusted boundary). private void _setLong(long v) @trustedWrite the `long` union field (trusted boundary). private void _setUlong(ulong v) @trustedWrite the `ulong` union field (trusted boundary). private void _setFloat(float v) @trustedWrite the `float` union field (trusted boundary). private void _setDouble(double v) @trustedWrite the `double` union field (trusted boundary). private void _setReal(double v) @trustedWrite the `real` union field (trusted boundary). private void _setChar(char v) @trustedWrite the `char` union field (trusted boundary). private void _setWchar(wchar v) @trustedWrite the `wchar` union field (trusted boundary). private void _setDchar(dchar v) @trustedWrite the `dchar` union field (trusted boundary). Type type() @property scope const nothrow @nogc pure @safeGet the current type tag of this value.bool isNull() @property const nothrow @nogc pure @safeCheck if this value is null (Type.NULL).bool isArray() @property scope const nothrow @nogc pure @safeCheck if this value is an array (Type.ARRAY).bool isObject() @property const nothrow @nogc pure @safeCheck if this value is an object/map (Type.OBJECT).bool isNumeric() @property const nothrow @nogc pure @safeCheck if this value is a numeric type.bool isInteger() @property const nothrow @nogc pure @safeReturns true if this is any integer type (BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG).bool isFloat() @property const nothrow @nogc pure @safeReturns true if this is any floating-point type (FLOAT, DOUBLE, REAL).bool isString() @property const nothrow @nogc pure @safeCheck if this value is a string (Type.STRING).bool empty() @property const @safeCheck if this value is empty.bool isBool() @property const nothrow @nogc pure @safeCheck if this value is a boolean (Type.BOOL).bool isDate() @property const nothrow @nogc pure @safeCheck if this `var` holds a `Date` value.bool isTime() @property const nothrow @nogc pure @safeCheck if this `var` holds a `TimeOfDay` value.bool isDateTime() @property const nothrow @nogc pure @safeCheck if this `var` holds a `DateTime` value.bool isSysTime() @property const nothrow @nogc pure @safeCheck if this `var` holds a `SysTime` value.bool isTimestamp() @property const nothrow @nogc pure @safeCheck if this `var` holds a `ddn.datetime.Timestamp` value.bool isDuration() @property const nothrow @nogc pure @safeCheck if this `var` holds a `Duration` value.bool isTemporal() @property const nothrow @nogc pure @safeCheck if this `var` holds any temporal (datetime) type.auto visit(handlers...)() scope const @safeApply a visitor pattern to this value, dispatching to the appropriate handler based on type.auto visitNogc(handlers...)() const @safe @nogc`visitNogc` is a no-GC variant of `visit`.private static auto _visitDispatch(R, T, handlers...)(T value) @safeHelper to find and call the appropriate handler var makeArray() static @safeCreate an empty array value (`Type.ARRAY`).var makeObject() static @safeCreate an empty map value (`Type.OBJECT`).var emptyArray() static @property @safeReturns an empty array value (`Type.ARRAY`).var emptyObject() static @property @safeReturns an empty object/map value (`Type.OBJECT`).var array_() static @property @safeAlias for `emptyArray`. Returns an empty array value (`Type.ARRAY`).var object_() static @property @safeAlias for `emptyObject`. Returns an empty object/map value (`Type.OBJECT`).var fromArray(T)(T[] arr) static @safeConstruct a `var` from an array `arr`, converting elements to `var`.var fromMap(const var[string] m) static @safeConstruct a `var` from a map `m` (string -> var).Constructors
this(ref return scope inout var rhs) Copy constructor for same-constness copies (mutable→mutable, const→const, immutable→immutable, and compiler-generated `inout` copies in structs that embed `var`): shallow payload copy, mat...this(ref return scope const var rhs)Copy constructor from a `const` `var` into a mutable one: deep copy. A shallow blit would hand back a mutable alias to the const payload, letting @safe callers mutate "const" data (and race on shar...this(ref return scope immutable var rhs)Copy constructor from an `immutable` `var` into a mutable one: deep copy (see the `const` overload).this(ref return scope const var rhs)Copy constructor from a `const` `var` into a `const` one: shallow copy. A const destination cannot be used to mutate the payload, so aliasing is sound.this(ref return scope immutable var rhs)Copy constructor from an `immutable` `var` into a `const` one: shallow copy (a const view of immutable data; nobody can mutate it).this(T arg)Construct a `var` from another value `arg`.Nested Templates
TypeThe concrete type of a `var` value.
ElementTypeElement kind of a native-array value (`Type.NATIVE_ARRAY`).
NativeQualElement qualifier recorded at native-array construction. Controls whether a mutable view may be handed out; const views are always safe.
DecimalCapFixed-decimal capacity of a `Type.FIXED_DECIMAL` value.
_isFDInst(T)True for any `FixedDecimal` instantiation.
_nativeKindOf(T)Maps a (possibly const/immutable-qualified) element type to its kind.
_isSharedQualified(T)True when `T` carries the `shared` qualifier (including shared-const forms).
_isNativeSlice(T)True for dynamic arrays of whitelisted native element types.
_isNativeView(T)True for `const(E)[]` views over whitelisted native element types.
_nativeViewElem(T)Element type of a native view type `const(E)[]`.
_isBareNativeSlice(T)True for unqualified `E[]` slices of whitelisted native element types.
ElementRangeA forward range over the elements of a `var` array.
ConstElementRangeA forward range over the elements of a `const var` array.
KeyRangeA forward range over the keys of a `var` object.
ValueRangeA forward range over the values of a `var` object.
KeyValuePairA key-value pair returned by `PairRange`.
PairRangeA forward range over the key-value pairs of a `var` object.
_PutAdapterNormalizes a sink that provides either put capability to one that provides both.