Bug 13087 – Error: no property 'xyz' for type 'Vec!4'
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-07-10T05:53:00Z
Last change time
2014-08-22T08:04:18Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
edwards.ac
Comments
Comment #0 by edwards.ac — 2014-07-10T05:53:38Z
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));
}
}
Comment #1 by k.hara.pg — 2014-07-10T06:56:23Z
Reduced test case:
struct Vec
{
int x;
void foo() const // const is necessary
{
auto n = component!(this, 'x');
}
}
template component(alias vec, char c)
{
alias component = vec.x;
}