www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Swap furthest element type of an array

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I just had a need for this but couldn't find it in Phobos:

import std.stdio;
import std.traits;
import std.range;

template SwapElem(Arr, Type)
{
    static if (isArray!(ElementType!Arr))
    {
        static if (isDynamicArray!Arr)
            alias SwapElem!(ElementType!Arr, Type)[] SwapElem;
        else
            alias SwapElem!(ElementType!Arr, Type)[Arr.length] SwapElem;
    }
    else
    {
        static if (isDynamicArray!Arr)
            alias Type[] SwapElem;
        else
            alias Type[Arr.length] SwapElem;
    }
}

void main()
{
    alias int[2][1] IntArr;
    alias SwapElem!(IntArr, float) FloatArr;
    writeln(typeid(FloatArr));  // float[2][1]
}

It doesn't handle complex declarations like "int[2]*[1]". It seems
hard to do since I can't pass a naked pointer as a type to a template.
Some other clever tricks would have to be used here. But it's a worthy
start. If you can improve it feel free to do so. :)
Jun 18 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/18/2012 06:29 PM, Andrej Mitrovic wrote:
 I just had a need for this but couldn't find it in Phobos:

 import std.stdio;
 import std.traits;
 import std.range;

 template SwapElem(Arr, Type)
 {
      static if (isArray!(ElementType!Arr))
      {
          static if (isDynamicArray!Arr)
              alias SwapElem!(ElementType!Arr, Type)[] SwapElem;
          else
              alias SwapElem!(ElementType!Arr, Type)[Arr.length] SwapElem;
      }
      else
      {
          static if (isDynamicArray!Arr)
              alias Type[] SwapElem;
          else
              alias Type[Arr.length] SwapElem;
      }
 }

 void main()
 {
      alias int[2][1] IntArr;
      alias SwapElem!(IntArr, float) FloatArr;
      writeln(typeid(FloatArr));  // float[2][1]
 }

 It doesn't handle complex declarations like "int[2]*[1]". It seems
 hard to do since I can't pass a naked pointer as a type to a template.
 Some other clever tricks would have to be used here. But it's a worthy
 start. If you can improve it feel free to do so. :)

template SwapElem(A, E){ static if(is(A X:X[N],size_t N)) alias SwapElem!(X,E)[N] R; else static if(is(A X:X[])) alias SwapElem!(X,E)[] R; else static if(is(A X:X*)) alias SwapElem!(X,E)* R; else alias E R; alias R SwapElem; } pragma(msg, SwapElem!(int[]*[3][]*[2][]*[1][], float));
Jun 18 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/19/2012 12:01 AM, Andrej Mitrovic wrote:
 On 6/18/12, Timon Gehr<timon.gehr gmx.ch>  wrote:
 template SwapElem(A, E){
       static if(is(A X:X[N],size_t N)) alias SwapElem!(X,E)[N] R;
       else static if(is(A X:X[])) alias SwapElem!(X,E)[] R;
       else static if(is(A X:X*)) alias SwapElem!(X,E)* R;
       else alias E R;
       alias R SwapElem;
 }

 pragma(msg, SwapElem!(int[]*[3][]*[2][]*[1][], float));

Niiiice! Did you just come up with this right now? :D

Indeed. If you are interested, I'll make it work with qualified types as well. =)
Jun 18 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/18/12, Timon Gehr <timon.gehr gmx.ch> wrote:
 template SwapElem(A, E){
      static if(is(A X:X[N],size_t N)) alias SwapElem!(X,E)[N] R;
      else static if(is(A X:X[])) alias SwapElem!(X,E)[] R;
      else static if(is(A X:X*)) alias SwapElem!(X,E)* R;
      else alias E R;
      alias R SwapElem;
 }

 pragma(msg, SwapElem!(int[]*[3][]*[2][]*[1][], float));

Niiiice! Did you just come up with this right now? :D
Jun 18 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/19/12, Timon Gehr <timon.gehr gmx.ch> wrote:
 Indeed. If you are interested, I'll make it work with qualified types as
 well. =)

I thought it already does?
Jun 18 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/19/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 6/19/12, Timon Gehr <timon.gehr gmx.ch> wrote:
 Indeed. If you are interested, I'll make it work with qualified types as
 well. =)

I thought it already does?

Oh you meant to *keep* the qualifier, yeah.
Jun 18 2012
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/19/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 6/19/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 6/19/12, Timon Gehr <timon.gehr gmx.ch> wrote:
 Indeed. If you are interested, I'll make it work with qualified types as
 well. =)

I thought it already does?

Oh you meant to *keep* the qualifier, yeah.

Well since you conveniently use the "R" alias, I think all that's needed is this at the end: static if (is(A T == const)) alias const(R) SwapElem; else alias R SwapElem;
Jun 18 2012