Skip to content

Commit d0615a1

Browse files
authored
Improve opUnary docs (#3463)
Make example runnable. Explain opIndexUnary indexing and slicing. Add opIndexUnary example.
1 parent c111ace commit d0615a1

File tree

1 file changed

+53
-6
lines changed

1 file changed

+53
-6
lines changed

spec/operatoroverloading.dd

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ $(H2 $(LEGACY_LNAME2 Unary, unary, Unary Operator Overloading))
7070
$(P For example, in order to overload the $(D -) (negation) operator for struct S, and
7171
no other operator:)
7272

73+
$(SPEC_RUNNABLE_EXAMPLE_RUN
7374
---
7475
struct S
7576
{
@@ -81,11 +82,18 @@ struct S
8182
}
8283
}
8384

84-
int foo(S s)
85+
void main()
8586
{
86-
return -s;
87+
S s = {2};
88+
assert(-s == -2);
8789
}
8890
---
91+
)
92+
93+
$(NOTE *opUnary* above can also be declared using a template parameter specialization:)
94+
---
95+
int opUnary(string s : "-")()
96+
---
8997

9098
$(H3 $(LNAME2 postincrement_postdecrement_operators, Postincrement $(I e)$(D ++) and Postdecrement $(I e)$(D --) Operators))
9199

@@ -97,14 +105,18 @@ $(H3 $(LNAME2 postincrement_postdecrement_operators, Postincrement $(I e)$(D ++)
97105
$(THEAD $(I op), $(I rewrite))
98106
$(TROW
99107
$(ARGS $(I e)$(D --)),
100-
$(ARGS $(D $(LPAREN)auto t =) $(I e)$(D , --)$(I e)$(D , t$(RPAREN))))
108+
$(ARGS $(D $(LPAREN)auto t =) $(I e)$(D , )$(I e)`.opUnary!"--"`$(D , t$(RPAREN))))
101109
$(TROW
102110
$(ARGS $(I e)$(D ++)),
103-
$(ARGS $(D $(LPAREN)auto t =) $(I e)$(D , ++)$(I e)$(D , t$(RPAREN))))
111+
$(ARGS $(D $(LPAREN)auto t =) $(I e)$(D , )$(I e)`.opUnary!"++"`$(D , t$(RPAREN))))
104112
)
105113

106114
$(H3 $(LNAME2 index_unary_operators, Overloading Index Unary Operators))
107115

116+
$(P Indexing can be $(RELATIVE_LINK2 array, overloaded).
117+
A unary operation on an index expression can also be overloaded independently.
118+
This works for multidimensional indexing.)
119+
108120
$(TABLE2 Overloadable Index Unary Operators,
109121
$(THEAD $(I op), $(I rewrite))
110122
$(TROW
@@ -132,8 +144,28 @@ $(H3 $(LNAME2 index_unary_operators, Overloading Index Unary Operators))
132144
)
133145
)
134146

147+
$(SPEC_RUNNABLE_EXAMPLE_RUN
148+
---
149+
struct S
150+
{
151+
private int[] a;
152+
153+
void opIndexUnary(string s: "++")(size_t i) { ++a[i]; }
154+
}
155+
156+
S s = {[4]};
157+
++s[0];
158+
assert(s.a[0] == 5);
159+
---
160+
)
161+
135162
$(H3 $(LNAME2 slice_unary_operators, Overloading Slice Unary Operators))
136163

164+
$(P Slicing can be $(RELATIVE_LINK2 slice, overloaded).
165+
A unary operation on a slice can also be overloaded independently.
166+
`opIndexUnary` is defined either with no function arguments for a full slice,
167+
or with two arguments for the start and end indices of the slice.)
168+
137169
$(TABLE2 Overloadable Slice Unary Operators,
138170
$(THEAD $(I op), $(I rewrite))
139171
$(TROW
@@ -197,7 +229,22 @@ $(H3 $(LNAME2 slice_unary_operators, Overloading Slice Unary Operators))
197229
)
198230
)
199231

200-
$(P For backward compatibility, if the above rewrites fail to compile and
232+
$(SPEC_RUNNABLE_EXAMPLE_RUN
233+
---
234+
struct S
235+
{
236+
private int[] a;
237+
238+
void opIndexUnary(string s: "--")() { --a[]; }
239+
}
240+
241+
S s = {[1, 2]};
242+
--s[];
243+
assert(s.a == [0, 1]);
244+
---
245+
)
246+
247+
$(NOTE For backward compatibility, if the above rewrites fail to compile and
201248
$(D opSliceUnary) is defined, then the rewrites
202249
$(D a.opSliceUnary!(op)(i, j)) and
203250
$(D a.opSliceUnary!(op)) are tried instead, respectively.)
@@ -216,7 +263,7 @@ $(H2 $(LEGACY_LNAME2 Cast, cast, Cast Operator Overloading))
216263

217264
$(P Note that `opCast` is only ever used with an explicit `cast`
218265
expression, except in the case of boolean operations (see next
219-
section))
266+
section).)
220267

221268
$(H3 $(LNAME2 boolean_operators, Boolean Operations))
222269

0 commit comments

Comments
 (0)