@@ -652,6 +652,11 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
652652 && Filter! (isIndex, Slices).length < Slices.length
653653 && allSatisfy! (templateOr! (isIndex, is_Slice), Slices);
654654
655+ enum isIndexSlice (Indexes... ) =
656+ Indexes.length
657+ && Indexes.length <= packs[0 ]
658+ && allSatisfy! (isIndex, Indexes);
659+
655660 enum isFullPureSlice (Slices... ) =
656661 Slices.length == 0
657662 || Slices.length == packs[0 ]
@@ -752,80 +757,138 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
752757 static if (isPointer! Iterator)
753758 {
754759 private alias ConstThis = Slice! (kind, packs, const (Unqual! (PointerTarget! Iterator))* );
760+ private alias ImmutableThis = Slice! (kind, packs, immutable (Unqual! (PointerTarget! Iterator))* );
755761
756- static if (! is (ConstThis == This))
762+ /+ +
763+ Cast to const and immutable slices in case of underlaying range is a pointer.
764+ +/
765+ ref toImmutable ()() immutable @trusted pure nothrow @nogc
757766 {
758- /+ +
759- Implicit cast to const slices in case of underlaying range is a pointer.
760- +/
761- ref ConstThis toConst ()() const @trusted pure nothrow @nogc
762- {
763- pragma (inline, true );
764- return * cast (ConstThis* ) &this ;
765- }
766-
767- // / ditto
768- alias toConst this ;
767+ pragma (inline, true );
768+ return * cast (Slice! (kind, packs, immutable (Unqual! (PointerTarget! Iterator))* )* ) &this ;
769769 }
770- }
771770
772- static if (doUnittest)
773- // /
774- unittest
775- {
776- Slice! (Universal, [2 ], double * ) nn;
777- Slice! (Universal, [2 ], immutable (double )* ) ni;
778- Slice! (Universal, [2 ], const (double )* ) nc;
771+ // / ditto
772+ ref toConst ()() const @trusted pure nothrow @nogc
773+ {
774+ pragma (inline, true );
775+ return * cast (Slice! (kind, packs, const (Unqual! (PointerTarget! Iterator))* )* ) &this ;
776+ }
779777
780- const Slice! (Universal, [ 2 ], double * ) cn;
781- const Slice ! (Universal, [ 2 ], immutable ( double ) * ) ci;
782- const Slice ! (Universal, [ 2 ], const ( double ) * ) cc ;
778+ static if ( ! is ( Slice! (kind, packs, const (Unqual ! (PointerTarget ! Iterator)) * ) == This))
779+ // / ditto
780+ alias toConst this ;
783781
784- immutable Slice! (Universal, [2 ], double * ) in_;
785- immutable Slice! (Universal, [2 ], immutable (double )* ) ii;
786- immutable Slice! (Universal, [2 ], const (double )* ) ic;
782+ // / ditto
783+ auto ref opIndex (Indexes... )(Indexes indexes) const @trusted
784+ if (isPureSlice! Indexes || isIndexedSlice! Indexes || isIndexSlice! Indexes)
785+ {
786+ return (* cast (Slice! (kind, packs, const (PointerTarget! Iterator)* )* ) &this )[indexes];
787+ }
787788
788- nc = nc; nc = cn; nc = in_;
789- nc = nc; nc = cc; nc = ic;
790- nc = ni; nc = ci; nc = ii;
789+ // / ditto
790+ auto ref opIndex (Indexes... )(Indexes indexes) immutable @trusted
791+ if (isPureSlice! Indexes || isIndexedSlice! Indexes || isIndexSlice! Indexes)
792+ {
793+ return (* cast (Slice! (kind, packs, immutable (PointerTarget! Iterator)* )* ) &this )[indexes];
794+ }
791795
792- void fun (size_t [] packs, T)(Slice! (Universal, packs, const (T)* ) sl)
796+ static if (doUnittest)
797+ // /
798+ unittest
793799 {
794- // ...
800+ static struct Foo
801+ {
802+ ContiguousSlice! (1 , int ) bar;
803+
804+ int get (size_t i) immutable
805+ {
806+ return bar[i];
807+ }
808+
809+ int get (size_t i) const
810+ {
811+ return bar[i];
812+ }
813+
814+ int get (size_t i) inout
815+ {
816+ return bar[i];
817+ }
818+ }
795819 }
796820
797- fun(nn); fun (cn); fun(in_);
798- fun(nc); fun (cc); fun(ic);
799- fun(ni); fun (ci); fun(ii);
800- }
821+ static if (doUnittest)
822+ // /
823+ unittest
824+ {
825+ Slice! (Universal, [2 ], double * ) nn;
826+ Slice! (Universal, [2 ], immutable (double )* ) ni;
827+ Slice! (Universal, [2 ], const (double )* ) nc;
801828
802- static if (doUnittest)
803- unittest
804- {
805- Slice! (Universal, [2 , 2 ], double * ) nn;
806- Slice! (Universal, [2 , 2 ], immutable (double )* ) ni;
807- Slice! (Universal, [2 , 2 ], const (double )* ) nc;
829+ const Slice! (Universal, [2 ], double * ) cn;
830+ const Slice! (Universal, [2 ], immutable (double )* ) ci;
831+ const Slice! (Universal, [2 ], const (double )* ) cc;
832+
833+ immutable Slice! (Universal, [2 ], double * ) in_;
834+ immutable Slice! (Universal, [2 ], immutable (double )* ) ii;
835+ immutable Slice! (Universal, [2 ], const (double )* ) ic;
836+
837+ nc = nc; nc = cn; nc = in_;
838+ nc = nc; nc = cc; nc = ic;
839+ nc = ni; nc = ci; nc = ii;
808840
809- const Slice! (Universal, [2 , 2 ], double * ) cn;
810- const Slice! (Universal, [2 , 2 ], immutable (double )* ) ci;
811- const Slice! (Universal, [2 , 2 ], const (double )* ) cc;
841+ void fun (size_t [] packs, T)(Slice! (Universal, packs, const (T)* ) sl)
842+ {
843+ // ...
844+ }
812845
813- immutable Slice ! (Universal, [ 2 , 2 ], double * ) in_;
814- immutable Slice ! (Universal, [ 2 , 2 ], immutable ( double ) * ) ii ;
815- immutable Slice ! (Universal, [ 2 , 2 ], const ( double ) * ) ic ;
846+ fun(nn); fun (cn); fun( in_) ;
847+ fun(nc); fun (cc); fun(ic) ;
848+ fun(ni); fun (ci); fun(ii) ;
816849
817- nc = nc; nc = cn; nc = in_ ;
818- nc = nc; nc = cc; nc = ic ;
819- nc = ni; nc = ci; nc = ii ;
850+ static assert ( is ( typeof (cn[]) == typeof (nc))) ;
851+ static assert ( is ( typeof (ci[]) == typeof (ni))) ;
852+ static assert ( is ( typeof (cc[]) == typeof (nc))) ;
820853
821- void fun (size_t [] packs, T)(Slice! (Universal, packs, const (T)* ) sl)
822- {
823- // ...
854+ static assert (is (typeof (in_[]) == typeof (ni)));
855+ static assert (is (typeof (ii[]) == typeof (ni)));
856+ static assert (is (typeof (ic[]) == typeof (ni)));
857+
858+ ni = ci[];
859+ ni = in_[];
860+ ni = ii[];
861+ ni = ic[];
824862 }
825863
826- fun(nn); fun (cn); fun(in_);
827- fun(nc); fun (cc); fun(ic);
828- fun(ni); fun (ci); fun(ii);
864+ static if (doUnittest)
865+ unittest
866+ {
867+ Slice! (Universal, [2 , 2 ], double * ) nn;
868+ Slice! (Universal, [2 , 2 ], immutable (double )* ) ni;
869+ Slice! (Universal, [2 , 2 ], const (double )* ) nc;
870+
871+ const Slice! (Universal, [2 , 2 ], double * ) cn;
872+ const Slice! (Universal, [2 , 2 ], immutable (double )* ) ci;
873+ const Slice! (Universal, [2 , 2 ], const (double )* ) cc;
874+
875+ immutable Slice! (Universal, [2 , 2 ], double * ) in_;
876+ immutable Slice! (Universal, [2 , 2 ], immutable (double )* ) ii;
877+ immutable Slice! (Universal, [2 , 2 ], const (double )* ) ic;
878+
879+ nc = nc; nc = cn; nc = in_;
880+ nc = nc; nc = cc; nc = ic;
881+ nc = ni; nc = ci; nc = ii;
882+
883+ void fun (size_t [] packs, T)(Slice! (Universal, packs, const (T)* ) sl)
884+ {
885+ // ...
886+ }
887+
888+ fun(nn); fun (cn); fun(in_);
889+ fun(nc); fun (cc); fun(ic);
890+ fun(ni); fun (ci); fun(ii);
891+ }
829892 }
830893
831894 /+ +
@@ -1672,7 +1735,7 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
16721735 $(BOLD Fully defined index)
16731736 +/
16741737 auto ref opIndex (Indexes... )(Indexes indexes) @safe
1675- if (Indexes.length && Indexes.length <= packs[ 0 ] && allSatisfy ! (isIndex, Indexes) )
1738+ if (isIndexSlice ! Indexes)
16761739 {
16771740 return this .opIndex ! (indexes.length)([indexes]);
16781741 }
@@ -2042,7 +2105,7 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
20422105 void opIndexAssign (T, Slices... )(T[] value, Slices slices) @safe
20432106 if (isFullPureSlice! Slices
20442107 && ! isDynamicArray! DeepElemType
2045- && DynamicArrayDimensionsCount! (T[]) <= ReturnType ! ( opIndex ! Slices ).N)
2108+ && DynamicArrayDimensionsCount! (T[]) <= typeof ( this [slices] ).N)
20462109 {
20472110 this [slices].opIndexOpAssignImplArray! " " (value);
20482111 }
@@ -2332,7 +2395,7 @@ struct Slice(SliceKind kind, size_t[] packs, Iterator)
23322395 @safe
23332396 if (isFullPureSlice! Slices
23342397 && ! isDynamicArray! DeepElemType
2335- && DynamicArrayDimensionsCount! (T[]) <= ReturnType ! ( opIndex ! Slices ).N)
2398+ && DynamicArrayDimensionsCount! (T[]) <= typeof ( this [slices] ).N)
23362399 {
23372400 this [slices].opIndexOpAssignImplArray! op(value);
23382401 }
0 commit comments