Skip to content

Commit c686add

Browse files
authored
Merge pull request #3563 from ntrel/struct-copy
[spec/struct] Tweak Copy Constructor docs Signed-off-by: Dennis <[email protected]> Merged-on-behalf-of: Dennis <[email protected]>
2 parents 5ddd708 + 09e06b0 commit c686add

File tree

1 file changed

+59
-12
lines changed

1 file changed

+59
-12
lines changed

spec/struct.dd

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,10 +1055,11 @@ $(H3 $(LNAME2 field-init, Field initialization inside a constructor))
10551055
---
10561056
)
10571057

1058-
$(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy Constructors))
1058+
$(H2 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy Constructors))
10591059

10601060
$(P Copy constructors are used to initialize a `struct` instance from
1061-
another `struct` of the same type.)
1061+
another instance of the same type. A `struct` that defines a copy constructor
1062+
is not $(RELATIVE_LINK2 POD, POD).)
10621063

10631064
$(P A constructor declaration is a copy constructor declaration if it meets
10641065
the following requirements:)
@@ -1094,20 +1095,31 @@ $(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy
10941095

10951096
$(OL
10961097
$(LI When a variable is explicitly initialized:)
1098+
1099+
$(SPEC_RUNNABLE_EXAMPLE_RUN
10971100
---
10981101
struct A
10991102
{
1100-
this(ref return scope A rhs) {}
1103+
int[] arr;
1104+
this(ref return scope A rhs) { arr = rhs.arr.dup; }
11011105
}
11021106

11031107
void main()
11041108
{
11051109
A a;
1110+
a.arr = [1, 2];
1111+
11061112
A b = a; // copy constructor gets called
1113+
b.arr[] += 1;
1114+
assert(a.arr == [1, 2]); // a is unchanged
1115+
assert(b.arr == [2, 3]);
11071116
}
11081117
---
1118+
)
11091119

11101120
$(LI When a parameter is passed by value to a function:)
1121+
1122+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11111123
---
11121124
struct A
11131125
{
@@ -1122,9 +1134,12 @@ $(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy
11221134
fun(a); // copy constructor gets called
11231135
}
11241136
---
1137+
)
11251138

1126-
$(LI When a parameter is returned by value from a function and Named Returned Value Optiomization (NRVO)
1139+
$(LI When a parameter is returned by value from a function and Named Returned Value Optimization (NRVO)
11271140
cannot be performed:)
1141+
1142+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11281143
---
11291144
struct A
11301145
{
@@ -1150,11 +1165,15 @@ $(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy
11501165
}
11511166
---
11521167
)
1168+
)
1169+
1170+
$(H3 $(LNAME2 disable-copy, Disabled Copying))
11531171

1154-
$(LNAME2 disable-copy)
11551172
$(P When a copy constructor is defined for a `struct` (or marked `@disable`), the compiler no
11561173
longer implicitly generates default copy/blitting constructors for that `struct`:
11571174
)
1175+
1176+
$(SPEC_RUNNABLE_EXAMPLE_FAIL
11581177
---
11591178
struct A
11601179
{
@@ -1170,7 +1189,9 @@ $(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy
11701189
fun(a); // error: copy constructor cannot be called with types (immutable) immutable
11711190
}
11721191
---
1192+
)
11731193

1194+
$(SPEC_RUNNABLE_EXAMPLE_FAIL
11741195
---
11751196
struct A
11761197
{
@@ -1183,19 +1204,40 @@ $(H3 $(LEGACY_LNAME2 StructCopyConstructor, struct-copy-constructor, Struct Copy
11831204
A b = a; // error: copy constructor is disabled
11841205
}
11851206
---
1207+
)
11861208

1187-
$(P If a `union S` has fields that define a copy constructor, whenever an object of type `S`
1209+
$(P If a `union U` has fields that define a copy constructor, whenever an object of type `U`
11881210
is initialized by copy, an error will be issued. The same rule applies to overlapped fields
11891211
(anonymous unions).)
11901212

1191-
$(P A `struct` that defines a copy constructor is not $(RELATIVE_LINK2 POD, POD).)
1213+
$(SPEC_RUNNABLE_EXAMPLE_FAIL
1214+
---
1215+
struct S
1216+
{
1217+
this(ref S);
1218+
}
1219+
1220+
union U
1221+
{
1222+
S s;
1223+
}
1224+
1225+
void main()
1226+
{
1227+
U a;
1228+
U b = a; // error, could not generate copy constructor for U
1229+
}
1230+
---
1231+
)
11921232

1193-
$(H4 $(LNAME2 copy-constructor-attributes, Copy Constructor Attributes))
1233+
$(H3 $(LNAME2 copy-constructor-attributes, Copy Constructor Attributes))
11941234

11951235
$(P The copy constructor can be overloaded with different qualifiers applied
11961236
to the parameter (copying from a qualified source) or to the copy constructor
11971237
itself (copying to a qualified destination):
11981238
)
1239+
1240+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
11991241
---
12001242
struct A
12011243
{
@@ -1216,10 +1258,13 @@ $(H4 $(LNAME2 copy-constructor-attributes, Copy Constructor Attributes))
12161258
immutable A a5 = ia; // calls 4
12171259
}
12181260
---
1261+
)
12191262

12201263
$(P The `inout` qualifier may be applied to the copy constructor parameter in
12211264
order to specify that mutable, `const`, or `immutable` types are treated the same:
12221265
)
1266+
1267+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
12231268
---
12241269
struct A
12251270
{
@@ -1238,8 +1283,9 @@ $(H4 $(LNAME2 copy-constructor-attributes, Copy Constructor Attributes))
12381283
immutable(A) c = r3;
12391284
}
12401285
---
1286+
)
12411287

1242-
$(H4 $(LNAME2 implicit-copy-constructors, Implicit Copy Constructors))
1288+
$(H3 $(LNAME2 implicit-copy-constructors, Implicit Copy Constructors))
12431289

12441290
$(P A copy constructor is generated implicitly by the compiler for a `struct S`
12451291
if all of the following conditions are met:)
@@ -1251,6 +1297,7 @@ $(H4 $(LNAME2 implicit-copy-constructors, Implicit Copy Constructors))
12511297
)
12521298

12531299
$(P If the restrictions above are met, the following copy constructor is generated:)
1300+
12541301
---
12551302
this(ref return scope inout(S) src) inout
12561303
{
@@ -1270,7 +1317,7 @@ $(GNAME Postblit):
12701317
$(D this $(LPAREN) this $(RPAREN)) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(GLINK2 function, FunctionBody)
12711318
)
12721319

1273-
$(P WARNING: The postblit is considered legacy and is not recommended for new code.
1320+
$(P $(RED Warning): The postblit is considered legacy and is not recommended for new code.
12741321
Code should use $(RELATIVE_LINK2 struct-copy-constructor, copy constructors)
12751322
defined in the previous section. For backward compatibility reasons, a `struct` that
12761323
explicitly defines both a copy constructor and a postblit will only use the postblit
@@ -1280,7 +1327,7 @@ $(GNAME Postblit):
12801327
will have priority over the copy constructor.)
12811328

12821329
$(P $(I Copy construction) is defined as initializing
1283-
a struct instance from another struct of the same type.
1330+
a struct instance from another instance of the same type.
12841331
Copy construction is divided into two parts:)
12851332

12861333
$(OL
@@ -1298,7 +1345,7 @@ $(GNAME Postblit):
12981345
etc. For example:
12991346
)
13001347

1301-
$(SPEC_RUNNABLE_EXAMPLE_RUN
1348+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
13021349
---
13031350
struct S
13041351
{

0 commit comments

Comments
 (0)