egedit: do not save cursor movement in undo -- this is my stupid habit, and it comple...
[iv.d.git] / unarray.d
blob1e2f7757fe9248c31d2077e36f98afcc44d9f64c
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, 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*/;
20 import iv.alice;
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) {
27 auto optr = arr.ptr;
28 arr.reserve(newlen);
29 if (arr.ptr !is optr) {
30 import core.memory : GC;
31 optr = arr.ptr;
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) {
41 arr.length = newlen;
42 if (arr.capacity) arr.assumeSafeAppend;
43 } else if (arr.length < newlen) {
44 auto optr = arr.ptr;
45 arr.length = newlen;
46 if (arr.ptr !is optr) {
47 import core.memory : GC;
48 optr = arr.ptr;
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");
57 auto optr = arr.ptr;
58 arr ~= v;
59 if (arr.ptr !is optr) {
60 import core.memory : GC;
61 optr = arr.ptr;
62 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
67 public void unsafeArrayClear(T) (ref T[] arr) /*nothrow*/ {
68 if (arr.length) {
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);
72 arr.length = 0;
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);
86 arr.length -= 1;
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");
95 auto optr = arr.ptr;
96 arr.length += 1;
97 if (arr.ptr != optr) {
98 import core.memory : GC;
99 optr = arr.ptr;
100 if (optr is GC.addrOf(optr)) GC.setAttr(optr, GC.BlkAttr.NO_INTERIOR);
102 // move elements down
103 if (idx < olen) {
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);
108 arr[idx] = v;