1 module nxt.borrowed; 2 3 /** Read-and-Write-borrowed access to a range of type `Range` owned by `Owner`. */ 4 struct WriteBorrowed(Range, Owner) 5 // if (is(Owner == Owned!(_), _)) 6 { 7 this(Range range, Owner* owner) { 8 assert(owner); 9 _range = range; 10 _owner = owner; 11 owner._writeBorrowed = true; 12 } 13 14 this(this) @disable; // cannot be copied 15 16 ~this() nothrow @nogc 17 { 18 debug assert(_owner._writeBorrowed, "Write borrow flag is already false, something is wrong with borrowing logic"); 19 _owner._writeBorrowed = false; 20 } 21 22 Range _range; /// range 23 alias _range this; /// behave like range 24 25 private: 26 Owner* _owner = null; /// pointer to container owner 27 } 28 29 /** Read-borrowed access to a range of type `Range` owned by `Owner`. */ 30 struct ReadBorrowed(Range, Owner) 31 // if (is(Owner == Owned!(_), _)) 32 { 33 this(const Range range, Owner* owner) { 34 import core.internal.traits : Unqual; 35 _range = *(cast(Unqual!Range*)&range); 36 _owner = owner; 37 if (_owner) { 38 assert(_owner._readBorrowCount != _owner.readBorrowCountMax, "Cannot have more borrowers"); 39 _owner._readBorrowCount = _owner._readBorrowCount + 1; 40 } 41 } 42 43 this(this) { 44 if (_owner) { 45 assert(_owner._readBorrowCount != _owner.readBorrowCountMax, "Cannot have more borrowers"); 46 _owner._readBorrowCount = _owner._readBorrowCount + 1; 47 } 48 } 49 50 ~this() nothrow @nogc 51 { 52 if (_owner) { 53 assert(_owner._readBorrowCount != 0, "Read borrow counter is already zero, something is wrong with borrowing logic"); 54 _owner._readBorrowCount = _owner._readBorrowCount - 1; 55 } 56 } 57 58 /// Get read-only slice in range `i` .. `j`. 59 auto opSlice(size_t i, size_t j) => typeof(this)(_range[i .. j], _owner); 60 61 /// Get read-only slice. 62 auto opSlice() inout => this; // same as copy 63 64 bool empty() const @property pure nothrow @safe @nogc 65 { 66 import std.range.primitives : empty; // pick this if `_range` doesn't have it 67 return _range.empty; 68 } 69 70 @property auto ref front() inout @safe pure in(!empty) { 71 import std.range.primitives : front; // pick this if `_range` doesn't have it 72 return _range.front; 73 } 74 75 typeof(this) save() => this; 76 77 void popFront() @safe in(!empty) { 78 import std.range.primitives : popFront; // pick this if `_range` doesn't have it 79 _range.popFront(); 80 } 81 82 Range _range; /// constant range 83 alias _range this; /// behave like range 84 85 private: 86 Owner* _owner = null; /// pointer to container owner 87 }