Быстрая векторная структура, которая позволяет [я] и .xyz-операции в D?

Я хотел бы создать векторную структуру в 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

Позже я также хотел бы добавить материал как 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
задан 0scar 23 June 2010 в 00:58
поделиться

4 ответа

В целом это выглядит вполне разумно. Для целей цепочки назначений 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].

}

Обратите внимание, хотя этот псевдоним this сейчас довольно глючит, и вам, вероятно, пока не стоит его использовать, если только вы готовы отправить несколько отчетов об ошибках.

5
ответ дан 13 December 2019 в 22:01
поделиться

Вы можете использовать opDispatch для переключения произвольной глубины. Я также рекомендую создать шаблон для вашей векторной структуры по размеру и типу. Вот моя версия для сравнения: tools.vector (D1, поэтому swizzling немного сложнее).

2
ответ дан 13 December 2019 в 22:01
поделиться

Вы можете использовать операцию с массивом, чтобы скопировать весь массив за один раз в opAssign:

data[] = v[];
2
ответ дан 13 December 2019 в 22:01
поделиться
@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, чтобы иметь массив data[3] в любом случае.

1
ответ дан 13 December 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: