Thread overview
casting with preserving attributes
May 22, 2013
Jack Applegame
May 22, 2013
Jack Applegame
May 22, 2013
bearophile
May 22, 2013
Jack Applegame
May 22, 2013
bearophile
May 22, 2013
Hello.

I need a template for casting arrays to another type without changing const and immutable attributes:

template ByteType(T) {
  // some magic
}

const(int)[] ca;
immutable(short)[] is;
long[] ml;

static assert(is(ByteType!ca == const(byte)[]));
static assert(is(ByteType!is == immutable(byte)[]));
static assert(is(ByteType!ml == byte[]));

What kind of template magic I should use?
May 22, 2013
I found awkward solution:

template ByteType(alias t) {
  alias typeof(t) T;
  static if(is(ElementType!T == const)) alias const(byte)[] ByteType;
  else static if(is(ElementType!T == immutable)) alias immutable(byte)[] ByteType;
  else alias byte[] ByteType;
}

May 22, 2013
Jack Applegame:

> I found awkward solution:
>
> template ByteType(alias t) {
>   alias typeof(t) T;
>   static if(is(ElementType!T == const)) alias const(byte)[] ByteType;
>   else static if(is(ElementType!T == immutable)) alias immutable(byte)[] ByteType;
>   else alias byte[] ByteType;
> }

I think that's essentially the right solution. I suggest to generalize it a bit, removing the byte from its insides, and making it a template argument. I think "shared" is missing.

Bye,
bearophile
May 22, 2013
On Wednesday, 22 May 2013 at 13:01:26 UTC, bearophile wrote:
> I think that's essentially the right solution. I suggest to generalize it a bit, removing the byte from its insides, and making it a template argument. I think "shared" is missing.
Yes.

Finally http://dpaste.1azy.net/fc503331
May 22, 2013
Jack Applegame:

> Finally http://dpaste.1azy.net/fc503331

I suggest to use indents composed by 4 spaces.
Generally in D we use template constraints, instead of static ifs with a nice error message...
In such complex situations I also suggest to add braces.

Something like this:


auto castElementType(T = byte, F)(ref F from)
if (isArray!F) {
    alias E = typeof(from[0]);

    static if(is(E == const)) {
        return cast(const(Unqual!T)[])from;
    } else static if(is(E == immutable)) {
        return cast(immutable(Unqual!T)[])from;
    } else static if(is(E == shared)) {
        return cast(shared(Unqual!T)[])from;
    } else {
        return cast(Unqual!T[])from;
    }
}


Bye,
bearophile