2010-06-23 19 views
5

tôi muốn tạo một cấu trúc vector trong D mà làm việc như thế này:Cấu trúc véc tơ nhanh cho phép hoạt động [i] và .xyz trong D?

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

Sau đó tôi cũng muốn thêm thứ như u = v * u vv Nhưng ở trên sẽ làm cho bây giờ.
Đây là cách xa tôi đã đến:

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]; 
    } 
} 

Bây giờ này khá nhiều làm cho nó làm việc như tôi muốn, nhưng tôi cảm thấy rất chắc chắn về nếu điều này là "đúng". Liệu opAssign() có lẽ trả về một số giá trị?

Tôi cũng tự hỏi nếu điều này thực sự nhanh như nó có thể? Tôi đã thử thêm alias data[0] x; v.v. nhưng điều đó không hoạt động. Bất kỳ ý tưởng? Hoặc là "làm thế nào nó được thực hiện"? Có lẽ trình biên dịch đủ thông minh để tìm ra các hàm thích hợp là nhiều hoặc ít bí danh?

Trả lời

5

Nhìn chung, điều này có vẻ khá hợp lý. Đối với mục đích của chuỗi phân công, opAssign nên được cho là trở lại v. Tuy nhiên, trong thực tế điều này thường bị bỏ qua và có thể gây ra một hit hiệu suất (tôi không biết). Không giống như trong D1, bạn có thể trả về các mảng tĩnh từ các hàm trong D2.

Theo như hiệu suất, cách tốt nhất để nghĩ về điều này là ở cấp độ lắp ráp. Giả sử nội tuyến được bật, x() gần như chắc chắn sẽ được gạch chân. Các mảng tĩnh được lưu trữ trực tiếp trong struct mà không cần thêm một lớp indirection. Hướng dẫn return data[0]; sẽ làm cho trình biên dịch tạo mã để đọc từ một bù đắp từ đầu của cấu trúc. Sự bù đắp này sẽ được biết tại thời gian biên dịch. Do đó, rất có thể gọi x() sẽ tạo chính xác các hướng dẫn lắp ráp giống như nếu x thực sự là một biến thành viên công khai.

Một khác khả năng, tuy nhiên, sẽ được sử dụng một công đoàn vô danh và struct:

struct vec3f 
{ 
    union { 
     float[3] vec; 

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

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

} 

Lưu ý, dù rằng alias this khá buggy ngay bây giờ, và có lẽ bạn không nên sử dụng nó nhưng trừ khi bạn' sẵn sàng gửi một số báo cáo lỗi.

2

Bạn có thể sử dụng opDispatch để điều chỉnh độ sâu tùy ý. Tôi cũng khuyên bạn nên templating vector của bạn struct về kích thước và loại. Đây là phiên bản của tôi để so sánh: tools.vector (D1, do đó, swizzling là một chút cồng kềnh hơn).

+1

+1, tôi đã có ý tưởng tương tự cho sự gian lận với opDispatch. Tôi vẫn đang ở giai đoạn đầu của D, vì vậy giải pháp của tôi có lẽ không tốt bằng nó. Các công cụ biên dịch thời gian bạn có thể làm là tâm-boggling, mặc dù! – shambulator

2

Bạn có thể sử dụng một hoạt động mảng đến sao chép toàn bộ mảng trong một shot trong 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]; } 
    } 

Tại sao tính?

Tôi khuyên bạn nên xóa các dòng này và tạo các trường công khai x, y và z. Điều này cũng sẽ cải thiện hiệu suất ở chế độ không trực tuyến. Bạn có thể sử dụng union để có một mảng dữ liệu [3].

Các vấn đề liên quan