Skip to content

Commit 976794d

Browse files
ntreldlang-bot
authored andcommitted
[operatoroverloading.dd] move Array2D example down
The example should come after opIndex, opSlice and opDollar have been explained. No content changes other than adding SPEC_RUNNABLE_EXAMPLE_RUN.
1 parent eebc0b6 commit 976794d

File tree

1 file changed

+98
-94
lines changed

1 file changed

+98
-94
lines changed

spec/operatoroverloading.dd

Lines changed: 98 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -785,100 +785,6 @@ $(H2 $(LEGACY_LNAME2 ArrayOps, array-ops, Array Indexing and Slicing Operators O
785785
These may be combined to implement multidimensional arrays.
786786
)
787787

788-
$(P The code example below shows a simple implementation of a
789-
2-dimensional array with overloaded indexing and slicing operators. The
790-
explanations of the various constructs employed are given in the
791-
sections following.)
792-
793-
-------
794-
struct Array2D(E)
795-
{
796-
E[] impl;
797-
int stride;
798-
int width, height;
799-
800-
this(int width, int height, E[] initialData = [])
801-
{
802-
impl = initialData;
803-
this.stride = this.width = width;
804-
this.height = height;
805-
impl.length = width * height;
806-
}
807-
808-
// Index a single element, e.g., arr[0, 1]
809-
ref E opIndex(int i, int j) { return impl[i + stride*j]; }
810-
811-
// Array slicing, e.g., arr[1..2, 1..2], arr[2, 0..$], arr[0..$, 1].
812-
Array2D opIndex(int[2] r1, int[2] r2)
813-
{
814-
Array2D result;
815-
816-
auto startOffset = r1[0] + r2[0]*stride;
817-
auto endOffset = r1[1] + (r2[1] - 1)*stride;
818-
result.impl = this.impl[startOffset .. endOffset];
819-
820-
result.stride = this.stride;
821-
result.width = r1[1] - r1[0];
822-
result.height = r2[1] - r2[0];
823-
824-
return result;
825-
}
826-
auto opIndex(int[2] r1, int j) { return opIndex(r1, [j, j+1]); }
827-
auto opIndex(int i, int[2] r2) { return opIndex([i, i+1], r2); }
828-
829-
// Support for `x..y` notation in slicing operator for the given dimension.
830-
int[2] opSlice(size_t dim)(int start, int end)
831-
if (dim >= 0 && dim < 2)
832-
in { assert(start >= 0 && end <= this.opDollar!dim); }
833-
do
834-
{
835-
return [start, end];
836-
}
837-
838-
// Support `$` in slicing notation, e.g., arr[1..$, 0..$-1].
839-
@property int opDollar(size_t dim : 0)() { return width; }
840-
@property int opDollar(size_t dim : 1)() { return height; }
841-
}
842-
843-
unittest
844-
{
845-
auto arr = Array2D!int(4, 3, [
846-
0, 1, 2, 3,
847-
4, 5, 6, 7,
848-
8, 9, 10, 11
849-
]);
850-
851-
// Basic indexing
852-
assert(arr[0, 0] == 0);
853-
assert(arr[1, 0] == 1);
854-
assert(arr[0, 1] == 4);
855-
856-
// Use of opDollar
857-
assert(arr[$-1, 0] == 3);
858-
assert(arr[0, $-1] == 8); // Note the value of $ differs by dimension
859-
assert(arr[$-1, $-1] == 11);
860-
861-
// Slicing
862-
auto slice1 = arr[1..$, 0..$];
863-
assert(slice1[0, 0] == 1 && slice1[1, 0] == 2 && slice1[2, 0] == 3 &&
864-
slice1[0, 1] == 5 && slice1[1, 1] == 6 && slice1[2, 1] == 7 &&
865-
slice1[0, 2] == 9 && slice1[1, 2] == 10 && slice1[2, 2] == 11);
866-
867-
auto slice2 = slice1[0..2, 1..$];
868-
assert(slice2[0, 0] == 5 && slice2[1, 0] == 6 &&
869-
slice2[0, 1] == 9 && slice2[1, 1] == 10);
870-
871-
// Thin slices
872-
auto slice3 = arr[2, 0..$];
873-
assert(slice3[0, 0] == 2 &&
874-
slice3[0, 1] == 6 &&
875-
slice3[0, 2] == 10);
876-
877-
auto slice4 = arr[0..3, 2];
878-
assert(slice4[0, 0] == 8 && slice4[1, 0] == 9 && slice4[2, 0] == 10);
879-
}
880-
-------
881-
882788
$(H3 $(LEGACY_LNAME2 Array, array, Index Operator Overloading))
883789

884790
$(P Expressions of the form $(D arr[)$(ARGUMENTS)$(D ]) are translated
@@ -1097,6 +1003,104 @@ arr.opIndex(__tmp1 - sqrt(__tmp1), 0, __tmp2 - 1);
10971003
than one argument.
10981004
)
10991005

1006+
$(H3 $(LNAME2 index-slicing-example, Complete Example))
1007+
1008+
$(P The code example below shows a simple implementation of a
1009+
2-dimensional array with overloaded indexing and slicing operators. The
1010+
explanations of the various constructs employed are given in the
1011+
sections following.)
1012+
1013+
$(SPEC_RUNNABLE_EXAMPLE_RUN
1014+
-------
1015+
struct Array2D(E)
1016+
{
1017+
E[] impl;
1018+
int stride;
1019+
int width, height;
1020+
1021+
this(int width, int height, E[] initialData = [])
1022+
{
1023+
impl = initialData;
1024+
this.stride = this.width = width;
1025+
this.height = height;
1026+
impl.length = width * height;
1027+
}
1028+
1029+
// Index a single element, e.g., arr[0, 1]
1030+
ref E opIndex(int i, int j) { return impl[i + stride*j]; }
1031+
1032+
// Array slicing, e.g., arr[1..2, 1..2], arr[2, 0..$], arr[0..$, 1].
1033+
Array2D opIndex(int[2] r1, int[2] r2)
1034+
{
1035+
Array2D result;
1036+
1037+
auto startOffset = r1[0] + r2[0]*stride;
1038+
auto endOffset = r1[1] + (r2[1] - 1)*stride;
1039+
result.impl = this.impl[startOffset .. endOffset];
1040+
1041+
result.stride = this.stride;
1042+
result.width = r1[1] - r1[0];
1043+
result.height = r2[1] - r2[0];
1044+
1045+
return result;
1046+
}
1047+
auto opIndex(int[2] r1, int j) { return opIndex(r1, [j, j+1]); }
1048+
auto opIndex(int i, int[2] r2) { return opIndex([i, i+1], r2); }
1049+
1050+
// Support for `x..y` notation in slicing operator for the given dimension.
1051+
int[2] opSlice(size_t dim)(int start, int end)
1052+
if (dim >= 0 && dim < 2)
1053+
in { assert(start >= 0 && end <= this.opDollar!dim); }
1054+
do
1055+
{
1056+
return [start, end];
1057+
}
1058+
1059+
// Support `$` in slicing notation, e.g., arr[1..$, 0..$-1].
1060+
@property int opDollar(size_t dim : 0)() { return width; }
1061+
@property int opDollar(size_t dim : 1)() { return height; }
1062+
}
1063+
1064+
void main()
1065+
{
1066+
auto arr = Array2D!int(4, 3, [
1067+
0, 1, 2, 3,
1068+
4, 5, 6, 7,
1069+
8, 9, 10, 11
1070+
]);
1071+
1072+
// Basic indexing
1073+
assert(arr[0, 0] == 0);
1074+
assert(arr[1, 0] == 1);
1075+
assert(arr[0, 1] == 4);
1076+
1077+
// Use of opDollar
1078+
assert(arr[$-1, 0] == 3);
1079+
assert(arr[0, $-1] == 8); // Note the value of $ differs by dimension
1080+
assert(arr[$-1, $-1] == 11);
1081+
1082+
// Slicing
1083+
auto slice1 = arr[1..$, 0..$];
1084+
assert(slice1[0, 0] == 1 && slice1[1, 0] == 2 && slice1[2, 0] == 3 &&
1085+
slice1[0, 1] == 5 && slice1[1, 1] == 6 && slice1[2, 1] == 7 &&
1086+
slice1[0, 2] == 9 && slice1[1, 2] == 10 && slice1[2, 2] == 11);
1087+
1088+
auto slice2 = slice1[0..2, 1..$];
1089+
assert(slice2[0, 0] == 5 && slice2[1, 0] == 6 &&
1090+
slice2[0, 1] == 9 && slice2[1, 1] == 10);
1091+
1092+
// Thin slices
1093+
auto slice3 = arr[2, 0..$];
1094+
assert(slice3[0, 0] == 2 &&
1095+
slice3[0, 1] == 6 &&
1096+
slice3[0, 2] == 10);
1097+
1098+
auto slice4 = arr[0..3, 2];
1099+
assert(slice4[0, 0] == 8 && slice4[1, 0] == 9 && slice4[2, 0] == 10);
1100+
}
1101+
-------
1102+
)
1103+
11001104

11011105
$(H2 $(LEGACY_LNAME2 Dispatch, dispatch, Forwarding))
11021106

0 commit comments

Comments
 (0)