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