Skip to content

Commit 74629f0

Browse files
authored
[spec/statement] Improve foreach for ranges docs (#4242)
Improve wording. Explain that `front` can be `ref`, add example. Rename node variable. Also don't include OpApplyDeclaration in spec/grammar page.
1 parent b8dddee commit 74629f0

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

spec/statement.dd

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
715715
These functions must each have the signature below:
716716
)
717717

718-
$(GRAMMAR
718+
$(INFORMATIVE_GRAMMAR
719719
$(GNAME OpApplyDeclaration):
720720
`int opApply` `(` `scope` `int delegate` `(` $(I OpApplyParameters) `)` `dg` `)` `;`
721721

@@ -873,16 +873,18 @@ $(H4 $(LNAME2 template-op-apply, Template `opApply`))
873873

874874
$(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Structs and Classes with Ranges))
875875

876-
$(P If the aggregate expression is a struct or class object, but the
877-
$(D opApply) for $(D foreach), or $(D opApplyReverse) for $(D foreach_reverse) do not exist,
878-
then iteration can be done with $(LINK2 $(ROOT_DIR)phobos/std_range.html, range) primitives.
879-
For $(D foreach), this means the following properties and methods must
880-
be defined:
876+
$(P If the $(GLINK ForeachAggregate) is a struct or class object, but
877+
$(RELATIVE_LINK2 foreach_over_struct_and_classes, `opApply`) does not exist,
878+
then $(D foreach) iteration will use $(LINK2 $(ROOT_DIR)phobos/std_range.html, range)
879+
primitives. These primitives produce a series of elements.
880+
)
881+
$(P The following properties and methods must
882+
be defined for the $(I ForeachAggregate):
881883
)
882884

883885
$(TABLE2 Foreach Range Properties,
884886
$(THEAD Property, Purpose)
885-
$(TROW $(ARGS $(D .empty)), $(ARGS returns true if no more elements))
887+
$(TROW $(ARGS $(D .empty)), $(ARGS returns `true` if no more elements))
886888
$(TROW $(ARGS $(D .front)), $(ARGS return the leftmost element of the range))
887889
)
888890

@@ -892,7 +894,8 @@ $(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Stru
892894
right by one))
893895
)
894896

895-
$(P Meaning:)
897+
$(P A temporary variable is used for iteration, which is initialized from the
898+
*ForeachAggregate*. The statement:)
896899

897900
---
898901
foreach (e; range) { ... }
@@ -908,13 +911,14 @@ $(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Stru
908911
}
909912
---
910913

911-
$(P Similarly, for $(D foreach_reverse), the following properties and
912-
methods must be defined:
914+
$(P Similarly, for $(D foreach_reverse) when $(D opApplyReverse) is not defined,
915+
range primitives will be used. The following properties and methods
916+
must be defined for the $(I ForeachAggregate):
913917
)
914918

915919
$(TABLE2 Foreach$(UNDERSCORE)reverse Range Properties,
916920
$(THEAD Property, Purpose)
917-
$(TROW $(ARGS $(D .empty)), $(ARGS returns true if no more elements))
921+
$(TROW $(ARGS $(D .empty)), $(ARGS returns `true` if no more elements))
918922
$(TROW $(ARGS $(D .back)), $(ARGS return the rightmost element of the range))
919923
)
920924

@@ -924,7 +928,7 @@ $(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Stru
924928
left by one))
925929
)
926930

927-
$(P Meaning:)
931+
$(P The statement:)
928932

929933
---
930934
foreach_reverse (e; range) { ... }
@@ -940,6 +944,28 @@ $(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Stru
940944
}
941945
---
942946

947+
$(P The $(GLINK ForeachType) variable may be declared with `ref` when `front`
948+
(or `back` for `foreach_reverse`) is a
949+
$(DDSUBLINK spec/function, ref-functions, Ref Function):)
950+
951+
$(SPEC_RUNNABLE_EXAMPLE_RUN
952+
---
953+
struct R
954+
{
955+
int[] a;
956+
// range primitives:
957+
bool empty() => a.length == 0;
958+
ref front() => a[0];
959+
void popFront() { a = a[1..$]; }
960+
}
961+
962+
R r = R([1, 2, 3]);
963+
foreach (ref e; r)
964+
e *= 2;
965+
966+
assert(r.a == [2, 4, 6]);
967+
---
968+
)
943969
$(P Example with a linked list:)
944970

945971
$(SPEC_RUNNABLE_EXAMPLE_RUN
@@ -954,19 +980,16 @@ struct Node
954980
struct List
955981
{
956982
Node* node;
957-
958983
bool empty() { return node == null; }
959-
960984
ref int front() { return node.i; }
961-
962985
void popFront() { node = node.next; }
963986
}
964987

965988
void main()
966989
{
967990
import std.stdio;
968-
auto l = new Node(1, new Node(2, null));
969-
auto r = List(l);
991+
auto n = new Node(1, new Node(2, null));
992+
auto r = List(n);
970993

971994
foreach (e; r)
972995
{

0 commit comments

Comments
 (0)