From 821ccc907b303b2cb2da85970768a742e3b5da83 Mon Sep 17 00:00:00 2001 From: Ilya Yaroshenko Date: Sun, 16 Oct 2016 17:30:34 +0200 Subject: [PATCH] Implicit cast to const slices in case of underlaying range is a pointer. --- std/experimental/ndslice/slice.d | 86 +++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/std/experimental/ndslice/slice.d b/std/experimental/ndslice/slice.d index 5b0bc881f30..63972de00fe 100644 --- a/std/experimental/ndslice/slice.d +++ b/std/experimental/ndslice/slice.d @@ -1366,6 +1366,88 @@ struct Slice(size_t _N, _Range) assert(slice.byElement.equal(only(1, 99, 5, 6))); } + static if (isPointer!PureRange) + { + static if (NSeq.length == 1) + private alias ConstThis = Slice!(N, const(Unqual!DeepElemType)*); + else + private alias ConstThis = Slice!(N, Range.ConstThis); + + static if (!is(ConstThis == This)) + { + /++ + Implicit cast to const slices in case of underlaying range is a pointer. + +/ + ref ConstThis toConst() const @trusted pure nothrow @nogc + { + pragma(inline, true); + return *cast(ConstThis*) &this; + } + + /// ditto + alias toConst this; + } + } + + static if (doUnittest) + /// + unittest + { + Slice!(2, double*) nn; + Slice!(2, immutable(double)*) ni; + Slice!(2, const(double)*) nc; + + const Slice!(2, double*) cn; + const Slice!(2, immutable(double)*) ci; + const Slice!(2, const(double)*) cc; + + immutable Slice!(2, double*) in_; + immutable Slice!(2, immutable(double)*) ii; + immutable Slice!(2, const(double)*) ic; + + nc = nc; nc = cn; nc = in_; + nc = nc; nc = cc; nc = ic; + nc = ni; nc = ci; nc = ii; + + void fun(size_t N, T)(Slice!(N, const(T)*) sl) + { + //... + } + + fun(nn); fun(cn); fun(in_); + fun(nc); fun(cc); fun(ic); + fun(ni); fun(ci); fun(ii); + } + + static if (doUnittest) + unittest + { + Slice!(2, Slice!(2, double*)) nn; + Slice!(2, Slice!(2, immutable(double)*)) ni; + Slice!(2, Slice!(2, const(double)*)) nc; + + const Slice!(2, Slice!(2, double*)) cn; + const Slice!(2, Slice!(2, immutable(double)*)) ci; + const Slice!(2, Slice!(2, const(double)*)) cc; + + immutable Slice!(2, Slice!(2, double*) )in_; + immutable Slice!(2, Slice!(2, immutable(double)*)) ii; + immutable Slice!(2, Slice!(2, const(double)*)) ic; + + nc = nn; nc = cn; nc = in_; + nc = nc; nc = cc; nc = ic; + nc = ni; nc = ci; nc = ii; + + void fun(size_t N, size_t M, T)(Slice!(N, Slice!(M, const(T)*)) sl) + { + //... + } + + fun(nn); fun(cn); fun(in_); + fun(nc); fun(cc); fun(ic); + fun(ni); fun(ci); fun(ii); + } + /++ Returns: Pointer to the first element of a slice if slice is defined as `Slice!(N, T*)` @@ -2019,7 +2101,7 @@ struct Slice(size_t _N, _Range) do { static if (is(E == Unqual!ElemType)) - u.elems[rem] = r.front; + u.elems[rem] = cast() r.front; else static if (__traits(compiles, r.front.toHash)) u.elems[rem] = r.front.toHash; @@ -2065,7 +2147,7 @@ struct Slice(size_t _N, _Range) foreach (k; Iota!(0, K)) { static if (is(E == Unqual!ElemType)) - u.elems[k] = r.front; + u.elems[k] = cast() r.front; else static if (__traits(compiles, r.front.toHash)) u.elems[k] = r.front.toHash;