1 module libd.memory.ptr; 2 3 // "NotNull" is deemed "uninitialised" if it's value is null. Think of it like "undefined" from JS. 4 5 struct NotNullPtr(T, string Tag_ = "default") 6 { 7 static immutable Tag = Tag_; 8 alias ptr this; 9 T* ptr; 10 11 auto opAssign()(T* ptr) 12 { 13 assert(ptr !is null, "Pointer is null."); 14 this.ptr = ptr; 15 return this; 16 } 17 18 auto opAssign()(MaybeNullPtr!(T, Tag) ptr) 19 { 20 assert(ptr !is null, "Pointer is null."); 21 this.ptr = ptr; 22 return this; 23 } 24 25 auto opAssign(string Tag2)(MaybeNullPtr!(T, Tag2) ptr) 26 if(Tag2 != Tag) 27 { 28 static assert(false, "Cannot implicitly assign from pointer with different tag."); 29 } 30 } 31 32 struct MaybeNullPtr(T, string Tag_ = "default") 33 { 34 static immutable Tag = Tag_; 35 alias ptr this; 36 T* ptr; 37 } 38 39 struct NotNullSlice(T, string Tag_ = "default") 40 { 41 static immutable Tag = Tag_; 42 alias slice this; 43 T[] slice; 44 45 auto opAssign()(T[] value) 46 { 47 assert(value !is null, "Slice is null."); 48 this.slice = value; 49 return this; 50 } 51 52 auto opAssign()(MaybeNullSlice!(T, Tag) slice) 53 { 54 assert(slice !is null, "Slice is null."); 55 this.slice = slice.slice; 56 return this; 57 } 58 59 auto opAssign(string Tag2)(MaybeNullSlice!(T, Tag2) slice) 60 if(Tag2 != Tag) 61 { 62 static assert(false, "Cannot implicitly assign from slice with different tag."); 63 } 64 } 65 66 struct MaybeNullSlice(T, string Tag_ = "default") 67 { 68 static immutable Tag = Tag_; 69 alias slice this; 70 T[] slice; 71 } 72 73 @safe @nogc nothrow pure: 74 // This code is mostly write-once update-never due to its simple nature, so I don't give a damn about making it readable. 75 MaybeNullPtr !(T, Tag) maybeNull(string Tag, T)(T* ptr) { return typeof(return)(ptr); } 76 MaybeNullPtr !(T, Tag) maybeNull(string Tag, T)(NotNullPtr!(T, Tag) ptr) { return typeof(return)(ptr); } 77 MaybeNullSlice!(T, Tag) maybeNull(string Tag, T)(T[] slice) { return typeof(return)(slice); } 78 MaybeNullSlice!(T, Tag) maybeNull(string Tag, T)(NotNullSlice!(T, Tag) slice) { return typeof(return)(slice); } 79 NotNullPtr !(T, Tag) notNull (string Tag, T)(T* ptr) { assert(ptr !is null, "Pointer is null"); return typeof(return)(ptr); } 80 NotNullPtr !(T, Tag) notNull (string Tag, T)(MaybeNullPtr!(T, Tag) ptr) { assert(ptr !is null, "Pointer is null"); return typeof(return)(ptr); } 81 NotNullSlice !(T, Tag) notNull (string Tag, T)(T[] slice) { assert(slice !is null, "Slice is null"); return typeof(return)(slice); } 82 NotNullSlice !(T, Tag) notNull (string Tag, T)(MaybeNullSlice!(T, Tag) slice) { assert(slice !is null, "Slice is null"); return typeof(return)(slice); } 83 84 MaybeNullPtr !(T, "default") maybeNull(T)(T* ptr) { return typeof(return)(ptr); } 85 NotNullPtr !(T, "default") notNull (T)(T* ptr) { assert(ptr !is null, "Pointer is null"); return typeof(return)(ptr); } 86 MaybeNullSlice!(T, "default") maybeNull(T)(T[] slice) { return typeof(return)(slice); } 87 NotNullSlice !(T, "default") notNull (T)(T[] slice) { assert(slice !is null, "Slice is null"); return typeof(return)(slice); }