@@ -1621,24 +1621,25 @@ version(mir_test) unittest
16211621/+ +
16221622`StairsIterator` is used by $(SUBREF topology, stairs).
16231623+/
1624- struct StairsIterator (Iterator)
1624+ struct StairsIterator (Iterator, string direction)
1625+ if (direction == " +" || direction == " -" )
16251626{
16261627 // /
1627- size_t _length = 1 ;
1628+ size_t _length;
16281629
16291630 // /
16301631 Iterator _iterator;
16311632
16321633 // /
16331634 auto lightConst ()() const @property
16341635 {
1635- return StairsIterator! (LightConstOf! Iterator)(_length, _iterator.lightConst);
1636+ return StairsIterator! (LightConstOf! Iterator, direction )(_length, _iterator.lightConst);
16361637 }
16371638
16381639 // /
16391640 auto lightImmutable ()() immutable @property
16401641 {
1641- return StairsIterator! (LightImmutableOf! Iterator)(_length, _iterator.lightImmutable);
1642+ return StairsIterator! (LightImmutableOf! Iterator, direction )(_length, _iterator.lightImmutable);
16421643 }
16431644
16441645@optmath:
@@ -1654,9 +1655,17 @@ struct StairsIterator(Iterator)
16541655 Slice! Iterator opIndex ()(ptrdiff_t index)
16551656 {
16561657 import mir.ndslice.slice: sliced;
1657- auto newLength = _length + index;
1658+ static if (direction == " +" )
1659+ {
1660+ auto newLength = _length + index;
1661+ auto shift = ptrdiff_t (_length + newLength - 1 ) * index / 2 ;
1662+ }
1663+ else
1664+ {
1665+ auto newLength = _length - index;
1666+ auto shift = ptrdiff_t (_length + newLength + 1 ) * index / 2 ;
1667+ }
16581668 assert (ptrdiff_t (newLength) >= 0 );
1659- auto shift = ptrdiff_t (_length + newLength - 1 ) * index / 2 ;
16601669 return (_iterator + shift).sliced(newLength);
16611670 }
16621671
@@ -1666,24 +1675,39 @@ struct StairsIterator(Iterator)
16661675 static if (op == " ++" )
16671676 {
16681677 _iterator += _length;
1669- ++ _length;
1678+ static if (direction == " +" )
1679+ ++ _length;
1680+ else
1681+ -- _length;
16701682 }
16711683 else
16721684 {
16731685 assert (_length);
1674- -- _length;
1686+ static if (direction == " +" )
1687+ -- _length;
1688+ else
1689+ ++ _length;
16751690 _iterator -= _length;
16761691 }
16771692 }
16781693
16791694 void opOpAssign (string op)(ptrdiff_t index)
16801695 if (op == " -" || op == " +" )
16811696 {
1682- auto newLength = mixin (" _length " ~ op ~ " index" );
1697+ static if (op == direction)
1698+ auto newLength = _length + index;
1699+ else
1700+ auto newLength = _length - index;
1701+ static if (direction == " +" )
1702+ auto shift = ptrdiff_t (_length + newLength - 1 ) * index / 2 ;
1703+ else
1704+ auto shift = ptrdiff_t (_length + newLength + 1 ) * index / 2 ;
16831705 assert (ptrdiff_t (newLength) >= 0 );
1684- auto shift = ptrdiff_t (_length + newLength - 1 ) * index / 2 ;
16851706 _length = newLength;
1686- mixin (" _iterator " ~ op ~ " = shift;" );
1707+ static if (op == " +" )
1708+ _iterator += shift;
1709+ else
1710+ _iterator -= shift;
16871711 }
16881712
16891713 auto opBinary (string op)(ptrdiff_t index)
@@ -1695,13 +1719,18 @@ struct StairsIterator(Iterator)
16951719 }
16961720
16971721 ptrdiff_t opBinary (string op : " -" )(auto ref const typeof (this ) right) const
1698- { return this ._length - right._length; }
1722+ {
1723+ static if (direction == " +" )
1724+ return this ._length - right._length;
1725+ else
1726+ return right._length - this ._length;
1727+ }
16991728
17001729 bool opEquals ()(ref const typeof (this ) right) const
17011730 { return this ._length == right._length; }
17021731
17031732 ptrdiff_t opCmp ()(ref const typeof (this ) right) const
1704- { return this ._length - right._length ; }
1733+ { return this - right; }
17051734}
17061735
17071736// /
@@ -1712,7 +1741,7 @@ version(mir_test) unittest
17121741 // 3 4 5
17131742 // 6 7 8 9
17141743 // 10 11 12 13 14
1715- auto it = StairsIterator! (IotaIterator! size_t )(1 , IotaIterator! size_t ());
1744+ auto it = StairsIterator! (IotaIterator! size_t , " + " )(1 , IotaIterator! size_t ());
17161745 assert (* it == [0 ]);
17171746 assert (it[4 ] == [10 , 11 , 12 , 13 , 14 ]);
17181747 assert (* (it + 4 ) == [10 , 11 , 12 , 13 , 14 ]);
@@ -1724,7 +1753,33 @@ version(mir_test) unittest
17241753 assert (* (it - 3 ) == [1 , 2 ]);
17251754 assert (it + 1 > it);
17261755 assert (it + 1 - 1 == it);
1727- assert (it + 3 - it == 3 );
1756+ assert (it - 3 - it == - 3 );
17281757 -- it;
17291758 assert (* it == [6 , 7 , 8 , 9 ]);
17301759}
1760+
1761+ // /
1762+ version (mir_test) unittest
1763+ {
1764+ // [0, 1, 2, 3, 4],
1765+ // [5, 6, 7, 8],
1766+ // [9, 10, 11],
1767+ // [12, 13],
1768+ // [14]]);
1769+
1770+ auto it = StairsIterator! (IotaIterator! size_t , " -" )(5 , IotaIterator! size_t ());
1771+ assert (* it == [0 , 1 , 2 , 3 , 4 ]);
1772+ assert (it[4 ] == [14 ]);
1773+ assert (* (it + 4 ) == [14 ]);
1774+ ++ it;
1775+ assert (* it == [5 , 6 , 7 , 8 ]);
1776+ it += 3 ;
1777+ assert (* it == [14 ]);
1778+ assert (it[- 3 ] == [5 , 6 , 7 , 8 ]);
1779+ assert (* (it - 3 ) == [5 , 6 , 7 , 8 ]);
1780+ assert (it + 1 > it);
1781+ assert (it + 1 - 1 == it);
1782+ assert (it - 3 - it == - 3 );
1783+ -- it;
1784+ assert (* it == [12 , 13 ]);
1785+ }
0 commit comments