digitalmars.D.learn - Nullable fixed sized arrays
- bearophile (56/56) Dec 27 2012 In some situations I need to pass to a function a "nullable"
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
Dec 27 2012