1 module ggeD.iterator; 2 import mir.qualifier; 3 import mir.ndslice; 4 import std.traits; 5 6 struct EinsumIterator(Iterator,SomeSlice,Node) if(is(SomeSlice == Slice!(T, Rank, kind),T,ulong Rank,SliceKind kind)) 7 { 8 Iterator _iterator; 9 SomeSlice _slice; 10 Node node_; 11 12 static enum Rank = SomeSlice.N; 13 14 private size_t[Rank] ijk(Iterator itr) 15 { 16 size_t num = cast(size_t)(itr - _slice._iterator); 17 size_t[Rank] result; 18 static foreach(i; 0..Rank) 19 { 20 result[i] = cast(size_t)(num/_slice._stride!i); 21 num -= result[i]*_slice._stride!i; 22 } 23 return result; 24 } 25 auto lightConst()() const @property 26 { 27 return EinsumIterator!(LightConstOf!Iterator,SomeSlice, Node)(mir.qualifier.lightConst(_iterator),_slice,cast(Unqual!Node)node_); 28 } 29 auto lightImmutable()() immutable @property 30 { 31 return EinsumIterator!(LightImmutableOf!Iterator, SomeSlice, Node)(mir.qualifier.lightImmutable(_iterator),cast(Unqual!Node)_slice,node_); 32 } 33 import std.stdio; 34 35 auto ref opUnary(string op : "*")() 36 { 37 return node_.calc(ijk(_iterator).tupleof); 38 } 39 40 auto ref opIndex(ptrdiff_t index) scope 41 { 42 return node_.calc(ijk(_iterator+index).tupleof); 43 } 44 static if (!__traits(compiles, &opIndex(ptrdiff_t.init))) 45 { 46 auto ref opIndexAssign(T)(auto ref T value, ptrdiff_t index) scope 47 { 48 return _iterator[index] = value; 49 } 50 51 auto ref opIndexUnary(string op)(ptrdiff_t index) 52 { 53 return mixin(op ~ "node_.calc(ijk(_iterator+index).tupleof)"); 54 } 55 56 auto ref opIndexOpAssign(string op, T)(T value, ptrdiff_t index) 57 { 58 return mixin("_iterator[index]" ~ op ~ "= value"); 59 } 60 } 61 62 63 void opUnary(string op)() scope 64 if (op == "--" || op == "++") 65 { mixin(op ~ "_iterator;"); } 66 67 void opOpAssign(string op)(ptrdiff_t index) scope 68 if (op == "-" || op == "+") 69 { mixin("_iterator " ~ op ~ "= index;"); } 70 71 auto opBinary(string op)(ptrdiff_t index) 72 if (op == "+" || op == "-") 73 { 74 auto ret = this; 75 mixin(`ret ` ~ op ~ `= index;`); 76 return ret; 77 } 78 79 ptrdiff_t opBinary(string op : "-")(scope ref const typeof(this) right) scope const 80 { return this._iterator - right._iterator; } 81 82 bool opEquals()(scope ref const typeof(this) right) scope const 83 { return this._iterator == right._iterator; } 84 85 ptrdiff_t opCmp()(scope ref const typeof(this) right) scope const 86 { 87 static if (isPointer!Iterator) 88 return this._iterator - right._iterator; 89 else 90 return this._iterator.opCmp(right._iterator); 91 } 92 93 }