Skip to content

Commit 2e382b2

Browse files
committed
[spec/statement.dd] Improve opApply docs
Improve wording of delegate parameter usage. Add *Template `opApply`* subheading and move paragraph about catching exceptions above it. Make template example runnable.
1 parent aeaa8c6 commit 2e382b2

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

spec/statement.dd

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
675675
special $(LEGACY_LNAME2 opApply, op-apply, $(D opApply)) member function, and the
676676
`foreach_reverse` behavior is defined by the special
677677
$(LEGACY_LNAME2 opApplyReverse, op-apply-reverse, $(D opApplyReverse)) member function.
678-
These functions have the type:
678+
These functions have the signatures:
679679
)
680680

681681
--------------
@@ -684,21 +684,27 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
684684
int opApplyReverse(scope int delegate(ref Type [, ...]) dg);
685685
--------------
686686

687-
$(P where $(I Type) matches the $(I Type) used in the $(I ForeachType)
688-
declaration of $(I Identifier). Multiple $(I ForeachType)s
689-
correspond with multiple $(I Type)s in the delegate type
690-
passed to $(D opApply) or $(D opApplyReverse).
691-
There can be multiple $(D opApply) and $(D opApplyReverse) functions,
687+
$(P where $(I Type) determines the type of the first $(GLINK ForeachType)
688+
declared. Multiple $(I ForeachType)s are supported.
689+
Each one must match a parameter of the delegate *dg*,
690+
otherwise the *ForeachStatement* will cause an error.)
691+
692+
$(P There can be multiple $(D opApply) and $(D opApplyReverse) functions -
692693
one is selected
693-
by matching the type of $(I dg) to the $(I ForeachType)s
694-
of the $(I ForeachStatement).
695-
The body of the apply
696-
function iterates over the elements it aggregates, passing them
697-
each to the $(I dg) function. If the $(I dg) returns 0, then
698-
apply goes on to the next element.
699-
If the $(I dg) returns a nonzero value, apply must cease
700-
iterating and return that value. Otherwise, after done iterating
701-
across all the elements, apply will return 0.
694+
by matching each parameter type of *dg* to the type of each $(I ForeachType)
695+
declared in the $(I ForeachStatement).)
696+
697+
$(P The body of the apply
698+
function iterates over the elements it aggregates, passing each one
699+
in successive calls to the $(I dg) delegate. The delegate return value
700+
determines whether to interrupt iteration:)
701+
702+
$(UL
703+
$(LI If the result is nonzero, apply must cease
704+
iterating and return that value.)
705+
$(LI If the result is 0, then iteration should continue.
706+
If there are no more elements to iterate,
707+
apply must return 0.)
702708
)
703709

704710
$(P For example, consider a class that is a container for two elements:)
@@ -726,10 +732,9 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
726732
void main()
727733
{
728734
import std.stdio;
729-
Foo a = new Foo();
730735

731-
a.array[0] = 73;
732-
a.array[1] = 82;
736+
Foo a = new Foo();
737+
a.array = [73, 82];
733738

734739
foreach (uint u; a)
735740
{
@@ -745,34 +750,46 @@ $(CONSOLE
745750
73
746751
82
747752
)
748-
$(P The `scope` storage class on the $(I dg) parameter means that the parameter's value does
753+
$(P The `scope` storage class on the $(I dg) parameter means that the delegate does
749754
not escape the scope of the $(I opApply) function (an example would be assigning $(I dg) to a
750755
global). If it cannot be statically guaranteed that $(I dg) does not escape, a closure may
751756
be allocated for it on the heap instead of the stack.
752757
)
753758

754759
$(BEST_PRACTICE Annotate delegate parameters to `opApply` functions with `scope` when possible.)
755760

756-
$(P $(LEGACY_LNAME2 opApply, op-apply, $(I opApply)) can also be a templated function,
761+
$(P It is important to make sure that, if $(D opApply) catches any exceptions, that those
762+
exceptions did not originate from the delegate passed to $(I opApply). The user would expect
763+
exceptions thrown from a `foreach` body to both terminate the loop, and propagate outside
764+
the `foreach` body.
765+
)
766+
767+
$(H4 $(LNAME2 template-op-apply, Template `opApply`))
768+
769+
$(P $(I opApply) can also be a templated function,
757770
which will infer the types of parameters based on the $(I ForeachStatement).
758771
)
759772

760773
$(P For example:)
761774

775+
$(SPEC_RUNNABLE_EXAMPLE_RUN
762776
--------------
763777
struct S
764778
{
765779
import std.traits : ParameterTypeTuple; // introspection template
780+
import std.stdio;
766781

767782
int opApply(Dg)(scope Dg dg)
768783
if (ParameterTypeTuple!Dg.length == 2) // foreach with 2 parameters
769784
{
785+
writeln(2);
770786
return 0;
771787
}
772788

773789
int opApply(Dg)(scope Dg dg)
774-
if (ParameterTypeTuple!Dg.length == 3) // foreach with takes 3 parameters
790+
if (ParameterTypeTuple!Dg.length == 3) // foreach with 3 parameters
775791
{
792+
writeln(3);
776793
return 0;
777794
}
778795
}
@@ -783,12 +800,7 @@ $(CONSOLE
783800
foreach (int a, int b, float c; S()) { } // calls second opApply function
784801
}
785802
--------------
786-
787-
$(P It is important to make sure that, if $(D opApply) catches any exceptions, that those
788-
exceptions did not originate from the delegate passed to $(I opApply). The user would expect
789-
exceptions thrown from a `foreach` body to both terminate the loop, and propagate outside
790-
the `foreach` body.
791-
)
803+
)
792804

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

@@ -946,7 +958,8 @@ $(H4 $(LNAME2 front-seq, Multiple Element Values))
946958
$(H3 $(LNAME2 foreach_over_delegates, Foreach over Delegates))
947959

948960
$(P If $(I ForeachAggregate) is a delegate, the type signature of
949-
the delegate is of the same as for $(D opApply). This enables
961+
the delegate is of the same as for
962+
$(RELATIVE_LINK2 foreach_over_struct_and_classes, opApply). This enables
950963
many different named looping strategies to coexist in the same
951964
class or struct.)
952965

0 commit comments

Comments
 (0)