Skip to content

Commit f33531c

Browse files
author
Guillaume Piolat
committed
Multiple vec fixes that are useful to implement canvas_ity. I found quite a bit of oddity in vector still.
- Remove bizzarre idata() method, normally inout should not contaminate identifiers. Fixed that in strings, I supposed the goal was to not return mutable C string from numem string - vec.ptr() as alias to vec.data(), which is not inout. It fixed ref auto opOpAssign(string op = "~")(vector!T other) that uses other.ptr - vec.length as alias of vec.size - clear() and remove() will clean-up items in reverse manner just like the destructor, and only if not a basic type. - ref inout(T) opIndex. else you can't index vector fields in const methods - BREAKING remove is fixed (it was not possible to remove zero items with its API without crashing) and is now "delete [start, end)" instead of "delete [start, end]" Changed error recovery that swaps start and end to assertion. That makes the functions more similar in contract to c++ std::vector::erase and a bit more expected to me. IF the contract doesn't change, at least it should say plainly that this will crash if no items are removed.
1 parent 273b28f commit f33531c

File tree

2 files changed

+36
-39
lines changed

2 files changed

+36
-39
lines changed

source/numem/collections/vector.d

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,10 @@ public:
199199
Gets the C data pointer
200200
*/
201201
@trusted
202-
T* data() {
202+
inout(T)* data() inout {
203203
return memory;
204204
}
205-
206-
/**
207-
Gets the C data pointer as an inout pointer
208-
*/
209-
@trusted
210-
inout(T)* idata() inout {
211-
return cast(inout(T)*)memory;
212-
}
205+
alias ptr = data; ///ditto
213206

214207
/**
215208
Gets the C data pointer atomically
@@ -278,6 +271,7 @@ public:
278271
size_t size() inout {
279272
return size_;
280273
}
274+
alias length = size; ///ditto
281275

282276
/**
283277
Gets the capacity of the vector
@@ -302,8 +296,8 @@ public:
302296
void clear() {
303297

304298
// Delete elements in the array.
305-
static if (ownsMemory) {
306-
foreach(item; 0..size_) {
299+
static if (ownsMemory && !isBasicType!T) {
300+
foreach_reverse(item; 0..size_) {
307301
nogc_delete(memory[item]);
308302
}
309303
}
@@ -318,7 +312,7 @@ public:
318312
void remove(size_t position) {
319313
if (position < size_) {
320314

321-
static if (ownsMemory)
315+
static if (ownsMemory && !isBasicType!T)
322316
nogc_delete(memory[position]);
323317

324318
// Move memory region around so that the deleted element is overwritten.
@@ -329,33 +323,27 @@ public:
329323
}
330324

331325
/**
332-
Erases element at position
326+
Erases element at position [start, end)
327+
End is NOT included in that range.
333328
*/
334329
@trusted
335330
void remove(size_t start, size_t end) {
336331

337-
// Flip inputs if they are reversed, just in case.
338-
if (end > start) {
339-
size_t tmp = start;
340-
start = end;
341-
end = tmp;
342-
}
343-
344-
if (start < size_ && end < size_) {
345-
346-
// NOTE: the ".." operator is start inclusive, end exclusive.
347-
static if (ownsMemory) {
348-
foreach(i; start..end+1)
349-
nogc_delete(memory[i]);
350-
}
332+
assert(start <= end && end <= size_);
351333

352-
// Copy over old elements
353-
size_t span = (end+1)-start;
354-
// memory[start..start+span] = memory[end..end+span];
355-
memmove(memory+start, memory+end, span*(T*).sizeof);
334+
// NOTE: the ".." operator is start inclusive, end exclusive.
335+
static if (ownsMemory && !isBasicType!T) {
336+
foreach_reverse(i; start..end)
337+
nogc_delete(memory[i]);
356338

357-
size_ -= span;
358339
}
340+
341+
// Copy over old elements
342+
size_t span = end-start;
343+
// memory[start..start+span] = memory[end..end+span];
344+
memmove(memory+start, memory+end, span*(T*).sizeof);
345+
346+
size_ -= span;
359347
}
360348

361349
/**
@@ -491,7 +479,7 @@ public:
491479
Override for $ operator
492480
*/
493481
@trusted
494-
size_t opDollar() {
482+
size_t opDollar() const {
495483
return size_;
496484
}
497485

@@ -525,7 +513,7 @@ public:
525513
Allows getting an item from the vector.
526514
*/
527515
@trusted
528-
ref T opIndex(size_t index) {
516+
ref inout(T) opIndex(size_t index) inout {
529517
return memory[index];
530518
}
531519

@@ -578,3 +566,12 @@ unittest {
578566
vector!(shared_ptr!A) v;
579567
v ~= a; // Used to crash, see Issue #2
580568
}
569+
570+
@("vector: delete")
571+
unittest {
572+
vector!int v;
573+
v ~= [1, 2, 3];
574+
v.remove(0, 0);
575+
v.remove(1, 1);
576+
v.remove(2, 2);
577+
}

source/numem/string.d

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,16 @@ public:
207207
/**
208208
Returns C string
209209
*/
210-
inout(T)* toCStringi() inout {
211-
return cast(inout(T)*)this.vec_.idata();
210+
immutable(T)* toCString() immutable {
211+
return this.vec_.data();
212212
}
213213

214214
/**
215215
Returns C string
216216
*/
217217
@trusted
218-
const(T)* toCString() {
219-
return cast(const(T)*)this.vec_.data();
218+
const(T)* toCString() const {
219+
return this.vec_.data();
220220
}
221221

222222
/**
@@ -359,7 +359,7 @@ public:
359359
import core.stdc.string : strncmp;
360360
if (this.size() < s.size()) return -1;
361361
if (this.size() > s.size()) return 1;
362-
return strncmp(this.toCStringi(), s.toCStringi(), this.size());
362+
return strncmp(this.toCString(), s.toCString(), this.size());
363363
}
364364

365365
/**

0 commit comments

Comments
 (0)