struct Foo {
    Bars bars;
    ...
}

struct Foos {
    Foo[] arr;
    Foo opIndex (size_t idx) { return arr[idx]; }
    ...
}

struct Bar {
    // No Car[] cars;
    ...
}

struct Bars {
    Bar[] arr;
    Bar opIndex (size_t idx) { return arr[idx]; }
    ...
}

struct Car {
    ...
}

Foos foos;
Foo foo = foos[1];                  // Works
Bar bar = foos[1].bars[2];          // Works
Car car = foos[1].bars[2].cars[3];  // Desired abstraction.

For any Bar there are some Cars, but Bar doesn't hold any Cars. In other words, there could be a function Car cars (Bar bar, size_t idx) { ... }, but that would be called with parens;

Car car = foos[i].bars[j].cars(k);

which would be inconsistent and confusing. Defining

struct Cars {
    Car opIndex (Bar bar, size_t idx) {}
}

and

struct Bar {
    Cars cars;
    ...
}

doesn't enable chaining and then would have to be used like this, AFAIK:

Car car = cars[foos[i].bars[j], k];

Which is out of the question. Any suggestions to achieve the desired abstraction in a clean manner?

Reply via email to