Skip to content

Commit 1d9bd10

Browse files
committed
improve rcarray
ditto
1 parent c804962 commit 1d9bd10

File tree

4 files changed

+150
-62
lines changed

4 files changed

+150
-62
lines changed

source/mir/interpolate/constant.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ struct Constant(F, size_t N = 1, FirstGridIterator = immutable(F)*, NextGridIter
116116

117117
/++
118118
+/
119-
this(GridVectors grid) scope @safe @nogc
119+
this(GridVectors grid) @safe @nogc
120120
{
121121
size_t length = 1;
122122
size_t[N] shape;

source/mir/interpolate/linear.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ struct Linear(F, size_t N = 1, FirstGridIterator = immutable(F)*, NextGridIterat
203203

204204
/++
205205
+/
206-
this(GridVectors grid) scope @safe @nogc
206+
this(GridVectors grid) @safe @nogc
207207
{
208208
size_t length = 1;
209209
size_t[N] shape;

source/mir/interpolate/spline.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,11 @@ struct Spline(F, size_t N = 1, FirstGridIterator = immutable(F)*, NextGridIterat
458458

459459
/++
460460
+/
461-
this()(GridVectors grid) @trusted @nogc
461+
this(GridVectors grid) @safe @nogc
462462
{
463463
size_t length = 1;
464464
size_t[N] shape;
465-
enum msg = "linear interpolant: minimal allowed length for the grid equals 2.";
465+
enum msg = "spline/pchip interpolant: minimal allowed length for the grid equals 2.";
466466
version(D_Exceptions)
467467
static immutable exc = new Exception(msg);
468468
foreach(i, ref x; grid)

source/mir/rcarray.d

Lines changed: 146 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/++
2+
$(H1 Thread-safe reference-counted arrays and iterators).
23
+/
34
module mir.rcarray;
45

@@ -24,10 +25,8 @@ private template preferCppLinkage(T)
2425
enum preferCppLinkage = true;
2526
else
2627
enum preferCppLinkage = false;
27-
2828
}
2929

30-
///
3130
version(mir_test)
3231
unittest
3332
{
@@ -42,10 +41,6 @@ unittest
4241
static assert (!preferCppLinkage!(immutable C));
4342
}
4443

45-
// extern(C++)
46-
// enum C {e, b}
47-
// pragma(msg, __traits(getLinkage, C));
48-
4944
/++
5045
Thread safe reference counting array.
5146
@@ -54,8 +49,9 @@ Thread safe reference counting array.
5449
The implementation never adds roots into the GC.
5550
+/
5651
struct mir_rcarray(T)
57-
if (T.alignof <= 16)
5852
{
53+
import std.traits;
54+
5955
enum cppSupport = preferCppLinkage!T;
6056

6157
private struct Context
@@ -79,29 +75,6 @@ struct mir_rcarray(T)
7975
return *cast(inout(Context*)*)&_payload;
8076
}
8177

82-
// private inout(Context)* _context() inout @trusted pure nothrow @nogc scope
83-
// {
84-
// return cast(Context*) _contextCode;
85-
// }
86-
87-
// private void _context(Context * context) @trusted pure nothrow @nogc scope
88-
// {
89-
// _contextCode = cast(size_t) context;
90-
// }
91-
92-
///
93-
this(this) scope @trusted pure nothrow @nogc
94-
{
95-
import core.atomic: atomicOp;
96-
if (_context !is null) with(*_context)
97-
{
98-
if (counter)
99-
{
100-
counter.atomicOp!"+="(1);
101-
}
102-
}
103-
}
104-
10578
private void dec()() scope
10679
{
10780
import core.atomic: atomicOp;
@@ -111,7 +84,6 @@ struct mir_rcarray(T)
11184
{
11285
if (counter.atomicOp!"-="(1) == 0)
11386
{
114-
import std.traits: Unqual;
11587
import mir.conv: xdestroy;
11688
Unqual!T[] array;
11789
()@trusted { array = (cast(Unqual!T*)(_context + 1))[0 .. length]; }();
@@ -143,20 +115,21 @@ struct mir_rcarray(T)
143115
}
144116
}
145117

146-
static if (cppSupport) extern(C++)
118+
static if (cppSupport)
147119
{
120+
extern(C++):
148121
///
149122
pragma(inline, false)
150-
~this() scope nothrow @nogc @safe
123+
~this() nothrow @nogc @safe
151124
{
152125
dec();
153126
}
154127

155-
///
128+
/// Extern constructor
156129
pragma(inline, false)
157-
bool initialize(size_t length, uint alignment = T.alignof, bool deallocate = true) scope @safe nothrow @nogc
130+
bool initialize(size_t length, uint alignment, bool deallocate, bool initialize) scope @safe nothrow @nogc
158131
{
159-
return initializeImpl(length, alignment, deallocate);
132+
return initializeImpl(length, alignment, deallocate, initialize);
160133
}
161134

162135
///
@@ -169,15 +142,29 @@ struct mir_rcarray(T)
169142
else
170143
{
171144
pragma(inline, false)
172-
~this() scope nothrow @nogc @safe
145+
~this() nothrow @nogc @safe
173146
{
174147
dec();
175148
}
176149

150+
/// Extern constructor
177151
pragma(inline, false)
178-
bool initialize(size_t length, uint alignment = T.alignof, bool deallocate = true) scope @safe nothrow @nogc
152+
bool initialize(size_t length, uint alignment, bool deallocate, bool initialize) scope @safe nothrow @nogc
179153
{
180-
return initializeImpl(length, alignment, deallocate);
154+
return initializeImpl(length, alignment, deallocate, initialize);
155+
}
156+
}
157+
158+
///
159+
this(this) scope @trusted pure nothrow @nogc
160+
{
161+
import core.atomic: atomicOp;
162+
if (_context !is null) with(*_context)
163+
{
164+
if (counter)
165+
{
166+
counter.atomicOp!"+="(1);
167+
}
181168
}
182169
}
183170

@@ -186,10 +173,11 @@ struct mir_rcarray(T)
186173
length = array length
187174
alignment = alignment, must be power of 2
188175
deallocate = Flag, never deallocates memory if `false`.
176+
initialize = Flag, don't initialize memory with default value if `false`.
189177
+/
190-
this(size_t length, uint alignment = T.alignof, bool deallocate = true) scope @trusted @nogc
178+
this(size_t length, uint alignment = T.alignof, bool deallocate = true, bool initialize = true) @safe @nogc
191179
{
192-
if (!initialize(length, alignment, deallocate))
180+
if (!this.initialize(length, alignment, deallocate, initialize))
193181
{
194182
version(D_Exceptions)
195183
{
@@ -199,10 +187,67 @@ struct mir_rcarray(T)
199187
{
200188
assert(0, allocationExcMsg);
201189
}
202-
}
190+
}
191+
}
192+
193+
static if (isImplicitlyConvertible!(const T, T))
194+
static if (isImplicitlyConvertible!(const Unqual!T, T))
195+
private alias V = const Unqual!T;
196+
else
197+
private alias V = const T;
198+
else
199+
private alias V = T;
200+
201+
static if (hasIndirections!T)
202+
/++
203+
Contructor is defined if `hasIndirections!T == true`.
204+
+/
205+
static typeof(this) create(V[] values...) @safe @nogc
206+
{
207+
auto ret = typeof(this)(values.length, T.alignof, true, false);
208+
static if (!hasElaborateAssign!T)
209+
{
210+
()@trusted {
211+
import core.stdc.string: memcpy;
212+
memcpy(cast(void*)ret.ptr, cast(const void*)values.ptr, values.length * T.sizeof);
213+
}();
214+
}
215+
else
216+
{
217+
import mir.conv: emplaceRef;
218+
auto lhs = ret[];
219+
foreach (i, ref e; values)
220+
lhs[i].emplaceRef(e);
221+
}
222+
return ret;
223+
}
224+
225+
static if (!hasIndirections!T)
226+
/++
227+
Contructor is defined if `hasIndirections!T == false`.
228+
+/
229+
static typeof(this) create(scope V[] values...) @trusted @nogc
230+
{
231+
auto ret = RCArray!T(values.length, T.alignof, true, false);
232+
static if (!hasElaborateAssign!T)
233+
{
234+
()@trusted {
235+
import core.stdc.string: memcpy;
236+
memcpy(cast(void*)ret.ptr, cast(const void*)values.ptr, values.length * T.sizeof);
237+
}();
238+
}
239+
else
240+
{
241+
import mir.conv: emplaceRef;
242+
auto lhs = ret[];
243+
foreach (i, ref e; values)
244+
lhs[i].emplaceRef(e);
245+
}
246+
import std.algorithm.mutation: move;
247+
return ret;
203248
}
204249

205-
private bool initializeImpl()(size_t length, uint alignment, bool deallocate) scope @trusted nothrow @nogc
250+
private bool initializeImpl()(size_t length, uint alignment, bool deallocate, bool initialize) scope @trusted nothrow @nogc
206251
{
207252
if (length == 0)
208253
{
@@ -238,9 +283,12 @@ struct mir_rcarray(T)
238283

239284
_context.length = length;
240285
_context.counter = deallocate; // 0
241-
import mir.conv: uninitializedFillDefault;
242-
import std.traits: Unqual;
243-
uninitializedFillDefault((cast(Unqual!T*)(_context + 1))[0 .. _context.length]);
286+
if (initialize)
287+
{
288+
import mir.conv: uninitializedFillDefault;
289+
import std.traits: Unqual;
290+
uninitializedFillDefault((cast(Unqual!T*)(_context + 1))[0 .. _context.length]);
291+
}
244292
return true;
245293
}
246294

@@ -321,9 +369,35 @@ unittest
321369
assert(a[4] == 100);
322370

323371
import mir.ndslice.slice;
324-
auto s = a.toSlice;
372+
373+
auto s = a.asSlice; // as RC random access range (ndslice)
325374
static assert(is(typeof(s) == Slice!(RCI!double)));
326375
static assert(is(typeof(s) == mir_slice!(mir_rci!double)));
376+
377+
auto r = a[]; // scope array
378+
static assert(is(typeof(r) == double[]));
379+
380+
auto fs = r.sliced; // scope fast random access range (ndslice)
381+
static assert(is(typeof(fs) == Slice!(double*)));
382+
}
383+
384+
///
385+
version(mir_test)
386+
@safe pure @nogc
387+
unittest
388+
{
389+
auto a = RCArray!double.create(1.0, 2, 5, 3);
390+
assert(a[0] == 1);
391+
assert(a[$ - 1] == 3);
392+
393+
auto s = RCArray!char.create("hello!");
394+
assert(s[0] == 'h');
395+
assert(s[$ - 1] == '!');
396+
397+
alias rcstring = RCArray!(immutable char).create;
398+
auto r = rcstring("string");
399+
assert(r[0] == 's');
400+
assert(r[$ - 1] == 'g');
327401
}
328402

329403
/++
@@ -334,20 +408,9 @@ struct mir_rci(T)
334408
///
335409
T* _iterator;
336410

337-
// private inout(T)* _iterator() inout @trusted pure nothrow @nogc scope
338-
// {
339-
// return cast(T*) _iteratorCode;
340-
// }
341-
342-
// private void _iterator(T * iterator) @trusted pure nothrow @nogc scope
343-
// {
344-
// _iteratorCode = cast(size_t) iterator;
345-
// }
346-
347411
///
348412
RCArray!T _array;
349413

350-
351414
mir_rci!(const T) lightConst() scope return const @nogc nothrow @trusted @property
352415
{ return typeof(return)(_iterator, _array.lightConst); }
353416

@@ -465,3 +528,28 @@ version(mir_test)
465528
b = a;
466529
}
467530
}
531+
532+
version(mir_test)
533+
unittest
534+
{
535+
import mir.ndslice.slice: Slice;
536+
static RCArray!int foo() @safe
537+
{
538+
auto ret = RCArray!int(10);
539+
return ret;
540+
}
541+
542+
543+
static Slice!(RCI!int) bat() @safe
544+
{
545+
auto ret = RCArray!int(10);
546+
return ret.asSlice;
547+
}
548+
549+
static Slice!(RCI!int) bar() @safe
550+
{
551+
auto ret = RCArray!int(10);
552+
auto d = ret.asSlice;
553+
return d;
554+
}
555+
}

0 commit comments

Comments
 (0)