mir-algorithm icon indicating copy to clipboard operation
mir-algorithm copied to clipboard

const conversion with labels

Open jmh530 opened this issue 1 year ago • 4 comments

There seems to be some weird behavior when you have a function that takes a slice with a const(T)* iterator and try to handle cases with labels. The errors I get as it is is that some of these match multiple functions for reasons that don't quite make sense. I know there's some part of the mir_slice code that converts things to const, but I've never really dug into it to understand how it works.

The code below doesn't have errors when you replace the const(T)* with T*. Alternately, if you replace the int*s with const(int)*s, then the errors go away.

/+dub.sdl:
dependency "mir-algorithm" version="*"
+/


import mir.ndslice.slice;
import mir.ndslice.allocation;
import std.stdio: writeln;


void foo(T)(Slice!(const(T)*, 2u, Contiguous) a)
{
    writeln(typeid(typeof(a)));
    writeln("here0");
}

void foo(T)(Slice!(const(T)*, 2u, Contiguous, int*) a)
{
    writeln(typeid(typeof(a)));
    writeln("here1");
}

void foo(T)(Slice!(const(T)*, 2u, Contiguous, int*, int*) a)
{
    writeln(typeid(typeof(a)));
    writeln("here2");
}

void main()
{
    auto X = slice!double(3, 3);
    auto X1 = slice!(double, int)(3, 3);
    auto X2 = slice!(double, int, int)(3, 3);

    writeln(typeid(typeof(X)));
    foo(X);
    writeln(typeid(typeof(X1)));
    foo(X1); //error
    writeln(typeid(typeof(X2)));
    foo(X2); //error

    writeln("done");
}

jmh530 avatar May 23 '24 17:05 jmh530

Anyway, the consequence of this is that it can be hard to write a function like below that works generically with labels and const T pointers.

void foo(T, Labels...)(Slice!(const(T)*, 2u, Contiguous, Labels) a) {}

jmh530 avatar May 23 '24 17:05 jmh530

The lables almost not implemented.

9il avatar May 23 '24 18:05 9il

Mit uses alias this on toConst. Maybe updating toConst could help

9il avatar May 23 '24 18:05 9il

@9il After looking at it for a bit, it is starting to make a bit more sense why you did it this way. The idea is to make the whole thing const, including both values and labels.

The only thing that really jumps out is that the alias toConst this only applies for when the type is not constant. Here: static if (!is(Slice!(const(Unqual!(PointerTarget!Iterator))*, N, kind) == This)) This only considers the case where the Iterator is const. What if the iterator is const, but the labels aren't?

And for whatever reason, this doesn't work but would make my life a lot easier if you could void foo(T, Labels...)(Slice!(const(T)*, 2u, Contiguous, staticMap!(ConstOfUnqualOfPointerTarget, Labels)) a)

You instead have to do something like:

void foo(T)(Slice!(const(T)*, 2u, Contiguous) a) {}
void foo(T, Label1)(Slice!(const(T)*, 2u, Contiguous, const(Label1)*) a) {}
void foo(T, Label1, Label2)(Slice!(const(T)*, 2u, Contiguous, const(Label1)*, const(Label2)*) a) {}

jmh530 avatar May 23 '24 20:05 jmh530