#!/usr/bin/env dub
/+ dub.sdl:
name "property_tree_open_set_descent"
targetPath "build"
dependency "sparkles:ui" path="../../../.."
dflags "-preview=in" "-preview=dip1000"
buildType "checked" {
buildOptions "optimize" "inline" "debugInfo"
}
+/
/**
* Descent driven by the OPENED SET, over the real `TreeData`/`DisclosureState`.
*
* Three claims under test:
*
* C1. The escape from the CTFE recursion limit is NOT an erasure boundary —
* it is parameterising the walk by TYPE ONLY. `reflect-descent.d` failed
* because its template took (depth, prefix, Seen...), so each path was a
* fresh instantiation. A walk whose only template parameter is `T`
* instantiates once per type and recurses at RUNTIME, with no delegate.
*
* C2. If descent is driven by the user's opened set, no cycle guard is needed
* (the corpus rule: guard only the walk nobody drove). A cyclic value
* yields a finite tree, one level per open.
*
* C3. `DisclosureState.allOpen()` — a polarity flip, O(1) by design — is a
* TRAP here: it makes the walk undriven, and it does not terminate
* without a depth cap.
*
* Run: `dub run --single open-set-descent.d`
*/
module (module) property_tree_open_set_descentDescent driven by the OPENED SET, over the real TreeData/DisclosureState.
Three claims under test:
C1. The escape from the CTFE recursion limit is NOT an erasure boundary —
it is parameterising the walk by TYPE ONLY. reflect-descent.d failed
because its template took (depth, prefix, Seen...), so each path was a
fresh instantiation. A walk whose only template parameter is T
instantiates once per type and recurses at RUNTIME, with no delegate.
C2. If descent is driven by the user's opened set, no cycle guard is needed
(the corpus rule: guard only the walk nobody drove). A cyclic value
yields a finite tree, one level per open.
C3. DisclosureState.allOpen() — a polarity flip, O(1) by design — is a
TRAP here: it makes the walk undriven, and it does not terminate
without a depth cap.
Run
dub run --single open-set-descent.d
property_tree_open_set_descent;
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) property_tree_open_set_descent.text = std.conv.text(T...)(T args) if (T.length > 0)Convenience functions for converting one or more arguments
of any type into text (the three character widths).
text;
import (package) stdstd.(module) std.traitsTemplates which extract information about types and symbols at compile time.
Category Templates Symbol Name traits fullyQualifiedName mangledName moduleName packageName Function traits isFunction arity functionAttributes hasFunctionAttributes functionLinkage FunctionTypeOf isSafe isUnsafe isFinal ParameterDefaults ParameterIdentifierTuple ParameterStorageClassTuple Parameters ReturnType SetFunctionAttributes variadicFunctionStyle Aggregate Type traits BaseClassesTuple BaseTypeTuple classInstanceAlignment EnumMembers FieldNameTuple Fields hasAliasing hasElaborateAssign hasElaborateCopyConstructor hasElaborateDestructor hasElaborateMove hasIndirections hasMember hasStaticMember hasNested hasUnsharedAliasing InterfacesTuple isInnerClass isNested MemberFunctionsTuple RepresentationTypeTuple TemplateArgsOf TemplateOf TransitiveBaseTypeTuple Type Conversion CommonType AllImplicitConversionTargets ImplicitConversionTargets CopyTypeQualifiers CopyConstness isAssignable isCovariantWith isImplicitlyConvertible isQualifierConvertible Type Constructors InoutOf ConstOf SharedOf SharedInoutOf SharedConstOf SharedConstInoutOf ImmutableOf QualifierOf Categories of types allSameType ifTestable isType isAggregateType isArray isAssociativeArray isAutodecodableString isBasicType isBoolean isBuiltinType isCopyable isDynamicArray isEqualityComparable isFloatingPoint isIntegral isNarrowString isConvertibleToString isNumeric isOrderingComparable isPointer isScalarType isSigned isSIMDVector isSomeChar isSomeString isStaticArray isUnsigned Type behaviours isAbstractClass isAbstractFunction isCallable isDelegate isExpressions isFinalClass isFinalFunction isFunctionPointer isInstanceOf isIterable isMutable isSomeFunction isTypeTuple General Types ForeachType KeyType Largest mostNegative OriginalType PointerTarget Signed Unconst Unshared Unqual Unsigned ValueType Promoted Misc lvalueOf rvalueOf Select select User-Defined Attributes hasUDA getUDAs getSymbolsByUDA
Source
std/traits.d
traits : (alias template) property_tree_open_set_descent.FieldNameTuple = std.traits.FieldNameTuple(T)Get as an expression tuple the names of the fields of a struct, class, or
union. This consists of the fields that take up memory space, excluding the
hidden fields like the virtual function table pointer or a context pointer
for nested types.
Inherited fields (for classes) are not included.
If T isn't a struct, class, interface or union, an
expression tuple with an empty string is returned.
FieldNameTuple, (alias template) property_tree_open_set_descent.Fields = std.traits.Fields(T)Get as a tuple the types of the fields of a struct, class, or union.
This consists of the fields that take up memory space,
excluding the hidden fields like the virtual function
table pointer or a context pointer for nested types.
If T isn't a struct, class, interface or union returns a tuple
with one element T.
Fields, (alias template) property_tree_open_set_descent.isAggregateType = std.traits.isAggregateType(T)Detect whether type T is an aggregate type.
isAggregateType, (alias template) property_tree_open_set_descent.isArray = std.traits.isArray(T)Detect whether type T is an array (static or dynamic; for associative
arrays see isAssociativeArray).
isArray,
(alias template) property_tree_open_set_descent.isPointer = std.traits.isPointer(T)Detect whether type T is a pointer.
isPointer, (alias template) property_tree_open_set_descent.isSomeString = std.traits.isSomeString(T)Detect whether T is one of the built-in string types.
The built-in string types are Char[], where Char is any of char,
wchar or dchar, with or without qualifiers.
Static arrays of characters (like char[80]) are not considered
built-in string types.
isSomeString, (alias template) property_tree_open_set_descent.PointerTarget = std.traits.PointerTarget(T : T*)Returns the target type of a pointer.
PointerTarget;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.tree_widgetThe tree component (WGT12, VMD1–VMD6) — the exemplar of the
view-model/view split, built to the tree-view case study's three-layer design:
data (TreeData) — a flat node arena with parent/child/sibling
index links. No interaction state, no decoration: an independent
structural snapshot needs one explicit arena duplication. The current D
slice aliases under default copy (UI-O1), and T supplies its own copy
contract.
interaction — an opened set (DisclosureState), a selection, a scroll offset — lives beside
the data, keyed by identity, so one tree can back several independent
views.
view (treeView) — a pure function from both to a widget
subtree; owns glyphs and slots only.
flatten — hierarchy to the visible rows — is a pure free function
with no lazy loading and no filtering mixed in (the case study names mixing
them as the failure mode), and it precomputes the four-state guide model
(space / continue / fork / end) per depth level, so no renderer re-derives
rails per frame.
tree_widget : (alias template) property_tree_open_set_descent.flatten = sparkles.ui.components.tree_widget.flatten(T)(in TreeData!T data, scope bool delegate(uint) @safe isOpen)The flatten step (VMD3): hierarchy → the visible rows, honoring isOpen
(closed nodes keep their subtree out). Pure and free — no lazy loading, no
filtering — and the guides are computed here, once, from a per-depth
"has later siblings" accumulator (broot's precomputed rails).
flatten, (alias struct) property_tree_open_set_descent.TreeData = sparkles.ui.components.tree_widget.TreeData(T)The data layer (VMD1): a flat arena of T values with index links. add
appends under a parent (or as a root), maintaining sibling chains; there is no
remove — rebuild instead (flat storage is what makes per-keystroke rebuilding
viable, per the case study's tree-as-search-result mode).
TreeData;
import (package) sparklessparkles.(package) sparkles.uiui.(module) sparkles.ui.stateThe state level (STM) of sparkles.ui: presentation-free interaction
state machines fed the shared sparkles:input events — pure logic over
abstract input, producing state and derived geometry in abstract units, with
no draw calls and no device units.
Machines are advanced by transformations and are intended to be Regular
values. Scalar and immutable-payload machines meet that contract;
DisclosureState's exposed slice still needs the ownership/copy policy tracked
by UI-O1. They advance as state`.stepped(…) → `state (the caller assigns),
never by mutating shared locals — so behavior can be snapshotted, replayed and
diffed in tests. And
every machine exists once: where behavior was written per backend it
diverged (two scrollbar thumb formulas scrolling the same document
differently; one copy affordance flashing on a timer while another held until
the next event), which is precisely the "correctness does not compose" defect
this level removes.
HoverState + hoverTargets — which element is hot (STM4)
scrollbarThumb + ScrollState — one thumb formula (STM2)
Selection — normalized anchor/focus, no -1 sentinel (STM3)
DisclosureState — one opened/closed set for tree expansion
and content folding (STM5)
Timeline — transient effects as modes, not bare counters (STM6)
FocusState — keyboard focus + deterministic traversal (STM7)
SplitState — a draggable pane divider (STM8)
PressState — press arms, release-over-the-same-target
activates (STM10)
CaptureState — press owns the drag; one affordance holds the
pointer until release (STM11)
state : (alias struct) property_tree_open_set_descent.DisclosureState = sparkles.ui.state.DisclosureState(Key)One opened/collapsed machine (STM5) serving both tree expand/collapse
and content folding — the same question over different keys. The state is a
default polarity plus a sorted set of exceptions, so a tree (default
closed, opening nodes) and a folded document (default open, closing regions)
share the machine, and "open all" / "close all" are O(1) resets rather than
enumerations.
Transformations return new values and copy the exception set on change, so the
public operations support snapshot/replay without mutating an earlier state.
The exposed D slice still aliases under a default struct copy; UI-O1 tracks
the representation work required before this type can claim full Regular value
semantics.
DisclosureState;
@safe:
/// The row model. `composite` is a TYPE fact, known even when the node is
/// closed and its children were never materialised.
struct (struct) property_tree_open_set_descent.PropNodeThe row model. composite is a TYPE fact, known even when the node is
closed and its children were never materialised.
PropNode
{
(alias) object.string = stringstring (field) string property_tree_open_set_descent.PropNode.paththe Key: a dotted path
path; /// the Key: a dotted path
(alias) object.string = stringstring (field) string property_tree_open_set_descent.PropNode.labellast segment
label; /// last segment
(alias) object.string = stringstring (field) string property_tree_open_set_descent.PropNode.typeNametypeName; ///
(alias) object.string = stringstring (field) string property_tree_open_set_descent.PropNode.valuepresented scalar, empty for composites
value; /// presented scalar, empty for composites
bool (field) bool property_tree_open_set_descent.PropNode.compositethe type has children
composite; /// the type has children
bool (field) bool property_tree_open_set_descent.PropNode.cappedcomposite, open, but the depth cap refused to descend
capped; /// composite, open, but the depth cap refused to descend
}
private enum bool (constant) bool property_tree_open_set_descent.isLeafType!(property_tree_open_set_descent.Material) = falseisLeafType(T) = (template instance) std.traits.isSomeString!(property_tree_open_set_descent.Material)isSomeString!(alias) T = property_tree_open_set_descent.MaterialT || !(template instance) std.traits.isAggregateType!(property_tree_open_set_descent.Material)isAggregateType!(alias) T = property_tree_open_set_descent.MaterialT;
/// Everything the walk needs, as one value — so the walk itself takes only `T`.
struct (struct) property_tree_open_set_descent.DescentEverything the walk needs, as one value — so the walk itself takes only T.
Descent
{
(struct) sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode)The data layer (VMD1): a flat arena of T values with index links. add
appends under a parent (or as a root), maintaining sibling chains; there is no
remove — rebuild instead (flat storage is what makes per-keystroke rebuilding
viable, per the case study's tree-as-search-result mode).
TreeData!(struct) property_tree_open_set_descent.PropNodeThe row model. composite is a TYPE fact, known even when the node is
closed and its children were never materialised.
PropNode (field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata;
(struct) sparkles.ui.state.DisclosureState!stringOne opened/collapsed machine (STM5) serving both tree expand/collapse
and content folding — the same question over different keys. The state is a
default polarity plus a sorted set of exceptions, so a tree (default
closed, opening nodes) and a folded document (default open, closing regions)
share the machine, and "open all" / "close all" are O(1) resets rather than
enumerations.
Transformations return new values and copy the exception set on change, so the
public operations support snapshot/replay without mutating an earlier state.
The exposed D slice still aliases under a default struct copy; UI-O1 tracks
the representation work required before this type can claim full Regular value
semantics.
DisclosureState!(alias) object.string = stringstring (field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.openopen;
int (field) int property_tree_open_set_descent.Descent.maxDepththe cap that makes an undriven walk finite
maxDepth = 8; /// the cap that makes an undriven walk finite
(alias) object.size_t = ulongsize_t (field) ulong property_tree_open_set_descent.Descent.maxNodesmaxNodes = 5000;
(alias) object.size_t = ulongsize_t (field) ulong property_tree_open_set_descent.Descent.visitednodes materialised
visited; /// nodes materialised
}
/**
* The walk. Note the signature: `T` is the ONLY template parameter — path and
* depth are runtime arguments. That is what makes a self-referential type
* compile: `descend!Node` calls `descend!Node`, an ordinary recursive function.
*/
void void property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node)(ref property_tree_open_set_descent.Descent d, ref property_tree_open_set_descent.Node value, uint parent, string prefix, int depth) pure @safeThe walk. Note the signature: T is the ONLY template parameter — path and
depth are runtime arguments. That is what makes a self-referential type
compile: descend`!Node` calls descend!Node, an ordinary recursive function.
descend(T)(ref (struct) property_tree_open_set_descent.DescentEverything the walk needs, as one value — so the walk itself takes only T.
Descent (parameter) property_tree_open_set_descent.Descent dd, ref (alias) T = property_tree_open_set_descent.NodeT (parameter) property_tree_open_set_descent.Node valuevalue, uint (parameter) uint parentparent, (alias) object.string = stringstring (parameter) string prefixprefix, int (parameter) int depthdepth)
{
static foreach (i, name; (constant) string property_tree_open_set_descent.Node.fun!(label).NameOf = "label"FieldNameTuple!T)
{{
alias (alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = stringF = (alias) std.traits.Fields!(property_tree_open_set_descent.Node) = (string, property_tree_open_set_descent.Vec2, property_tree_open_set_descent.Material, property_tree_open_set_descent.Node*)Get as a tuple the types of the fields of a struct, class, or union.
This consists of the fields that take up memory space,
excluding the hidden fields like the virtual function
table pointer or a context pointer for nested types.
If T isn't a struct, class, interface or union returns a tuple
with one element T.
Examples
import std.meta : AliasSeq;
struct S { int x; float y; }
static assert(is(Fields!S == AliasSeq!(int, float)));
Fields!(alias) T = property_tree_open_set_descent.NodeT[(constant) ulong property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).i = 0LUi];
static if ((template instance) std.traits.isPointer!stringisPointer!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = stringF && (template instance) isAggregateType!(PointerTarget!F)isAggregateType!((alias) T = property_tree_open_set_descent.NodePointerTarget!(unresolved type) FF))
alias (alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.NodeTarget = (alias) T = property_tree_open_set_descent.NodePointerTarget!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = property_tree_open_set_descent.Node*F;
else
alias (alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = stringTarget = (alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = stringF;
const (local variable) const(string) pathpath = (parameter) string prefixprefix.(field) ulong string.lengthlength ? (parameter) string prefixprefix ~ "." ~ name : (constant) string property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).name = "label"name;
static if ((template instance) property_tree_open_set_descent.isLeafType!stringisLeafType!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = stringTarget)
{
(parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata.uint sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).add(property_tree_open_set_descent.PropNode value, uint parent = 4294967295u) pure nothrow @safeAppends value under parent (uint.max = a new root); returns its index.
add((struct) property_tree_open_set_descent.PropNodeThe row model. composite is a TYPE fact, known even when the node is
closed and its children were never materialised.
PropNode((local variable) const(string) pathpath, (constant) string property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).name = "label"name, (darray) stringF.(constant) string string.stringof = "string"stringof,
string property_tree_open_set_descent.present!string(in string v) pure nothrow @safepresent(__traits(getMember, value, name)), false, false), (parameter) uint parentparent);
(parameter) property_tree_open_set_descent.Descent dd.(field) ulong property_tree_open_set_descent.Descent.visitednodes materialised
visited++;
}
else
{
const (local variable) const(bool) wantOpenwantOpen = (parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.openopen.bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safetrue iff k is open under the current polarity + exceptions.
isOpen((local variable) const(string) pathpath);
const (local variable) const(bool) cappedcapped = (local variable) const(bool) wantOpenwantOpen && (parameter) int depthdepth + 1 >= (parameter) property_tree_open_set_descent.Descent dd.(field) int property_tree_open_set_descent.Descent.maxDepththe cap that makes an undriven walk finite
maxDepth;
const (local variable) const(uint) nodenode = (parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata.uint sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).add(property_tree_open_set_descent.PropNode value, uint parent = 4294967295u) pure nothrow @safeAppends value under parent (uint.max = a new root); returns its index.
add((struct) property_tree_open_set_descent.PropNodeThe row model. composite is a TYPE fact, known even when the node is
closed and its children were never materialised.
PropNode((local variable) const(string) pathpath, (constant) string property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).name = "position"name, (struct) property_tree_open_set_descent.Vec2F.(constant) string property_tree_open_set_descent.Vec2.stringof = "Vec2"stringof,
composite: true, capped: (local variable) const(bool) cappedcapped), (parameter) uint parentparent);
(parameter) property_tree_open_set_descent.Descent dd.(field) ulong property_tree_open_set_descent.Descent.visitednodes materialised
visited++;
if ((local variable) const(bool) wantOpenwantOpen && !(local variable) const(bool) cappedcapped && (parameter) property_tree_open_set_descent.Descent dd.(field) ulong property_tree_open_set_descent.Descent.visitednodes materialised
visited < (parameter) property_tree_open_set_descent.Descent dd.(field) ulong property_tree_open_set_descent.Descent.maxNodesmaxNodes)
{
static if ((template instance) std.traits.isPointer!(property_tree_open_set_descent.Vec2)isPointer!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = property_tree_open_set_descent.Vec2F)
{
auto (local variable) property_tree_open_set_descent.Node* pp = __traits(getMember, value, name);
if ((local variable) property_tree_open_set_descent.Node* pp !is null)
void property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node)(ref property_tree_open_set_descent.Descent d, ref property_tree_open_set_descent.Node value, uint parent, string prefix, int depth) pure @safeThe walk. Note the signature: T is the ONLY template parameter — path and
depth are runtime arguments. That is what makes a self-referential type
compile: descend`!Node` calls descend!Node, an ordinary recursive function.
descend!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.NodeTarget((parameter) property_tree_open_set_descent.Descent dd, *(local variable) property_tree_open_set_descent.Node* pp, (local variable) const(uint) nodenode, (local variable) const(string) pathpath, (parameter) int depthdepth + 1);
}
else
void property_tree_open_set_descent.descend!(property_tree_open_set_descent.Vec2)(ref property_tree_open_set_descent.Descent d, ref property_tree_open_set_descent.Vec2 value, uint parent, string prefix, int depth) pure @safeThe walk. Note the signature: T is the ONLY template parameter — path and
depth are runtime arguments. That is what makes a self-referential type
compile: descend`!Node` calls descend!Node, an ordinary recursive function.
descend!(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.Vec2Target((parameter) property_tree_open_set_descent.Descent dd, __traits(getMember, value, name), (local variable) const(uint) nodenode,
(local variable) const(string) pathpath, (parameter) int depthdepth + 1);
}
}
}}
}
private (alias) object.string = stringstring string property_tree_open_set_descent.present!string(in string v) pure nothrow @safepresent(T)(in (alias) T = stringT (parameter) const(string) vv)
{
static if ((template instance) std.traits.isSomeString!stringisSomeString!(alias) T = stringT)
return `"` ~ (parameter) const(string) vv.string object.idup!(immutable(char))(string a) pure nothrow @property @safeProvide the .idup array property, which creates an immutable duplicate.
idup ~ `"`;
else
return string std.conv.text!(const(float))(const(float) __param_0) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text((parameter) const(float) vv);
}
// ── the subject ──────────────────────────────────────────────────────────────
struct (struct) property_tree_open_set_descent.Vec2Vec2 { float (field) float property_tree_open_set_descent.Vec2.xx = 0, (field) float property_tree_open_set_descent.Vec2.yy = 0; }
struct (struct) property_tree_open_set_descent.MaterialMaterial { (alias) object.string = stringstring (field) string property_tree_open_set_descent.Material.namename; (struct) property_tree_open_set_descent.Vec2Vec2 (field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Material.offsetoffset; }
struct (struct) property_tree_open_set_descent.NodeNode
{
(alias) object.string = stringstring (field) string property_tree_open_set_descent.Node.labellabel;
(struct) property_tree_open_set_descent.Vec2Vec2 (field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Node.positionposition;
(struct) property_tree_open_set_descent.MaterialMaterial (field) property_tree_open_set_descent.Material property_tree_open_set_descent.Node.materialmaterial;
(struct) property_tree_open_set_descent.NodeNode* (field) property_tree_open_set_descent.Node* property_tree_open_set_descent.Node.parentparent; // the cycle
}
// ── driving ──────────────────────────────────────────────────────────────────
(struct) property_tree_open_set_descent.DescentEverything the walk needs, as one value — so the walk itself takes only T.
Descent property_tree_open_set_descent.Descent property_tree_open_set_descent.build(ref property_tree_open_set_descent.Node subject, sparkles.ui.state.DisclosureState!string open, int maxDepth = 8) @safebuild(ref (struct) property_tree_open_set_descent.NodeNode (parameter) property_tree_open_set_descent.Node subjectsubject, (struct) sparkles.ui.state.DisclosureState!stringOne opened/collapsed machine (STM5) serving both tree expand/collapse
and content folding — the same question over different keys. The state is a
default polarity plus a sorted set of exceptions, so a tree (default
closed, opening nodes) and a folded document (default open, closing regions)
share the machine, and "open all" / "close all" are O(1) resets rather than
enumerations.
Transformations return new values and copy the exception set on change, so the
public operations support snapshot/replay without mutating an earlier state.
The exposed D slice still aliases under a default struct copy; UI-O1 tracks
the representation work required before this type can claim full Regular value
semantics.
DisclosureState!(alias) object.string = stringstring (parameter) sparkles.ui.state.DisclosureState!string openopen, int (parameter) int maxDepthmaxDepth = 8)
{
auto (local variable) property_tree_open_set_descent.Descent dd = (struct) property_tree_open_set_descent.DescentEverything the walk needs, as one value — so the walk itself takes only T.
Descent(open: (parameter) sparkles.ui.state.DisclosureState!string openopen, maxDepth: (parameter) int maxDepthmaxDepth);
void property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node)(ref property_tree_open_set_descent.Descent d, ref property_tree_open_set_descent.Node value, uint parent, string prefix, int depth) pure @safeThe walk. Note the signature: T is the ONLY template parameter — path and
depth are runtime arguments. That is what makes a self-referential type
compile: descend`!Node` calls descend!Node, an ordinary recursive function.
descend!(struct) property_tree_open_set_descent.NodeNode((local variable) property_tree_open_set_descent.Descent dd, (parameter) property_tree_open_set_descent.Node subjectsubject, uint.(constant) uint uint.max = 4294967295umax, "", 0);
return (local variable) property_tree_open_set_descent.Descent dd;
}
void void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safedump(ref (struct) property_tree_open_set_descent.DescentEverything the walk needs, as one value — so the walk itself takes only T.
Descent (parameter) property_tree_open_set_descent.Descent dd)
{
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : (alias template) writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))Equivalent to $(D writef(fmt, args, '\n')).
writefln;
auto (local variable) sparkles.ui.components.tree_widget.FlatTreeRow[] rowsrows = sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_widget.flatten!(property_tree_open_set_descent.PropNode)(in sparkles.ui.components.tree_widget.TreeData!(PropNode) data, scope bool delegate(uint) @safe isOpen) @safeThe flatten step (VMD3): hierarchy → the visible rows, honoring isOpen
(closed nodes keep their subtree out). Pure and free — no lazy loading, no
filtering — and the guides are computed here, once, from a per-depth
"has later siblings" accumulator (broot's precomputed rails).
flatten!(struct) property_tree_open_set_descent.PropNodeThe row model. composite is a TYPE fact, known even when the node is
closed and its children were never materialised.
PropNode((parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata,
(uint (parameter) uint nn) => (parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.openopen.bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safetrue iff k is open under the current polarity + exceptions.
isOpen((parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).nodesnodes[(parameter) uint nn].(field) property_tree_open_set_descent.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).Node.valuevalue.(field) string property_tree_open_set_descent.PropNode.paththe Key: a dotted path
path));
foreach ((parameter) sparkles.ui.components.tree_widget.FlatTreeRow rr; (local variable) sparkles.ui.components.tree_widget.FlatTreeRow[] rowsrows)
{
auto (local variable) property_tree_open_set_descent.PropNode nn = (parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.datadata.(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).nodesnodes[(local variable) sparkles.ui.components.tree_widget.FlatTreeRow rr.(field) uint sparkles.ui.components.tree_widget.FlatTreeRow.nodenode].(field) property_tree_open_set_descent.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).Node.valuevalue;
(alias) object.string = stringstring (local variable) string indentindent;
foreach ((local variable) int __; 0 .. (local variable) sparkles.ui.components.tree_widget.FlatTreeRow rr.(field) int sparkles.ui.components.tree_widget.FlatTreeRow.depthdepth) (local variable) string indentindent ~= " ";
const (local variable) const(string) markermarker = !(local variable) property_tree_open_set_descent.PropNode nn.(field) bool property_tree_open_set_descent.PropNode.compositethe type has children
composite ? " "
: (local variable) property_tree_open_set_descent.PropNode nn.(field) bool property_tree_open_set_descent.PropNode.cappedcomposite, open, but the depth cap refused to descend
capped ? "⋯ "
: (parameter) property_tree_open_set_descent.Descent dd.(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.openopen.bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safetrue iff k is open under the current polarity + exceptions.
isOpen((local variable) property_tree_open_set_descent.PropNode nn.(field) string property_tree_open_set_descent.PropNode.paththe Key: a dotted path
path) ? "▾ " : "▸ ";
void std.stdio.writefln!(char, string, string, string, string, string)(in char[] fmt, string __param_1, string __param_2, string __param_3, string __param_4, string __param_5) @safeEquivalent to writef(fmt, args, '\n').
writefln("%s%s%-12s %-10s %s", (local variable) string indentindent, (local variable) const(string) markermarker, (local variable) property_tree_open_set_descent.PropNode nn.(field) string property_tree_open_set_descent.PropNode.labellast segment
label, (local variable) property_tree_open_set_descent.PropNode nn.(field) string property_tree_open_set_descent.PropNode.typeNametypeName,
(local variable) property_tree_open_set_descent.PropNode nn.(field) bool property_tree_open_set_descent.PropNode.compositethe type has children
composite ? ((local variable) property_tree_open_set_descent.PropNode nn.(field) bool property_tree_open_set_descent.PropNode.cappedcomposite, open, but the depth cap refused to descend
capped ? "(capped)" : "") : (local variable) property_tree_open_set_descent.PropNode nn.(field) string property_tree_open_set_descent.PropNode.valuepresented scalar, empty for composites
value);
}
void std.stdio.writefln!(char, ulong)(in char[] fmt, ulong __param_1) @safeEquivalent to writef(fmt, args, '\n').
writefln(" → %s rows materialised", (local variable) sparkles.ui.components.tree_widget.FlatTreeRow[] rowsrows.(field) ulong sparkles.ui.components.tree_widget.FlatTreeRow[].lengthlength);
}
void void D main() @safemain()
{
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : (alias template) writeln = std.stdio.writeln(T...)(T args)Equivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Params:
args = the items to write to stdout
Throws:
In case of an I/O error, throws an $(LREF StdioException).
Example:
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
---
writeln, (alias template) writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))Equivalent to $(D writef(fmt, args, '\n')).
writefln;
(struct) property_tree_open_set_descent.NodeNode (local variable) property_tree_open_set_descent.Node rootroot = (struct) property_tree_open_set_descent.NodeNode("root");
() @trusted { (local variable) property_tree_open_set_descent.Node rootroot.(field) property_tree_open_set_descent.Node* property_tree_open_set_descent.Node.parentparent = &(local variable) property_tree_open_set_descent.Node rootroot; }();
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("C1 — a walk parameterised by TYPE ONLY compiles on a cyclic type.");
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln(" (this program built; `reflect-descent.d` could not)\n");
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("C2 — nothing open: one level, composites marked closed");
auto (local variable) property_tree_open_set_descent.Descent d0d0 = property_tree_open_set_descent.Descent property_tree_open_set_descent.build(ref property_tree_open_set_descent.Node subject, sparkles.ui.state.DisclosureState!string open, int maxDepth = 8) @safebuild((local variable) property_tree_open_set_descent.Node rootroot, (template instance) sparkles.ui.state.DisclosureState!stringDisclosureState!(alias) object.string = stringstring.sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allClosed() pure nothrow @nogc @safeEverything open / everything closed (zR / zM): a polarity reset.
allClosed());
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safedump((local variable) property_tree_open_set_descent.Descent d0d0);
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("\nC2 — the reader opens `parent`, then `parent.parent`:");
auto (local variable) sparkles.ui.state.DisclosureState!string openopen = (template instance) sparkles.ui.state.DisclosureState!stringDisclosureState!(alias) object.string = stringstring.sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allClosed() pure nothrow @nogc @safeEverything open / everything closed (zR / zM): a polarity reset.
allClosed()
.sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.opened(string k) const pure nothrow @safeThis state with k forced open / closed.
opened("parent").sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.opened(string k) const pure nothrow @safeThis state with k forced open / closed.
opened("parent.parent");
auto (local variable) property_tree_open_set_descent.Descent d1d1 = property_tree_open_set_descent.Descent property_tree_open_set_descent.build(ref property_tree_open_set_descent.Node subject, sparkles.ui.state.DisclosureState!string open, int maxDepth = 8) @safebuild((local variable) property_tree_open_set_descent.Node rootroot, (local variable) sparkles.ui.state.DisclosureState!string openopen);
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safedump((local variable) property_tree_open_set_descent.Descent d1d1);
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("\nC2 — same opened set, subject MUTATED: expansion survives");
(local variable) property_tree_open_set_descent.Node rootroot.(field) string property_tree_open_set_descent.Node.labellabel = "renamed";
(local variable) property_tree_open_set_descent.Node rootroot.(field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Node.positionposition.(field) float property_tree_open_set_descent.Vec2.xx = 3;
auto (local variable) property_tree_open_set_descent.Descent d2d2 = property_tree_open_set_descent.Descent property_tree_open_set_descent.build(ref property_tree_open_set_descent.Node subject, sparkles.ui.state.DisclosureState!string open, int maxDepth = 8) @safebuild((local variable) property_tree_open_set_descent.Node rootroot, (local variable) sparkles.ui.state.DisclosureState!string openopen);
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safedump((local variable) property_tree_open_set_descent.Descent d2d2);
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("\nC3 — allOpen(): the walk is now undriven. Depth cap = 4:");
auto (local variable) property_tree_open_set_descent.Descent d3d3 = property_tree_open_set_descent.Descent property_tree_open_set_descent.build(ref property_tree_open_set_descent.Node subject, sparkles.ui.state.DisclosureState!string open, int maxDepth = 8) @safebuild((local variable) property_tree_open_set_descent.Node rootroot, (template instance) sparkles.ui.state.DisclosureState!stringDisclosureState!(alias) object.string = stringstring.sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allOpen() pure nothrow @nogc @safeEverything open / everything closed (zR / zM): a polarity reset.
allOpen(), 4);
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safedump((local variable) property_tree_open_set_descent.Descent d3d3);
void std.stdio.writefln!(char, ulong)(in char[] fmt, ulong __param_1) @safeEquivalent to writef(fmt, args, '\n').
writefln(" without a cap this does not terminate; with it: %s nodes",
(local variable) property_tree_open_set_descent.Descent d3d3.(field) ulong property_tree_open_set_descent.Descent.visitednodes materialised
visited);
}