@@ -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:)
@@ -711,25 +717,22 @@ $(H3 $(LNAME2 foreach_over_struct_and_classes, Foreach over Structs and Classes
711
717
712
718
int opApply(scope int delegate(ref uint) dg)
713
719
{
714
- int result = 0;
715
-
716
720
foreach (e; array)
717
721
{
718
- result = dg(e);
722
+ int result = dg(e);
719
723
if (result)
720
- break ;
724
+ return result ;
721
725
}
722
- return result ;
726
+ return 0 ;
723
727
}
724
728
}
725
729
726
730
void main()
727
731
{
728
732
import std.stdio;
729
- Foo a = new Foo();
730
733
731
- a.array[0] = 73 ;
732
- a.array[1] = 82 ;
734
+ Foo a = new Foo() ;
735
+ a.array = [73, 82] ;
733
736
734
737
foreach (uint u; a)
735
738
{
@@ -745,34 +748,44 @@ $(CONSOLE
745
748
73
746
749
82
747
750
)
748
- $(P The `scope` storage class on the $(I dg) parameter means that the parameter's value does
749
- not escape the scope of the $(I opApply) function (an example would be assigning $(I dg) to a
750
- global). If it cannot be statically guaranteed that $(I dg) does not escape, a closure may
751
+ $(P The `scope` storage class on the $(I dg) parameter means that the delegate does
752
+ not escape the scope of the $(D opApply) function (an example would be assigning $(I dg) to a
753
+ global variable ). If it cannot be statically guaranteed that $(I dg) does not escape, a closure may
751
754
be allocated for it on the heap instead of the stack.
752
755
)
753
756
754
757
$(BEST_PRACTICE Annotate delegate parameters to `opApply` functions with `scope` when possible.)
755
758
756
- $(P $(LEGACY_LNAME2 opApply, op-apply, $(I opApply)) can also be a templated function,
757
- which will infer the types of parameters based on the $(I ForeachStatement).
758
- )
759
+ $(P $(B Important:) If $(D opApply) catches any exceptions, ensure that those
760
+ exceptions did not originate from the delegate passed to $(D opApply). The user would expect
761
+ exceptions thrown from a `foreach` body to both terminate the loop, and propagate outside
762
+ the `foreach` body.
763
+ )
759
764
760
- $(P For example: )
765
+ $(H4 $(LNAME2 template-op-apply, Template `opApply`) )
761
766
767
+ $(P $(D opApply) can also be a templated function,
768
+ which will infer the types of parameters based on the $(I ForeachStatement).
769
+ For example:)
770
+
771
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
762
772
--------------
763
773
struct S
764
774
{
765
775
import std.traits : ParameterTypeTuple; // introspection template
776
+ import std.stdio;
766
777
767
778
int opApply(Dg)(scope Dg dg)
768
779
if (ParameterTypeTuple!Dg.length == 2) // foreach with 2 parameters
769
780
{
781
+ writeln(2);
770
782
return 0;
771
783
}
772
784
773
785
int opApply(Dg)(scope Dg dg)
774
- if (ParameterTypeTuple!Dg.length == 3) // foreach with takes 3 parameters
786
+ if (ParameterTypeTuple!Dg.length == 3) // foreach with 3 parameters
775
787
{
788
+ writeln(3);
776
789
return 0;
777
790
}
778
791
}
@@ -783,12 +796,7 @@ $(CONSOLE
783
796
foreach (int a, int b, float c; S()) { } // calls second opApply function
784
797
}
785
798
--------------
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
- )
799
+ )
792
800
793
801
$(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Structs and Classes with Ranges))
794
802
@@ -946,7 +954,8 @@ $(H4 $(LNAME2 front-seq, Multiple Element Values))
946
954
$(H3 $(LNAME2 foreach_over_delegates, Foreach over Delegates))
947
955
948
956
$(P If $(I ForeachAggregate) is a delegate, the type signature of
949
- the delegate is of the same as for $(D opApply). This enables
957
+ the delegate is of the same as for
958
+ $(RELATIVE_LINK2 foreach_over_struct_and_classes, opApply). This enables
950
959
many different named looping strategies to coexist in the same
951
960
class or struct.)
952
961
0 commit comments