@@ -28,24 +28,29 @@ import mir.math.common: optmath;
28
28
@optmath:
29
29
30
30
/+ +
31
- Fuses ndrange `r` into GC-allocated ndslice. Can be used to join rows or columns into a matrix.
31
+ Fuses ndrange `r` into GC-allocated (`fuse`) or RC-allocated (`rcfuse`) ndslice. Can be used to join rows or columns into a matrix.
32
32
33
33
Params:
34
34
Dimensions = (optional) indexes of dimensions to be brought to the first position
35
35
Returns:
36
36
ndslice
37
37
+/
38
- template fuse (Dimensions... )
38
+ // /
39
+ alias fuse (Dimensions... ) = fuseImpl! (false , Dimensions);
40
+ // /
41
+ alias rcfuse (Dimensions... ) = fuseImpl! (true , Dimensions);
42
+ // / ditto
43
+ template fuseImpl (bool RC , Dimensions... )
39
44
{
40
45
import mir.ndslice.internal: isSize_t, toSize_t;
41
46
static if (! allSatisfy! (isSize_t, Dimensions))
42
- alias fuse = .fuse ! ( staticMap! (toSize_t, Dimensions));
47
+ alias fuseImpl = .fuseImpl ! ( RC , staticMap! (toSize_t, Dimensions));
43
48
else
44
49
/+ +
45
50
Params:
46
51
r = parallelotope (ndrange) with length/shape and input range primitives.
47
52
+/
48
- @optmath Slice ! (FuseElementType ! NDRange * , fuseDimensionCount ! NDRange) fuse (NDRange)(NDRange r)
53
+ @optmath auto fuseImpl (NDRange)(NDRange r)
49
54
if (hasShape! NDRange)
50
55
{
51
56
import mir.conv: emplaceRef;
@@ -54,8 +59,17 @@ template fuse(Dimensions...)
54
59
auto shape = fuseShape(r);
55
60
alias T = FuseElementType! NDRange;
56
61
alias UT = Unqual! T;
57
- alias R = typeof (return );
58
- Slice! (UT * , fuseDimensionCount! NDRange) ret;
62
+ static if (RC )
63
+ {
64
+ import mir.rc.array: RCI ;
65
+ alias R = Slice! (RCI ! T, fuseDimensionCount! NDRange);
66
+ Slice! (RCI ! UT , fuseDimensionCount! NDRange) ret;
67
+ }
68
+ else
69
+ {
70
+ alias R = Slice! (T* , fuseDimensionCount! NDRange);
71
+ Slice! (UT * , fuseDimensionCount! NDRange) ret;
72
+ }
59
73
static if (Dimensions.length)
60
74
{
61
75
import mir.ndslice.topology: iota;
@@ -72,40 +86,66 @@ template fuse(Dimensions...)
72
86
return ar;
73
87
}(perm)
74
88
);
75
- if (__ctfe )
89
+ static if (RC )
76
90
{
77
- ret = shapep.slice ! UT ;
78
- ret.transposed! InverseDimensions.each! " a = b " (r);
91
+ ret = shapep.uninitRcslice ! UT ;
92
+ ret.lightScope. transposed! InverseDimensions.each! (emplaceRef ! T) (r);
79
93
}
80
94
else
81
95
{
82
- ret = shapep.uninitSlice! UT ;
83
- ret.transposed! InverseDimensions.each! (emplaceRef! T)(r);
96
+ if (__ctfe)
97
+ {
98
+ ret = shapep.slice! UT ;
99
+ ret.transposed! InverseDimensions.each! " a = b" (r);
100
+ }
101
+ else
102
+ {
103
+ ret = shapep.uninitSlice! UT ;
104
+ ret.transposed! InverseDimensions.each! (emplaceRef! T)(r);
105
+ }
106
+
84
107
}
85
108
}
86
109
else
87
110
{
88
- if (__ctfe )
111
+ static if (RC )
89
112
{
90
- ret = shape.slice ! UT ;
91
- ret.each! " a = b " (r);
113
+ ret = shape.uninitRCslice ! UT ;
114
+ ret.lightScope. each! (emplaceRef ! T) (r);
92
115
}
93
116
else
94
117
{
95
- ret = shape.uninitSlice! UT ;
96
- ret.each! (emplaceRef! T)(r);
118
+ if (__ctfe)
119
+ {
120
+ ret = shape.slice! UT ;
121
+ ret.each! " a = b" (r);
122
+ }
123
+ else
124
+ {
125
+ ret = shape.uninitSlice! UT ;
126
+ ret.each! (emplaceRef! T)(r);
127
+ }
97
128
}
98
129
}
99
- return R (ret._structure, (() @trusted => cast (T* )ret._iterator)());
130
+ static if (RC )
131
+ {
132
+ import core.lifetime : move;
133
+ return move (* (() @trusted => cast (R* )&ret)());
134
+ }
135
+ else
136
+ {
137
+ return * (() @trusted => cast (R* )&ret)();
138
+ }
100
139
}
101
140
}
102
141
103
142
// /
104
- unittest
143
+ @safe pure nothrow version(mir_test) unittest
105
144
{
106
145
import mir.ndslice.fuse;
107
- import mir.ndslice.topology: iota;
108
146
import mir.ndslice.slice : Contiguous, Slice;
147
+ import mir.ndslice.topology: iota;
148
+ import mir.rc.array: RCI ;
109
149
110
150
enum ror = [
111
151
[0 , 1 , 2 , 3 ],
@@ -117,14 +157,19 @@ unittest
117
157
// 8 9 10 11
118
158
auto matrix = ror.fuse;
119
159
160
+ auto rcmatrix = ror.rcfuse; // nogc version
161
+
120
162
assert (matrix == [3 , 4 ].iota);
163
+ assert (rcmatrix == [3 , 4 ].iota);
121
164
static assert (ror.fuse == [3 , 4 ].iota); // CTFE-able
165
+
122
166
// matrix is contiguos
123
167
static assert (is (typeof (matrix) == Slice! (int * , 2 )));
168
+ static assert (is (typeof (rcmatrix) == Slice! (RCI ! int , 2 )));
124
169
}
125
170
126
171
// / Transposed
127
- unittest
172
+ @safe pure nothrow version(mir_test) unittest
128
173
{
129
174
import mir.ndslice.fuse;
130
175
import mir.ndslice.topology: iota;
@@ -153,7 +198,7 @@ unittest
153
198
154
199
155
200
// / 3D
156
- unittest
201
+ @safe pure nothrow version(mir_test) unittest
157
202
{
158
203
import mir.ndslice.fuse;
159
204
import mir.ndslice.topology: iota;
@@ -174,7 +219,7 @@ unittest
174
219
}
175
220
176
221
// / Work with RC Arrays of RC Arrays
177
- unittest
222
+ @safe pure nothrow version(mir_test) unittest
178
223
{
179
224
import mir.ndslice.fuse;
180
225
import mir.ndslice.slice;
0 commit comments