Skip to content

Commit 7af2d61

Browse files
committed
improve iterators
1 parent 0f7380d commit 7af2d61

File tree

1 file changed

+87
-15
lines changed

1 file changed

+87
-15
lines changed

source/mir/ndslice/iterator.d

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ auto MapIterator__map(Iterator, alias fun0, alias fun)(ref MapIterator!(Iterator
498498
+/
499499
struct MapIterator(Iterator, alias fun)
500500
{
501+
import mir.functional: RefTuple, unref;
502+
501503
@fastmath:
502504
///
503505
Iterator _iterator;
@@ -508,10 +510,6 @@ struct MapIterator(Iterator, alias fun)
508510

509511
auto ref opUnary(string op : "*")()
510512
{
511-
import mir.functional: RefTuple, unref;
512-
static if (is(Iterator : ZipIterator!(Iterators), Iterators...))
513-
return mixin("fun(" ~ _iotaArgs!(Iterators.length, "*_iterator._iterators[", "], ") ~ ")");
514-
else
515513
static if (is(typeof(*_iterator) : RefTuple!T, T...))
516514
{
517515
auto t = *_iterator;
@@ -527,10 +525,6 @@ struct MapIterator(Iterator, alias fun)
527525

528526
auto ref opIndex()(ptrdiff_t index)
529527
{
530-
import mir.functional: RefTuple, unref;
531-
static if (is(Iterator : ZipIterator!(Iterators), Iterators...))
532-
return mixin("fun(" ~ _iotaArgs!(Iterators.length, "_iterator._iterators[", "][index], ") ~ ")");
533-
else
534528
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
535529
{
536530
auto t = _iterator[index];
@@ -540,6 +534,42 @@ struct MapIterator(Iterator, alias fun)
540534
return fun(_iterator[index]);
541535
}
542536

537+
static if (!__traits(compiles, &opIndex(ptrdiff_t.init)))
538+
{
539+
auto ref opIndexAssign(T)(T value, ptrdiff_t index)
540+
{
541+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
542+
{
543+
auto t = _iterator[index];
544+
return mixin("fun(" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ ") = value");
545+
}
546+
else
547+
return fun(_iterator[index]) = value;
548+
}
549+
550+
auto ref opIndexUnary(string op)(ptrdiff_t index)
551+
{
552+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
553+
{
554+
auto t = _iterator[index];
555+
return mixin(op ~ "fun(" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ ")");
556+
}
557+
else
558+
return mixin(op ~ "fun(_iterator[index])");
559+
}
560+
561+
auto ref opIndexOpAssign(string op, T)(T value, ptrdiff_t index)
562+
{
563+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
564+
{
565+
auto t = _iterator[index];
566+
return mixin("fun(" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ ")" ~ op ~ "= value");
567+
}
568+
else
569+
return mixin("fun(_iterator[index])" ~ op ~ "= value");
570+
}
571+
}
572+
543573
void opOpAssign(string op)(ptrdiff_t index)
544574
if (op == "-" || op == "+")
545575
{ mixin("_iterator " ~ op ~ "= index;"); }
@@ -603,6 +633,8 @@ Iterates a field using an iterator.
603633
+/
604634
struct IndexIterator(Iterator, Field)
605635
{
636+
import mir.functional: RefTuple, unref;
637+
606638
@fastmath:
607639
///
608640
Iterator _iterator;
@@ -613,25 +645,65 @@ struct IndexIterator(Iterator, Field)
613645
static alias __map(alias fun) = IndexIterator__map!(Iterator, Field, fun);
614646

615647
auto ref opUnary(string op : "*")()
616-
{ return _field[*_iterator]; }
648+
{
649+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
650+
{
651+
auto t = *_iterator;
652+
return mixin("_field[" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ "]");
653+
}
654+
else
655+
return _field[*_iterator];
656+
}
617657

618658
void opUnary(string op)()
619659
if (op == "--" || op == "++")
620660
{ mixin(op ~ "_iterator;"); }
621661

622-
auto ref opIndex()(ptrdiff_t index)
623-
{ return _field[_iterator[index]]; }
662+
auto ref opIndex(ptrdiff_t index)
663+
{
664+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
665+
{
666+
auto t = _iterator[index];
667+
return mixin("_field[" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ "]");
668+
}
669+
else
670+
return _field[_iterator[index]];
671+
}
624672

625-
static if (!__traits(compiles, &_field[_iterator[ptrdiff_t.init]]))
673+
static if (!__traits(compiles, &opIndex(ptrdiff_t.init)))
626674
{
627675
auto ref opIndexAssign(T)(T value, ptrdiff_t index)
628-
{ return _field[_iterator[index]] = value; }
676+
{
677+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
678+
{
679+
auto t = _iterator[index];
680+
return mixin("_field[" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ "] = value");
681+
}
682+
else
683+
return _field[_iterator[index]] = value;
684+
}
629685

630686
auto ref opIndexUnary(string op)(ptrdiff_t index)
631-
{ mixin (`return ` ~ op ~ `_field[_iterator[_index]];`); }
687+
{
688+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
689+
{
690+
auto t = _iterator[index];
691+
return mixin(op ~ "_field[" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ "]");
692+
}
693+
else
694+
return mixin(op ~ "_field[_iterator[index]]");
695+
}
632696

633697
auto ref opIndexOpAssign(string op, T)(T value, ptrdiff_t index)
634-
{ mixin (`return _field[_iterator[_index]] ` ~ op ~ `= value;`); }
698+
{
699+
static if (is(typeof(_iterator[0]) : RefTuple!T, T...))
700+
{
701+
auto t = _iterator[index];
702+
return mixin("_field[" ~ _iotaArgs!(T.length, "t.expand[", "].unref, ") ~ "]" ~ op ~ "= value");
703+
}
704+
else
705+
return mixin("_field[_iterator[index]]" ~ op ~ "= value");
706+
}
635707
}
636708

637709
void opOpAssign(string op)(ptrdiff_t index)

0 commit comments

Comments
 (0)