Thread overview
Templated vec
Sep 25, 2010
bearophile
Sep 25, 2010
Simen kjaeraas
Sep 25, 2010
bearophile
Sep 25, 2010
bearophile
September 25, 2010
This is an array struct template, this code compiles:

struct Vec(size_t N) {
    void opBinary(string op:"~", size_t M)(int[M]) {}
}
void main() {
    Vec!2 a1;
    int[3] a2;
    a1 ~ a2; // OK
}



But this code doesn't compile:

struct Vec(size_t N) {
    void opBinary(string op:"~", size_t M)(Vec!M) {}
}
void main() {
    Vec!2 a1;
    Vec!3 a2;
    a1 ~ a2; // line 7, Error
}


DMD 2.049 shows:
test.d(7): Error: cannot implicitly convert expression (a2) of type Vec!(3) to Vec!(M)

Can you show me how to fix the second program?

Bye and thank you,
bearophile
September 25, 2010
bearophile <bearophileHUGS@lycos.com> wrote:

> Can you show me how to fix the second program?

This is issue #3467 - Non-int integral template parameters not correctly propagated

The solution is to use int instead of size_t:

struct Vec(int N) {
    void opBinary(string op:"~", int M)(Vec!M) {}
}
void main() {
    Vec!2 a1;
    Vec!3 a2;
    a1 ~ a2; // line 7, Error
}

-- 
Simen
September 25, 2010
This version works, but it requires a hidden field with distinct name (and no gensym at compile time is available). Do you know a better solution that avoids the need for the distinct hidden field?


struct Vec(size_t N) {
    enum size_t _hiddenVecLength = N;
    void opBinary(string op:"~", T)(T) if (IsVec!T) {}
}
struct Fake(size_t N) {
    enum size_t _hiddenVecLength = N;
}
template IsVec(T) {
    enum bool IsVec = is(typeof(T._hiddenVecLength) == size_t)
                      /* && is(T == Vec!(T._hiddenVecLength)) */ ;
}
void main() {
    Vec!2 a1;
    Vec!3 a2;
    a1 ~ a2;
    Fake!3 f;
    a1 ~ f; // bug
}

Bye,
bearophile
September 25, 2010
Simen kjaeraas:
> This is issue #3467 - Non-int integral template parameters not correctly
> propagated
> The solution is to use int instead of size_t:

Thank you! :-)

I'll add a template constraint to be sure M it's positive:
void opBinary(string op:"~", int M)(Vec!M) if (M >= 0) {}

Bye,
bearophile