alias ir = inclusiveRange;autoinclusiveRange(T =int)(T f =T(0), T l =T(0), T s =T(1)){if(!l){
l = f;
f =0;}return InclusiveRange!T(f, l, s);}structInclusiveRange(T){
T front, last, step, term;this(T front, T last, T step){this.front = front;this.last = last;this.step = step;this.term = last;if(this.diff % step){const t =cast(int)(this.diff / step);this.term =cast(T)(t * step +this.front);}}autosave(){returnthis;}autoopSlice(){returnthis;}autoopDollar(){returnthis.length;}autoopSlice(T a, T b)in(b<=this.length){return InclusiveRange!T(cast(T)(front + a * step),cast(T)(front +(b -1)* step), step);}boolopBinaryRight(string op:"in")(T lhs){foreach(r;this){if(isClose(lhs, r,1e-6)){returntrue;}}returnfalse;}
T sum(){const residueCheck = front ?2* front + diff
: diff;returncast(T)(length * residueCheck /2);}autodiff(){return term - front;}autolength(){returncast(int)(diff / step +1);}boolempty(){return front > last;}
T back(){return last;}voidpopBack(){if(!empty) last -= step;}voidpopFront(){if(!empty) front += step;}}