2010-06-23 42 views
5

我想创造一个d矢量结构是这样工作的:在D中允许[i]和.xyz-operations的快速向量结构?

vec u, v; 
vec w = [2,6,8]; 
v.x = 9; // Sets x 
v[1] = w.y; // Sets y 
u = v; // Should copy data 

后来我也想补充的东西一样u = v * u等,但上述将为现在要做的。
这是多远我来:

struct vec3f 
{ 
    float[3] data; 
    alias data this; 
    @property 
    { 
     float x(float f) { return data[0] = f; } 
     float y(float f) { return data[1] = f; } 
     float z(float f) { return data[2] = f; } 
     float x() { return data[0]; } 
     float y() { return data[1]; } 
     float z() { return data[2]; } 
    } 
    void opAssign(float[3] v) 
    { 
     data[0] = v[0]; 
     data[1] = v[1]; 
     data[2] = v[2]; 
    } 
} 

现在,这几乎使得它的工作就像我想要的,但我觉得,如果这是“正确的”非常不确定。 opAssign()是否应该返回一些值?

我也想知道这是否真的如此快?我试过添加alias data[0] x;等,但这不起作用。有任何想法吗?或者这是“它是如何完成的”?也许编译器足够聪明,弄清楚propery函数是或多或少的别名?

回答

5

总的来说,这看起来很合理。为了赋值链接的目的,opAssign应该可以返回v,但实际上这经常被忽略,并可能导致性能下降(我不知道)。与D1不同,您可以从D2中的函数返回静态数组。

就性能而言,考虑这一点的最佳方式是在装配层面。假设启用内联,x()几乎肯定会内联。静态数组直接存储在结构中,没有额外的间接层。指令return data[0];将导致编译器生成代码以从结构开头的偏移量读取。这个偏移量将在编译时知道。因此,最有可能调用x()将生成完全相同的汇编指令,就好像x实际上是一个公共成员变量。

另外一个可能性,不过,是使用匿名联合和结构:

struct vec3f 
{ 
    union { 
     float[3] vec; 

     struct { 
      float x; 
      float y; 
      float z; 
     } 
    } 

    alias vec this; // For assignment of a float[3]. 

} 

不过请注意,alias this是相当越野车,现在,你可能不应该用它了,除非你”重新愿意提交一些错误报告。

2

您可以使用opDispatch来调整任意深度。我也建议在大小和类型上模板化你的矢量结构。这是我的版本比较:tools.vector(D1,所以搅拌更麻烦一点)。

+1

+1,我有与opDispatch相同的想法。我仍然处于D的早期阶段,所以我的解决方案可能不如以前那么好。虽然编译时你可以做的事情是令人难以置信的! – shambulator 2010-07-28 22:46:47

2

您可以使用数组操作整个阵列中的一个镜头复制opAssign:

data[] = v[]; 
1
@property 
    { 
     float x(float f) { return data[0] = f; } 
     float y(float f) { return data[1] = f; } 
     float z(float f) { return data[2] = f; } 
     float x() { return data[0]; } 
     float y() { return data[1]; } 
     float z() { return data[2]; } 
    } 

为什么属性?

我会建议删除这些行,并使x,y和z公共字段。 这也将改善非内联模式下的性能。无论如何,你可以使用union有一个数据[3]数组。