1 /* 2 * Kiss - A refined core library for D programming language. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module kiss.container.array; 13 14 import core.stdc.string : memcpy; 15 /** 16 * 17 */ 18 size_t arrayRemove(E)(ref E[] ary, auto ref E e, bool one = false) { 19 E tv = E.init; 20 size_t rm = 0; 21 size_t site = 0; 22 bool unRemove = false; 23 for (size_t j = site; j < ary.length; ++j) { 24 if (ary[j] != e || unRemove) { 25 if(site != j) 26 memcpy(&ary[site], &ary[j], E.sizeof); 27 site++; 28 } else { 29 doInitVaule(ary[j]); 30 rm++; 31 if(one) 32 unRemove = true; 33 } 34 } 35 if(rm > 0) { 36 auto size = ary.length - rm; 37 auto rmed = ary[size .. $]; 38 ary = ary[0..size]; 39 fillWithMemcpy(rmed, tv); 40 } 41 return rm; 42 } 43 44 E[] removeSite(E)(ref E[] _array,size_t site) 45 in { 46 assert(site < _array.length); 47 } body{ 48 const size_t len = _array.length - 1; 49 doInitVaule(_array[site]); 50 for (size_t i = site; i < len; ++i) { 51 memcpy(&(_array[i]), &(_array[i + 1]), E.sizeof); 52 } 53 E v = E.init; 54 memcpy(&(_array[len]), &v, E.sizeof); 55 _array = _array[0..len]; 56 return _array; 57 } 58 59 void doInitVaule(E)(ref E v){ 60 static if(is(E == struct) && hasElaborateDestructor!E) { 61 destroy(v); 62 } 63 memcpy(&v,&v,E.sizeof); 64 } 65 66 //from std.experimental.allocator.package; 67 void fillWithMemcpy(T)(void[] array, auto ref T filler) nothrow 68 { 69 import core.stdc.string : memcpy; 70 import std.algorithm.comparison : min; 71 if (!array.length) return; 72 memcpy(array.ptr, &filler, T.sizeof); 73 // Fill the array from the initialized portion of itself exponentially. 74 for (size_t offset = T.sizeof; offset < array.length; ) 75 { 76 size_t extent = min(offset, array.length - offset); 77 memcpy(array.ptr + offset, array.ptr, extent); 78 offset += extent; 79 } 80 } 81 82 unittest { 83 import std.stdio; 84 85 int[] a = [0, 0, 0, 4, 5, 4, 0, 8, 0, 2, 0, 0, 0, 1, 2, 5, 8, 0]; 86 writeln("length a = ", a.length, " a is : ", a); 87 int[] b = a.dup; 88 auto rm = arrayRemove(b, 0); 89 writeln("length b = ", b.length, " b is : ", b); 90 assert(b == [4, 5, 4, 8, 2, 1, 2, 5, 8]); 91 92 int[] c = a.dup; 93 rm = arrayRemove(c, 8); 94 writeln("length c = ", c.length, " c is : ", c); 95 96 assert(c == [0, 0, 0, 4, 5, 4, 0, 0, 2, 0, 0, 0, 1, 2, 5, 0]); 97 98 int[] d = a.dup; 99 rm = arrayRemove(d, 9); 100 writeln("length d = ", d.length, " d is : ", d); 101 assert(d == a); 102 }