@@ -760,8 +760,8 @@ $(CONSOLE
760
760
$(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Structs and Classes with Ranges))
761
761
762
762
$(P If the aggregate expression is a struct or class object, but the
763
- $(D opApply) for $(D foreach), or $(D opApplyReverse) $(D foreach_reverse) do not exist,
764
- then iteration over struct and class objects can be done with range primitives.
763
+ $(D opApply) for $(D foreach), or $(D opApplyReverse) for $(D foreach_reverse) do not exist,
764
+ then iteration can be done with $(LINK2 $(ROOT_DIR)phobos/std_range.html, range) primitives.
765
765
For $(D foreach), this means the following properties and methods must
766
766
be defined:
767
767
)
@@ -826,42 +826,89 @@ $(H3 $(LEGACY_LNAME2 foreach_with_ranges, foreach-with-ranges, Foreach over Stru
826
826
}
827
827
---
828
828
829
+ $(P Example with a linked list:)
830
+
831
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
832
+ ---
833
+ struct Node
834
+ {
835
+ int i;
836
+ Node* next;
837
+ }
838
+
839
+ // range
840
+ struct List
841
+ {
842
+ Node* node;
843
+
844
+ bool empty() { return node == null; }
845
+
846
+ ref int front() { return node.i; }
847
+
848
+ void popFront() { node = node.next; }
849
+ }
850
+
851
+ void main()
852
+ {
853
+ import std.stdio;
854
+ auto l = new Node(1, new Node(2, null));
855
+ auto r = List(l);
856
+
857
+ foreach (e; r)
858
+ {
859
+ writeln(e);
860
+ }
861
+ }
862
+ ---
863
+ )
864
+
865
+ $(H4 $(LNAME2 front-seq, Multiple Element Values))
866
+
829
867
$(P Multiple loop variables are allowed if the `front` property returns a type that
830
868
expands to an $(DDSUBLINK spec/template, variadic-templates, expression sequence)
831
869
whose size matches the number of variables. Each variable is assigned
832
- to the corresponding value in the tuple .
870
+ to the corresponding value in the sequence .
833
871
)
834
872
873
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
835
874
---
836
- // Common tuple implementation that can decay into its members
837
- import std.typecons : Tuple;
875
+ struct Tuple(Types...) // takes a TypeSeq
876
+ {
877
+ Types items; // ValueSeq
878
+ alias items this; // decay to a value sequence
879
+ }
838
880
839
- // Range whose elements are tuples
881
+ // Infinite range whose element is a fixed tuple
840
882
struct TupleRange
841
883
{
842
- Tuple!(char, bool, int) front()
843
- {
844
- return typeof(return)('a', true, 2);
845
- }
884
+ enum front = Tuple!(char, bool, int)('a', true, 2);
846
885
847
- bool empty() { return false; }
886
+ enum bool empty = false;
848
887
849
888
void popFront() {}
850
889
}
851
890
852
891
void main()
853
892
{
893
+ // Tuple destructuring
854
894
foreach (a, b, c; TupleRange())
855
895
{
856
896
assert(a == 'a');
857
897
assert(b == true);
858
898
assert(c == 2);
899
+ break;
900
+ }
901
+ // Tuple variable
902
+ foreach (tup; TupleRange())
903
+ {
904
+ assert(tup[0] == 'a');
905
+ assert(tup == TupleRange.front);
906
+ break;
859
907
}
860
-
861
- // Expected 3 arguments, not 1
862
- // foreach (a; TupleRange()) { ... }
863
908
}
864
909
---
910
+ )
911
+ $(P See also: $(REF Tuple, std,typecons).)
865
912
866
913
$(H3 $(LNAME2 foreach_over_delegates, Foreach over Delegates))
867
914
0 commit comments