www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13087] New: Error: no property 'xyz' for type 'Vec!4'

https://issues.dlang.org/show_bug.cgi?id=13087

          Issue ID: 13087
           Summary: Error: no property 'xyz' for type 'Vec!4'
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: regression
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: edwards.ac gmail.com

Below code compiled int v2.065.0:

void main() {
    auto e = Vec4(5, 3, 3, 1);

    // This worked with dmd_2.065.0-0_amd64
    // but does not work with dmd_2.066.0~b2-0_amd64
    auto x = e.xyz; // Error: no property 'xyz' for type 'Vec!4'
}

alias Vec3 = Vec!3;
alias Vec4 = Vec!4;

struct Vec(int dim) if (3 <= dim && dim <= 4) {

    union {
        float[dim] comps;
        struct {
            float x;
            float y;
            float z;
            static if (4 <= dim) float w;
        }
    }

    alias r = x;
    alias g = y;
    alias b = z;
    static if (4 <= dim) alias a = w;

    static if (dim == 3) {
         safe pure nothrow
        this(float x, float y, float z) {
            this.comps[0] = x;
            this.comps[1] = y;
            this.comps[2] = z;
        }
    }

    static if (dim == 4) {
         safe pure nothrow
        this(float x, float y, float z, float w) {
            this.comps[0] = x;
            this.comps[1] = y;
            this.comps[2] = z;
            this.comps[3] = w;
        }
    }

    auto opDispatch(string components)() const {
        enum string comps_str = components[0] == '_' ? components[1..$] :
components;
        Vec!(comps_str.length) result = void;
        foreach (i; StaticRange!(0, comps_str.length))
            result.comps[i] = _component!(this, comps_str[i]);
        return result;
    }
}

private template _component(alias vec, char c) {
    static      if(c == 'x') alias _component = vec.x;
    else static if(c == 'y') alias _component = vec.y;
    else static if(c == 'z') alias _component = vec.z;
    else static if(c == 'w') alias _component = vec.w;
    else static if(c == 'r') alias _component = vec.r;
    else static if(c == 'g') alias _component = vec.g;
    else static if(c == 'b') alias _component = vec.b;
    else static if(c == 'a') alias _component = vec.a;
    else static if(c == '0') enum typeof(vec.x) _component = 0;
    else static if(c == '1') enum typeof(vec.x) _component = 1;
    else static if(c == '2') enum typeof(vec.x) _component = 2;
    else static assert(0);
}

import std.typecons : TypeTuple;
template StaticRange(int from, int to) if (from <= to) {
    static if (from >= to) {
        alias StaticRange = TypeTuple!();
    } else {
        alias StaticRange = TypeTuple!(from, StaticRange!(from + 1, to));
    }
}

--
Jul 09 2014