1 // Compiler implementation of the D programming language 2 // Copyright (c) 1999-2015 by Digital Mars 3 // All Rights Reserved 4 // written by Walter Bright 5 // http://www.digitalmars.com 6 // Distributed under the Boost Software License, Version 1.0. 7 // http://www.boost.org/LICENSE_1_0.txt 8 9 module ddmd.root.array; 10 11 import core.stdc..string; 12 13 import ddmd.root.rmem; 14 15 extern (C++) struct Array(T) 16 { 17 public: 18 size_t dim; 19 T* data; 20 21 private: 22 size_t allocdim; 23 enum SMALLARRAYCAP = 1; 24 T[SMALLARRAYCAP] smallarray; // inline storage for small arrays 25 26 public: 27 ~this() 28 { 29 if (data != &smallarray[0]) 30 mem.xfree(data); 31 } 32 33 char* toChars() 34 { 35 static if (is(typeof(T.init.toChars()))) 36 { 37 char** buf = cast(char**)mem.xmalloc(dim * (char*).sizeof); 38 size_t len = 2; 39 for (size_t u = 0; u < dim; u++) 40 { 41 buf[u] = data[u].toChars(); 42 len += strlen(buf[u]) + 1; 43 } 44 char* str = cast(char*)mem.xmalloc(len); 45 46 str[0] = '['; 47 char* p = str + 1; 48 for (size_t u = 0; u < dim; u++) 49 { 50 if (u) 51 *p++ = ','; 52 len = strlen(buf[u]); 53 memcpy(p, buf[u], len); 54 p += len; 55 } 56 *p++ = ']'; 57 *p = 0; 58 mem.xfree(buf); 59 return str; 60 } 61 else 62 { 63 assert(0); 64 } 65 } 66 67 void push(T ptr) 68 { 69 reserve(1); 70 data[dim++] = ptr; 71 } 72 73 void append(typeof(this)* a) 74 { 75 insert(dim, a); 76 } 77 78 void reserve(size_t nentries) 79 { 80 //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", (int)dim, (int)allocdim, (int)nentries); 81 if (allocdim - dim < nentries) 82 { 83 if (allocdim == 0) 84 { 85 // Not properly initialized, someone memset it to zero 86 if (nentries <= SMALLARRAYCAP) 87 { 88 allocdim = SMALLARRAYCAP; 89 data = SMALLARRAYCAP ? smallarray.ptr : null; 90 } 91 else 92 { 93 allocdim = nentries; 94 data = cast(T*)mem.xmalloc(allocdim * (*data).sizeof); 95 } 96 } 97 else if (allocdim == SMALLARRAYCAP) 98 { 99 allocdim = dim + nentries; 100 data = cast(T*)mem.xmalloc(allocdim * (*data).sizeof); 101 memcpy(data, smallarray.ptr, dim * (*data).sizeof); 102 } 103 else 104 { 105 allocdim = dim + nentries; 106 data = cast(T*)mem.xrealloc(data, allocdim * (*data).sizeof); 107 } 108 } 109 } 110 111 void remove(size_t i) 112 { 113 if (dim - i - 1) 114 memmove(data + i, data + i + 1, (dim - i - 1) * (data[0]).sizeof); 115 dim--; 116 } 117 118 void insert(size_t index, typeof(this)* a) 119 { 120 if (a) 121 { 122 size_t d = a.dim; 123 reserve(d); 124 if (dim != index) 125 memmove(data + index + d, data + index, (dim - index) * (*data).sizeof); 126 memcpy(data + index, a.data, d * (*data).sizeof); 127 dim += d; 128 } 129 } 130 131 void insert(size_t index, T ptr) 132 { 133 reserve(1); 134 memmove(data + index + 1, data + index, (dim - index) * (*data).sizeof); 135 data[index] = ptr; 136 dim++; 137 } 138 139 void setDim(size_t newdim) 140 { 141 if (dim < newdim) 142 { 143 reserve(newdim - dim); 144 } 145 dim = newdim; 146 } 147 148 ref T opIndex(size_t i) 149 { 150 return data[i]; 151 } 152 153 T* tdata() 154 { 155 return data; 156 } 157 158 typeof(this)* copy() 159 { 160 auto a = new typeof(this)(); 161 a.setDim(dim); 162 memcpy(a.data, data, dim * (void*).sizeof); 163 return a; 164 } 165 166 void shift(T ptr) 167 { 168 reserve(1); 169 memmove(data + 1, data, dim * (*data).sizeof); 170 data[0] = ptr; 171 dim++; 172 } 173 174 void zero() 175 { 176 memset(data, 0, dim * (data[0]).sizeof); 177 } 178 179 T pop() 180 { 181 return data[--dim]; 182 } 183 184 int apply(int function(T, void*) fp, void* param) 185 { 186 static if (is(typeof(T.init.apply(fp, null)))) 187 { 188 for (size_t i = 0; i < dim; i++) 189 { 190 T e = data[i]; 191 if (e) 192 { 193 if (e.apply(fp, param)) 194 return 1; 195 } 196 } 197 return 0; 198 } 199 else 200 assert(0); 201 } 202 }