open-set-descent.dhover×306all
#!/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_descent

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

property_tree_open_set_descent
;
import
(package) std
std
.
(module) std.conv

A 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

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
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) std
std
.
(module) std.traits

Templates 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

@copyrightCopyright The D Language Foundation 2005 - 2009.@licenseBoost License 1.0.@authorsWalter Bright, Tomasz Stachowiak (isExpressions), Andrei Alexandrescu, Shin Fujishiro, Robert Clipsham, David Nadlinger, Kenji Hara, Shoichi Kato
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.

@history
  • Returned AliasSeq!"" for interfaces prior to 2.097

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.

@history
  • Returned AliasSeq!(Interface) for interfaces prior to 2.097

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) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.tree_widget

The tree component (WGT12, VMD1VMD6) — 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) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(module) sparkles.ui.state

The 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.PropNode

The row model. composite is a TYPE fact, known even when the node is closed and its children were never materialised.

PropNode
{
(alias) object.string = string
string
(field) string property_tree_open_set_descent.PropNode.path

the Key: a dotted path

path
; /// the Key: a dotted path
(alias) object.string = string
string
(field) string property_tree_open_set_descent.PropNode.label

last segment

label
; /// last segment
(alias) object.string = string
string
(field) string property_tree_open_set_descent.PropNode.typeName
typeName
; ///
(alias) object.string = string
string
(field) string property_tree_open_set_descent.PropNode.value

presented scalar, empty for composites

value
; /// presented scalar, empty for composites
bool
(field) bool property_tree_open_set_descent.PropNode.composite

the type has children

composite
; /// the type has children
bool
(field) bool property_tree_open_set_descent.PropNode.capped

composite, 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) = false
isLeafType
(T) =
(template instance) std.traits.isSomeString!(property_tree_open_set_descent.Material)
isSomeString
!
(alias) T = property_tree_open_set_descent.Material
T
|| !
(template instance) std.traits.isAggregateType!(property_tree_open_set_descent.Material)
isAggregateType
!
(alias) T = property_tree_open_set_descent.Material
T
;
/// Everything the walk needs, as one value — so the walk itself takes only `T`. struct
(struct) property_tree_open_set_descent.Descent

Everything 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.PropNode

The 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.data
data
;
(struct) sparkles.ui.state.DisclosureState!string

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
!
(alias) object.string = string
string
(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.open
open
;
int
(field) int property_tree_open_set_descent.Descent.maxDepth

the cap that makes an undriven walk finite

maxDepth
= 8; /// the cap that makes an undriven walk finite
(alias) object.size_t = ulong
size_t
(field) ulong property_tree_open_set_descent.Descent.maxNodes
maxNodes
= 5000;
(alias) object.size_t = ulong
size_t
(field) ulong property_tree_open_set_descent.Descent.visited

nodes 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 @safe

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.

descend
(T)(ref
(struct) property_tree_open_set_descent.Descent

Everything the walk needs, as one value — so the walk itself takes only T.

Descent
(parameter) property_tree_open_set_descent.Descent d
d
, ref
(alias) T = property_tree_open_set_descent.Node
T
(parameter) property_tree_open_set_descent.Node value
value
, uint
(parameter) uint parent
parent
,
(alias) object.string = string
string
(parameter) string prefix
prefix
, int
(parameter) int depth
depth
)
{ 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 = string
F
=
(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)));
@history
  • Returned AliasSeq!(Interface) for interfaces prior to 2.097

Fields
!
(alias) T = property_tree_open_set_descent.Node
T
[
(constant) ulong property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).i = 0LU
i
];
static if (
(template instance) std.traits.isPointer!string
isPointer
!
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = string
F
&&
(template instance) isAggregateType!(PointerTarget!F)
isAggregateType
!(
(alias) T = property_tree_open_set_descent.Node
PointerTarget
!
(unresolved type) F
F
))
alias
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.Node
Target
=
(alias) T = property_tree_open_set_descent.Node
PointerTarget
!
(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 = string
Target
=
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).F = string
F
;
const
(local variable) const(string) path
path
=
(parameter) string prefix
prefix
.
(field) ulong string.length
length
?
(parameter) string prefix
prefix
~ "." ~ 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!string
isLeafType
!
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = string
Target
)
{
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.data
data
.
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 @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_open_set_descent.PropNode

The 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) path
path
,
(constant) string property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).name = "label"
name
,
(darray) string
F
.
(constant) string string.stringof = "string"
stringof
,
string property_tree_open_set_descent.present!string(in string v) pure nothrow @safe
present
(__traits(getMember, value, name)), false, false),
(parameter) uint parent
parent
);
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) ulong property_tree_open_set_descent.Descent.visited

nodes materialised

visited
++;
} else { const
(local variable) const(bool) wantOpen
wantOpen
=
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.open
open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(local variable) const(string) path
path
);
const
(local variable) const(bool) capped
capped
=
(local variable) const(bool) wantOpen
wantOpen
&&
(parameter) int depth
depth
+ 1 >=
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) int property_tree_open_set_descent.Descent.maxDepth

the cap that makes an undriven walk finite

maxDepth
;
const
(local variable) const(uint) node
node
=
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.data
data
.
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 @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_open_set_descent.PropNode

The 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) path
path
,
(constant) string property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).name = "position"
name
,
(struct) property_tree_open_set_descent.Vec2
F
.
(constant) string property_tree_open_set_descent.Vec2.stringof = "Vec2"
stringof
,
composite: true, capped:
(local variable) const(bool) capped
capped
),
(parameter) uint parent
parent
);
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) ulong property_tree_open_set_descent.Descent.visited

nodes materialised

visited
++;
if (
(local variable) const(bool) wantOpen
wantOpen
&& !
(local variable) const(bool) capped
capped
&&
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) ulong property_tree_open_set_descent.Descent.visited

nodes materialised

visited
<
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) ulong property_tree_open_set_descent.Descent.maxNodes
maxNodes
)
{ 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.Vec2
F
)
{ auto
(local variable) property_tree_open_set_descent.Node* p
p
= __traits(getMember, value, name);
if (
(local variable) property_tree_open_set_descent.Node* p
p
!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 @safe

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.

descend
!
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.Node
Target
(
(parameter) property_tree_open_set_descent.Descent d
d
, *
(local variable) property_tree_open_set_descent.Node* p
p
,
(local variable) const(uint) node
node
,
(local variable) const(string) path
path
,
(parameter) int depth
depth
+ 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 @safe

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.

descend
!
(alias) property_tree_open_set_descent.descend!(property_tree_open_set_descent.Node).Target = property_tree_open_set_descent.Vec2
Target
(
(parameter) property_tree_open_set_descent.Descent d
d
, __traits(getMember, value, name),
(local variable) const(uint) node
node
,
(local variable) const(string) path
path
,
(parameter) int depth
depth
+ 1);
} } }} } private
(alias) object.string = string
string
string property_tree_open_set_descent.present!string(in string v) pure nothrow @safe
present
(T)(in
(alias) T = string
T
(parameter) const(string) v
v
)
{ static if (
(template instance) std.traits.isSomeString!string
isSomeString
!
(alias) T = string
T
)
return `"` ~
(parameter) const(string) v
v
.
string object.idup!(immutable(char))(string a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
~ `"`;
else return
string std.conv.text!(const(float))(const(float) __param_0) pure @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
(
(parameter) const(float) v
v
);
} // ── the subject ────────────────────────────────────────────────────────────── struct
(struct) property_tree_open_set_descent.Vec2
Vec2
{ float
(field) float property_tree_open_set_descent.Vec2.x
x
= 0,
(field) float property_tree_open_set_descent.Vec2.y
y
= 0; }
struct
(struct) property_tree_open_set_descent.Material
Material
{
(alias) object.string = string
string
(field) string property_tree_open_set_descent.Material.name
name
;
(struct) property_tree_open_set_descent.Vec2
Vec2
(field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Material.offset
offset
; }
struct
(struct) property_tree_open_set_descent.Node
Node
{
(alias) object.string = string
string
(field) string property_tree_open_set_descent.Node.label
label
;
(struct) property_tree_open_set_descent.Vec2
Vec2
(field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Node.position
position
;
(struct) property_tree_open_set_descent.Material
Material
(field) property_tree_open_set_descent.Material property_tree_open_set_descent.Node.material
material
;
(struct) property_tree_open_set_descent.Node
Node
*
(field) property_tree_open_set_descent.Node* property_tree_open_set_descent.Node.parent
parent
; // the cycle
} // ── driving ──────────────────────────────────────────────────────────────────
(struct) property_tree_open_set_descent.Descent

Everything 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) @safe
build
(ref
(struct) property_tree_open_set_descent.Node
Node
(parameter) property_tree_open_set_descent.Node subject
subject
,
(struct) sparkles.ui.state.DisclosureState!string

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
!
(alias) object.string = string
string
(parameter) sparkles.ui.state.DisclosureState!string open
open
, int
(parameter) int maxDepth
maxDepth
= 8)
{ auto
(local variable) property_tree_open_set_descent.Descent d
d
=
(struct) property_tree_open_set_descent.Descent

Everything the walk needs, as one value — so the walk itself takes only T.

Descent
(open:
(parameter) sparkles.ui.state.DisclosureState!string open
open
, maxDepth:
(parameter) int maxDepth
maxDepth
);
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 @safe

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.

descend
!
(struct) property_tree_open_set_descent.Node
Node
(
(local variable) property_tree_open_set_descent.Descent d
d
,
(parameter) property_tree_open_set_descent.Node subject
subject
, uint.
(constant) uint uint.max = 4294967295u
max
, "", 0);
return
(local variable) property_tree_open_set_descent.Descent d
d
;
} void
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safe
dump
(ref
(struct) property_tree_open_set_descent.Descent

Everything the walk needs, as one value — so the walk itself takes only T.

Descent
(parameter) property_tree_open_set_descent.Descent d
d
)
{ import
(package) std
std
.
(module) std.stdio
Category 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:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
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[] rows
rows
=
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) @safe

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
!
(struct) property_tree_open_set_descent.PropNode

The 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 d
d
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.data
data
,
(uint
(parameter) uint n
n
) =>
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.open
open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.data
data
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).nodes
nodes
[
(parameter) uint n
n
].
(field) property_tree_open_set_descent.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).Node.value
value
.
(field) string property_tree_open_set_descent.PropNode.path

the Key: a dotted path

path
));
foreach (
(parameter) sparkles.ui.components.tree_widget.FlatTreeRow r
r
;
(local variable) sparkles.ui.components.tree_widget.FlatTreeRow[] rows
rows
)
{ auto
(local variable) property_tree_open_set_descent.PropNode n
n
=
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_open_set_descent.Descent.data
data
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).nodes
nodes
[
(local variable) sparkles.ui.components.tree_widget.FlatTreeRow r
r
.
(field) uint sparkles.ui.components.tree_widget.FlatTreeRow.node
node
].
(field) property_tree_open_set_descent.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_open_set_descent.PropNode).Node.value
value
;
(alias) object.string = string
string
(local variable) string indent
indent
;
foreach (
(local variable) int _
_
; 0 ..
(local variable) sparkles.ui.components.tree_widget.FlatTreeRow r
r
.
(field) int sparkles.ui.components.tree_widget.FlatTreeRow.depth
depth
)
(local variable) string indent
indent
~= " ";
const
(local variable) const(string) marker
marker
= !
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) bool property_tree_open_set_descent.PropNode.composite

the type has children

composite
? " "
:
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) bool property_tree_open_set_descent.PropNode.capped

composite, open, but the depth cap refused to descend

capped
? "⋯ "
:
(parameter) property_tree_open_set_descent.Descent d
d
.
(field) sparkles.ui.state.DisclosureState!string property_tree_open_set_descent.Descent.open
open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) string property_tree_open_set_descent.PropNode.path

the 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) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("%s%s%-12s %-10s %s",
(local variable) string indent
indent
,
(local variable) const(string) marker
marker
,
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) string property_tree_open_set_descent.PropNode.label

last segment

label
,
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) string property_tree_open_set_descent.PropNode.typeName
typeName
,
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) bool property_tree_open_set_descent.PropNode.composite

the type has children

composite
? (
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) bool property_tree_open_set_descent.PropNode.capped

composite, open, but the depth cap refused to descend

capped
? "(capped)" : "") :
(local variable) property_tree_open_set_descent.PropNode n
n
.
(field) string property_tree_open_set_descent.PropNode.value

presented scalar, empty for composites

value
);
}
void std.stdio.writefln!(char, ulong)(in char[] fmt, ulong __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" → %s rows materialised",
(local variable) sparkles.ui.components.tree_widget.FlatTreeRow[] rows
rows
.
(field) ulong sparkles.ui.components.tree_widget.FlatTreeRow[].length
length
);
} void
void D main() @safe
main
()
{ import
(package) std
std
.
(module) std.stdio
Category 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:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
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.Node
Node
(local variable) property_tree_open_set_descent.Node root
root
=
(struct) property_tree_open_set_descent.Node
Node
("root");
() @trusted {
(local variable) property_tree_open_set_descent.Node root
root
.
(field) property_tree_open_set_descent.Node* property_tree_open_set_descent.Node.parent
parent
= &
(local variable) property_tree_open_set_descent.Node root
root
; }();
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("C1 — a walk parameterised by TYPE ONLY compiles on a cyclic type.");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" (this program built; `reflect-descent.d` could not)\n");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("C2 — nothing open: one level, composites marked closed");
auto
(local variable) property_tree_open_set_descent.Descent d0
d0
=
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) @safe
build
(
(local variable) property_tree_open_set_descent.Node root
root
,
(template instance) sparkles.ui.state.DisclosureState!string
DisclosureState
!
(alias) object.string = string
string
.
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allClosed() pure nothrow @nogc @safe

Everything open / everything closed (zR / zM): a polarity reset.

allClosed
());
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safe
dump
(
(local variable) property_tree_open_set_descent.Descent d0
d0
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC2 — the reader opens `parent`, then `parent.parent`:");
auto
(local variable) sparkles.ui.state.DisclosureState!string open
open
=
(template instance) sparkles.ui.state.DisclosureState!string
DisclosureState
!
(alias) object.string = string
string
.
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allClosed() pure nothrow @nogc @safe

Everything 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 @safe

This state with k forced open / closed.

opened
("parent").
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.opened(string k) const pure nothrow @safe

This state with k forced open / closed.

opened
("parent.parent");
auto
(local variable) property_tree_open_set_descent.Descent d1
d1
=
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) @safe
build
(
(local variable) property_tree_open_set_descent.Node root
root
,
(local variable) sparkles.ui.state.DisclosureState!string open
open
);
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safe
dump
(
(local variable) property_tree_open_set_descent.Descent d1
d1
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC2 — same opened set, subject MUTATED: expansion survives");
(local variable) property_tree_open_set_descent.Node root
root
.
(field) string property_tree_open_set_descent.Node.label
label
= "renamed";
(local variable) property_tree_open_set_descent.Node root
root
.
(field) property_tree_open_set_descent.Vec2 property_tree_open_set_descent.Node.position
position
.
(field) float property_tree_open_set_descent.Vec2.x
x
= 3;
auto
(local variable) property_tree_open_set_descent.Descent d2
d2
=
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) @safe
build
(
(local variable) property_tree_open_set_descent.Node root
root
,
(local variable) sparkles.ui.state.DisclosureState!string open
open
);
void property_tree_open_set_descent.dump(ref property_tree_open_set_descent.Descent d) @safe
dump
(
(local variable) property_tree_open_set_descent.Descent d2
d2
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent 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);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC3 — allOpen(): the walk is now undriven. Depth cap = 4:");
auto
(local variable) property_tree_open_set_descent.Descent d3
d3
=
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) @safe
build
(
(local variable) property_tree_open_set_descent.Node root
root
,
(template instance) sparkles.ui.state.DisclosureState!string
DisclosureState
!
(alias) object.string = string
string
.
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.allOpen() pure nothrow @nogc @safe

Everything 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) @safe
dump
(
(local variable) property_tree_open_set_descent.Descent d3
d3
);
void std.stdio.writefln!(char, ulong)(in char[] fmt, ulong __param_1) @safe

Equivalent 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 d3
d3
.
(field) ulong property_tree_open_set_descent.Descent.visited

nodes materialised

visited
);
}