cosmetix
[iv.d.git] / unarray.d
blobf48e126c3e6a033a3b1f45d1e210a82dd699d622
1 /*
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, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // some "unsafe" array operations
19 // such arrays should be always anchored to first element
20 module iv.unarray /*is aliced*/;
21 import iv.alice;
24 // ////////////////////////////////////////////////////////////////////////// //
25 public void unsafeArrayReserve(T) (ref T[] arr, usize newlen) /*nothrow*/ {
26 if (/*newlen < 0 ||*/ newlen >= int.max/2) assert(0, "invalid number of elements in array");
27 if (arr.length < newlen) {
28 auto optr = arr.ptr;
29 arr.reserve(newlen);
30 if (arr.ptr !is optr) {
31 import core.memory : GC;
32 optr = arr.ptr;
33 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
39 public void unsafeArraySetLength(T) (ref T[] arr, usize newlen) /*nothrow*/ {
40 if (/*newlen < 0 ||*/ newlen >= int.max/2) assert(0, "invalid number of elements in array");
41 if (arr.length > newlen) {
42 arr.length = newlen;
43 arr.assumeSafeAppend;
44 } else if (arr.length < newlen) {
45 auto optr = arr.ptr;
46 arr.length = newlen;
47 if (arr.ptr !is optr) {
48 import core.memory : GC;
49 optr = arr.ptr;
50 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
56 public void unsafeArrayAppend(T) (ref T[] arr, auto ref T v) /*nothrow*/ {
57 if (arr.length >= int.max/2) assert(0, "too many elements in array");
58 auto optr = arr.ptr;
59 arr ~= v;
60 if (arr.ptr !is optr) {
61 import core.memory : GC;
62 optr = arr.ptr;
63 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
68 public void unsafeArrayClear(T) (ref T[] arr) /*nothrow*/ {
69 if (arr.length) {
70 import core.stdc.string : memset;
71 static if (is(T == class)) arr[] = null; /*else arr[] = T.init;*/
72 memset(arr.ptr, 0, arr.length*T.sizeof);
73 arr.length = 0;
74 arr.assumeSafeAppend;
79 public void unsafeArrayRemove(T) (ref T[] arr, usize idx) /*nothrow*/ {
80 if (/*idx < 0 ||*/ idx >= arr.length) assert(0, "invalid index in `unsafeArrayRemove()`");
81 static if (is(T == class)) arr[idx] = null; else arr[idx] = T.init;
82 if (arr.length-idx > 1) {
83 import core.stdc.string : memset, memmove;
84 memmove(arr.ptr+idx, arr.ptr+idx+1, (arr.length-idx-1)*T.sizeof);
85 memset(arr.ptr+arr.length-1, 0, T.sizeof);
87 arr.length -= 1;
88 arr.assumeSafeAppend;
92 public void unsafeArrayInsertBefore(T) (ref T[] arr, usize idx, auto ref T v) /*nothrow*/ {
93 if (/*idx < 0 ||*/ idx > arr.length) assert(0, "invalid index in `unsafeArrayRemove()`");
94 auto olen = cast(int)arr.length;
95 if (olen >= int.max/2) assert(0, "too many elements in array");
96 auto optr = arr.ptr;
97 arr.length += 1;
98 if (arr.ptr != optr) {
99 import core.memory : GC;
100 optr = arr.ptr;
101 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
103 // move elements down
104 if (idx < olen) {
105 import core.stdc.string : memset, memmove;
106 memmove(arr.ptr+idx+1, arr.ptr+idx, (olen-idx)*T.sizeof);
107 memset(arr.ptr+idx, 0, T.sizeof);
109 arr[idx] = v;