@@ -675,7 +675,7 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
675
675
special $(LEGACY_LNAME2 opApply, op-apply, $(D opApply)) member function, and the
676
676
`foreach_reverse` behavior is defined by the special
677
677
$(LEGACY_LNAME2 opApplyReverse, op-apply-reverse, $(D opApplyReverse)) member function.
678
- These functions have the type :
678
+ These functions have the signatures :
679
679
)
680
680
681
681
--------------
@@ -684,21 +684,27 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
684
684
int opApplyReverse(scope int delegate(ref Type [, ...]) dg);
685
685
--------------
686
686
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 -
692
693
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.)
702
708
)
703
709
704
710
$(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
726
732
void main()
727
733
{
728
734
import std.stdio;
729
- Foo a = new Foo();
730
735
731
- a.array[0] = 73 ;
732
- a.array[1] = 82 ;
736
+ Foo a = new Foo() ;
737
+ a.array = [73, 82] ;
733
738
734
739
foreach (uint u; a)
735
740
{
@@ -745,34 +750,46 @@ $(CONSOLE
745
750
73
746
751
82
747
752
)
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
749
754
not escape the scope of the $(I opApply) function (an example would be assigning $(I dg) to a
750
755
global). If it cannot be statically guaranteed that $(I dg) does not escape, a closure may
751
756
be allocated for it on the heap instead of the stack.
752
757
)
753
758
754
759
$(BEST_PRACTICE Annotate delegate parameters to `opApply` functions with `scope` when possible.)
755
760
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,
757
770
which will infer the types of parameters based on the $(I ForeachStatement).
758
771
)
759
772
760
773
$(P For example:)
761
774
775
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
762
776
--------------
763
777
struct S
764
778
{
765
779
import std.traits : ParameterTypeTuple; // introspection template
780
+ import std.stdio;
766
781
767
782
int opApply(Dg)(scope Dg dg)
768
783
if (ParameterTypeTuple!Dg.length == 2) // foreach with 2 parameters
769
784
{
785
+ writeln(2);
770
786
return 0;
771
787
}
772
788
773
789
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
775
791
{
792
+ writeln(3);
776
793
return 0;
777
794
}
778
795
}
@@ -783,12 +800,7 @@ $(CONSOLE
783
800
foreach (int a, int b, float c; S()) { } // calls second opApply function
784
801
}
785
802
--------------
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
+ )
792
804
793
805
$(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Structs and Classes with Ranges))
794
806
@@ -946,7 +958,8 @@ $(H4 $(LNAME2 front-seq, Multiple Element Values))
946
958
$(H3 $(LNAME2 foreach_over_delegates, Foreach over Delegates))
947
959
948
960
$(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
950
963
many different named looping strategies to coexist in the same
951
964
class or struct.)
952
965
0 commit comments