@@ -89,39 +89,79 @@ Emplaces T.init.
89
89
In contrast to `emplaceRef(chunk)`, there are no checks for disabled default
90
90
constructors etc.
91
91
+/
92
- nothrow pure @trusted
93
- void emplaceInitializer (T)( scope ref T chunk )
92
+ void emplaceInitializer (T)( scope ref T chunk) nothrow pure @trusted
93
+ if ( ! is (T == const ) && ! is (T == immutable ) && ! is (T == inout ) )
94
94
{
95
95
import core.internal.traits : hasElaborateAssign;
96
96
97
97
static if (! hasElaborateAssign! T && __traits(compiles, chunk = T.init))
98
98
{
99
99
chunk = T.init;
100
100
}
101
+ else static if (__traits(isZeroInit, T))
102
+ {
103
+ static if (is (T U == shared U))
104
+ alias Unshared = U;
105
+ else
106
+ alias Unshared = T;
107
+
108
+ import core.stdc.string : memset;
109
+ memset(cast (Unshared* ) &chunk, 0 , T.sizeof);
110
+ }
101
111
else
102
112
{
103
- static if (__traits(isZeroInit, T))
104
- {
105
- static if (is (T U == shared U))
106
- alias Unshared = U;
107
- else
108
- alias Unshared = T;
113
+ // emplace T.init (an rvalue) without extra variable (and according destruction)
114
+ alias RawBytes = void [T.sizeof];
109
115
110
- import core.stdc.string : memset;
111
- memset(cast (Unshared* ) &chunk, 0 , T.sizeof);
116
+ static union U
117
+ {
118
+ T dummy = T.init; // U.init corresponds to T.init
119
+ RawBytes data;
112
120
}
113
- else
121
+
122
+ * cast (RawBytes* ) &chunk = U.init.data;
123
+ }
124
+ }
125
+
126
+ @safe unittest
127
+ {
128
+ static void testInitializer (T)()
129
+ {
130
+ // mutable T
114
131
{
115
- // emplace T.init (an rvalue) without extra variable (and according destruction)
116
- alias RawBytes = void [T.sizeof];
132
+ T dst = void ;
133
+ emplaceInitializer(dst);
134
+ assert (dst is T.init);
135
+ }
117
136
118
- static union U
119
- {
120
- T dummy = T.init; // U.init corresponds to T.init
121
- RawBytes data;
122
- }
137
+ // shared T
138
+ {
139
+ shared T dst = void ;
140
+ emplaceInitializer(dst);
141
+ assert (dst is shared (T).init);
142
+ }
123
143
124
- * cast (RawBytes* ) &chunk = U.init.data;
144
+ // const T
145
+ {
146
+ const T dst = void ;
147
+ static assert (! __traits(compiles, emplaceInitializer(dst)));
125
148
}
126
149
}
150
+
151
+ static struct ElaborateAndZero
152
+ {
153
+ int a;
154
+ this (this ) {}
155
+ }
156
+
157
+ static struct ElaborateAndNonZero
158
+ {
159
+ int a = 42 ;
160
+ this (this ) {}
161
+ }
162
+
163
+ testInitializer! int ();
164
+ testInitializer! double ();
165
+ testInitializer! ElaborateAndZero();
166
+ testInitializer! ElaborateAndNonZero();
127
167
}
0 commit comments