[Issue 9265] New: Nullable fixed-sized array wrapper

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Jan 3 05:25:30 PST 2013


http://d.puremagic.com/issues/show_bug.cgi?id=9265

           Summary: Nullable fixed-sized array wrapper
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: bearophile_hugs at eml.cc


--- Comment #0 from bearophile_hugs at eml.cc 2013-01-03 05:25:28 PST ---
When I use fixed-sized arrays a lot, sometimes I need a nullable version of
them (fixed-sized arrays are allocated in-place, so they often avoid heap
allocations, avoiding the creation of some garbage, reducing the GC pressure
and generally speeding up the code). A "ref" can't be used because it can't be
null.

So I think the normal way to use them in D is this, but the "(*arr)[1]" syntax
is bug-prone and not elegant:


alias TA = immutable(int[5]);
bool foo(TA* arr) {
    if (arr)
        return (*arr)[1] == 20;
    else
        return false;
}
void main() {
    TA a;
    foo(&a);
}



std.typecons.Nullable and std.typecons.NullableRef contain enforce() that
throws and kills inlining.


This simple struct inspired by NullableRef is light, avoids the problem of
NullableRef and allows for a natural syntax for nullable fixed sized arrays:



// Nullable fixed-sized array --------
struct Ptr(T) {
    private T* ptr;

    this(T* ptr_) pure nothrow {
        this.ptr = ptr_;
    }

    bool opCast(T)() const pure nothrow if (is(T == bool)) {
        return ptr !is null;
    }

    @property ref inout(T) get()() inout pure nothrow
    in {
        assert(ptr);
    } body {
        return *ptr;
    }

    alias get this;
}

Ptr!T ptr(T)(ref T x) {
    return typeof(return)(&x);
}

// Example usage ----------

alias TA = immutable(int[5]);

bool foo(Ptr!TA arr=Ptr!TA.init) nothrow {
    if (arr)
        return arr[1] == 20;
    else
        return false;
}

bool foo(typeof(null) _) nothrow {
    return false;
}

void main() {
    assert(!foo());
    assert(!foo(null));
    TA items = [10, 20, 30, 40, 50];
    assert(foo(ptr(items)));
}
//---------------------------------



Unfortunately my benchmarks show that with the current DMD 2.061 the code that
uses such wrapped array is not as efficient as the first program that uses the
pointer to the fixed sized array.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list