Array start index

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Feb 6 15:42:55 PST 2017


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



More information about the Digitalmars-d-learn mailing list