1 module mutils.view2d; 2 3 import std.traits: ForeachType; 4 5 struct View2D(Slice){ 6 alias T=ForeachType!Slice; 7 Slice slice; 8 size_t columnsNum=1; 9 10 11 Slice opIndex(size_t y){ 12 return slice[y*columnsNum..(y+1)*columnsNum]; 13 } 14 15 ref T opIndex(size_t y, size_t x){ 16 assert(x<columnsNum); 17 return slice[y*columnsNum+x]; 18 } 19 20 Slice opIndex(size_t y, size_t[2] x){ 21 assert(x[0]<=x[1]); 22 assert(x[1]<=columnsNum); 23 size_t start=y*columnsNum; 24 return slice[start+x[0]..start+x[1]]; 25 } 26 27 size_t[2] opSlice(size_t dim)(size_t start, size_t end){ 28 return [start, end]; 29 } 30 31 size_t opDollar(size_t dim )() { 32 static assert(dim<2); 33 static if(dim==0){ 34 return columnsNum; 35 }else{ 36 return cast(size_t)(slice.length/columnsNum); 37 } 38 } 39 40 // foreach support 41 int opApply(scope int delegate(Slice) dg){ 42 int result; 43 foreach(y;0..cast(size_t)(slice.length/columnsNum)){ 44 result=dg(opIndex(y)); 45 if (result) 46 break; 47 } 48 49 return result; 50 } 51 52 // foreach support 53 int opApply(scope int delegate(size_t, Slice) dg){ 54 int result; 55 foreach(y;0..cast(size_t)(slice.length/columnsNum)){ 56 result=dg(y, opIndex(y)); 57 if (result) 58 break; 59 } 60 61 return result; 62 } 63 } 64 65 unittest{ 66 int[9] arr=[0,1,2,3,4,5,6,7,8]; 67 View2D!(int[]) view; 68 view.slice=arr[]; 69 view.columnsNum=3; 70 71 // opIndex[y] 72 assert(view[0]==[0,1,2]); 73 assert(view[1]==[3,4,5]); 74 assert(view[2]==[6,7,8]); 75 76 // opIndex[y, x] 77 assert(view[0,0]==0); 78 assert(view[0,1]==1); 79 assert(view[0,2]==2); 80 assert(view[1,0]==3); 81 assert(view[1,1]==4); 82 assert(view[1,2]==5); 83 assert(view[2,0]==6); 84 assert(view[2,1]==7); 85 assert(view[2,2]==8); 86 // opIndex[y,x1..x2] 87 assert(view[0,1..$]==[1,2]); 88 // opDollar 89 assert(view[$-1]==[6,7,8]); 90 assert(view[$-1,$-2]==7); 91 // Foreach 92 foreach(row; view){} 93 foreach(i, row; view){ 94 assert(row==[i*3+0, i*3+1, i*3+2]); 95 } 96 // Assigment 97 view[2,2]=123; 98 assert(view[2,2]==123); 99 }