Nullable fixed sized arrays
bearophile
bearophileHUGS at lycos.com
Thu Dec 27 02:39:56 PST 2012
In some situations I need to pass to a function a "nullable"
fixed sized array. This happens if you use fixed-sized arrays a
lot. So:
- You can't use ref, because it can't be null.
- Passing to the function a raw pointer and then using it as
(*arr)[x] doesn't look nice.
- NullableRef is a solutions, but it contain enforces that kill
inlining and make the code slower, so it's not usable for
performance-sensitive code (unless you turn the nullable into a
regular pointer inside the function, but this makes using
NullableRef much less useful).
This solution is derived by NullableRef:
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)));
}
The usage in foo() is clean.
I've created a kind of benchmark and unfortunately I've seen that
with DMD (compiling with -O -release -inline -noboundscheck) this
very light wrapping is not as efficient as a pointer to
fixed-sized array :-(
(But it's better than NullableRef).
Bye,
bearophile
More information about the Digitalmars-d-learn
mailing list