On 02/06/2017 03:00 PM, Bastiaan Veelo wrote:

> In "Numerical Recipes in C", section 1.2, Press et al. propose an easy
> solution using an offset pointer:
>
> float b[4], *bb;
> bb = b - 1;
>
> Thus bb[1] through bb[4] all exist, no space is wasted nor is there a
> run-time overhead.
>
> I have tried to adapt the internals of my struct to Press' approach, but
> it seems to me it is not that easy in D -- or I'm just not proficient
> enough. Can someone here show me how that could be done?

struct StaticArray(T, ptrdiff_t first, ptrdiff_t last) {
    T[last - first + 1] _payload;

If the static array has to be a member like that (as opposed to a dynamic one), you need an extra member:

    T* _ptr;

Because structs cannot have default constructors, you need an init() function to establish the invariant:

    void init() {
        this._ptr = _payload.ptr - first;
    }

Of course, that relies on the fact that _payload.ptr - first is a valid address to hold in a pointer.

[OT]:
    // Commented-out as it seems dangerous because _payload does not
    // have the same semantics as StaticArray.
    //
    //  alias _payload this;

Which means, you would implement length() yourself:

    size_t length() {
        return _payload.length;
    }

Then you use _ptr when indexing:

    // Support e = arr[5];
    ref T opIndex(ptrdiff_t index) {
        assert(index >= first);
        assert(index <= last);
        return *(_ptr + index);
    }

Ali

Reply via email to