2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // some "unsafe" array operations
18 // such arrays should be always anchored to first element
19 module iv
.unarray
/*is aliced*/;
23 // ////////////////////////////////////////////////////////////////////////// //
24 public void unsafeArrayReserve(T
) (ref T
[] arr
, usize newlen
) /*nothrow*/ {
25 if (/*newlen < 0 ||*/ newlen
>= int.max
/2) assert(0, "invalid number of elements in array");
26 if (arr
.length
< newlen
) {
29 if (arr
.ptr
!is optr
) {
30 import core
.memory
: GC
;
32 if (optr
is GC
.addrOf(optr
)) GC
.setAttr(optr
, GC
.BlkAttr
.NO_INTERIOR
);
38 public void unsafeArraySetLength(T
) (ref T
[] arr
, usize newlen
) /*nothrow*/ {
39 if (/*newlen < 0 ||*/ newlen
>= int.max
/2) assert(0, "invalid number of elements in array");
40 if (arr
.length
> newlen
) {
42 if (arr
.capacity
) arr
.assumeSafeAppend
;
43 } else if (arr
.length
< newlen
) {
46 if (arr
.ptr
!is optr
) {
47 import core
.memory
: GC
;
49 if (optr
is GC
.addrOf(optr
)) GC
.setAttr(optr
, GC
.BlkAttr
.NO_INTERIOR
);
55 public void unsafeArrayAppend(T
) (ref T
[] arr
, auto ref T v
) /*nothrow*/ {
56 if (arr
.length
>= int.max
/2) assert(0, "too many elements in array");
59 if (arr
.ptr
!is optr
) {
60 import core
.memory
: GC
;
62 if (optr
is GC
.addrOf(optr
)) GC
.setAttr(optr
, GC
.BlkAttr
.NO_INTERIOR
);
67 public void unsafeArrayClear(T
) (ref T
[] arr
) /*nothrow*/ {
69 import core
.stdc
.string
: memset
;
70 static if (is(T
== class)) arr
[] = null; /*else arr[] = T.init;*/
71 memset(arr
.ptr
, 0, arr
.length
*T
.sizeof
);
73 if (arr
.capacity
) arr
.assumeSafeAppend
;
78 public void unsafeArrayRemove(T
) (ref T
[] arr
, usize idx
) /*nothrow*/ {
79 if (/*idx < 0 ||*/ idx
>= arr
.length
) assert(0, "invalid index in `unsafeArrayRemove()`");
80 static if (is(T
== class)) arr
[idx
] = null; else arr
[idx
] = T
.init
;
81 if (arr
.length
-idx
> 1) {
82 import core
.stdc
.string
: memset
, memmove
;
83 memmove(arr
.ptr
+idx
, arr
.ptr
+idx
+1, (arr
.length
-idx
-1)*T
.sizeof
);
84 memset(arr
.ptr
+arr
.length
-1, 0, T
.sizeof
);
87 if (arr
.capacity
) arr
.assumeSafeAppend
;
91 public void unsafeArrayInsertBefore(T
) (ref T
[] arr
, usize idx
, auto ref T v
) /*nothrow*/ {
92 if (/*idx < 0 ||*/ idx
> arr
.length
) assert(0, "invalid index in `unsafeArrayRemove()`");
93 auto olen
= cast(int)arr
.length
;
94 if (olen
>= int.max
/2) assert(0, "too many elements in array");
97 if (arr
.ptr
!= optr
) {
98 import core
.memory
: GC
;
100 if (optr
is GC
.addrOf(optr
)) GC
.setAttr(optr
, GC
.BlkAttr
.NO_INTERIOR
);
102 // move elements down
104 import core
.stdc
.string
: memset
, memmove
;
105 memmove(arr
.ptr
+idx
+1, arr
.ptr
+idx
, (olen
-idx
)*T
.sizeof
);
106 memset(arr
.ptr
+idx
, 0, T
.sizeof
);