@@ -369,6 +369,7 @@ $(H2 $(LNAME2 eqcmp, Overloading the Comparison Operators))
369
369
$(D opCmp).)
370
370
371
371
$(P The equality and inequality operators are treated separately
372
+ from comparison operators
372
373
because while practically all user-defined types can be compared for
373
374
equality, only a subset of types have a meaningful ordering. For
374
375
example, while it makes sense to determine if two RGB color vectors are
@@ -514,6 +515,28 @@ struct S
514
515
version of $(D opEquals). Otherwise, inequalities like $(D a <= b)
515
516
will behave inconsistently with equalities like $(D a == b).)
516
517
518
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
519
+ ---
520
+ struct S
521
+ {
522
+ int i, j;
523
+ int opCmp(ref const S s) const { return (i > s.i) - (i < s.i); } // ignore j
524
+ }
525
+
526
+ S a = {2, 3};
527
+ S b = {2, 1};
528
+ S c = {3, 0};
529
+ assert(a < c);
530
+ assert(a <= b);
531
+ assert(!(a < b)); // opCmp ignores j
532
+ assert(a != b); // generated opEquals tests both i and j members
533
+ ---
534
+ )
535
+
536
+ $(BEST_PRACTICE Using `(i > s.i) - (i < s.i)` instead of `i - s.i` to
537
+ compare integers avoids overflow.)
538
+
539
+
517
540
$(H2 $(LEGACY_LNAME2 FunctionCall, function-call, Function Call Operator Overloading $(D f())))
518
541
519
542
$(P The function call operator, $(D ()), can be overloaded by
@@ -548,20 +571,24 @@ $(H2 $(LEGACY_LNAME2 FunctionCall, function-call, Function Call Operator Overloa
548
571
so that it takes priority over $(D opCall) in $(D Type(...)) syntax.
549
572
)
550
573
574
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
551
575
-------
552
576
struct Multiplier
553
577
{
554
578
int factor;
555
579
this(int num) { factor = num; }
556
580
int opCall(int value) { return value * factor; }
557
581
}
558
- void test()
582
+
583
+ void main()
559
584
{
560
585
Multiplier m = Multiplier(10); // invoke constructor
586
+ assert(m.factor == 10);
561
587
int result = m(5); // invoke opCall
562
588
assert(result == 50);
563
589
}
564
590
-------
591
+ )
565
592
566
593
$(H3 $(LNAME2 static-opcall, Static opCall))
567
594
@@ -729,6 +756,21 @@ a $(METACODE op)= b
729
756
a.opOpAssign!($(METACODE "op"))(b)
730
757
---
731
758
759
+ Example:
760
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
761
+ ---
762
+ struct S
763
+ {
764
+ int i;
765
+ void opOpAssign(string op: "+")(int rhs) { i += rhs; }
766
+ }
767
+
768
+ S s = {2};
769
+ s += 3;
770
+ assert(s.i == 5);
771
+ ---
772
+ )
773
+
732
774
$(H3 $(LNAME2 index_op_assignment, Index Op Assignment Operator Overloading))
733
775
734
776
$(P If the left hand side of an $(I op)= is an index expression on
@@ -823,6 +865,7 @@ $(H3 $(LEGACY_LNAME2 Slice, slice, Slice Operator Overloading))
823
865
$(P To overload $(D a[]), simply define $(D opIndex) with no parameters:
824
866
)
825
867
868
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
826
869
-----
827
870
struct S
828
871
{
@@ -832,25 +875,49 @@ struct S
832
875
return impl[];
833
876
}
834
877
}
835
- void test()
878
+
879
+ void main()
836
880
{
837
881
auto s = S([1,2,3]);
838
- auto t = s[]; // calls s.opIndex()
882
+ int[] t = s[]; // calls s.opIndex()
839
883
assert(t == [1,2,3]);
840
884
}
841
885
-----
886
+ )
842
887
843
- $(P To overload array indexing of the form $(D a[)$(SLICE)$(D ,) ... $(D ]),
888
+ $(P To overload array slicing of the form $(D a[)$(SLICE)$(D ]),
844
889
two steps are needed. First, the expressions of the form $(SLICE) are
845
- translated via $(D opSlice) into user-defined objects that encapsulate
846
- the endpoints $(I i) and $(I j). Then these user-defined objects are
847
- passed to $(D opIndex) to perform the actual slicing. This design was
890
+ translated via $(D opSlice!0) into objects that encapsulate
891
+ the endpoints $(I i) and $(I j). Then these objects are
892
+ passed to $(D opIndex) to perform the actual slicing.)
893
+
894
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
895
+ ---
896
+ struct S
897
+ {
898
+ int[] impl;
899
+
900
+ int[] opSlice(size_t dim: 0)(size_t i, size_t j)
901
+ {
902
+ return impl[i..j];
903
+ }
904
+ int[] opIndex()(int[] slice) { return slice; }
905
+ }
906
+
907
+ void main()
908
+ {
909
+ auto s = S([1, 2, 3]);
910
+ int[] t = s[0..2]; // calls s.opIndex(s.opSlice(0, 2))
911
+ assert(t == [1, 2]);
912
+ }
913
+ ---
914
+ )
915
+
916
+ $(P This design was
848
917
chosen in order to support mixed indexing and slicing in
849
918
multidimensional arrays; for example, in translating expressions like
850
919
$(D arr[1, 2..3, 4]).
851
- )
852
-
853
- $(P More precisely, an expression of the form $(D arr[)$(ARGUMENTS)$(D ])
920
+ More precisely, an expression of the form $(D arr[)$(ARGUMENTS)$(D ])
854
921
is translated into $(D arr.opIndex$(LPAREN))$(ARGUMENTS2)$(D $(RPAREN)).
855
922
Each argument $(I b)$(SUBSCRIPT i) can be either a single expression,
856
923
in which case it is passed directly as the corresponding argument $(I
@@ -911,7 +978,7 @@ __tmp.opIndexAssign(c, 1, __tmp.opSlice!1(2,3), __tmp.opDollar!2 - 1);
911
978
once.
912
979
)
913
980
914
- $(P For backward compatibility, $(D a[]) and $(D a[)$(SLICE)$(D ]) can
981
+ $(NOTE For backward compatibility, $(D a[]) and $(D a[)$(SLICE)$(D ]) can
915
982
also be overloaded by implementing $(D opSlice()) with no arguments and
916
983
$(D opSlice$(LPAREN))$(SLICE2)$(D $(RPAREN)) with two arguments,
917
984
respectively. This only applies for one-dimensional slicing, and dates
0 commit comments