1 module nxt.borrowed; 2 3 /** Write-borrowed access to range `Range`. */ 4 struct WriteBorrowed(Range, Owner) 5 // if (isInstanceOf!(Owned, Owner)) 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() @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 (isInstanceOf!(Owned, Owner)) 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() @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) 66 { 67 return typeof(this)(_range[i .. j], _owner); 68 } 69 70 /// Get read-only slice. 71 auto opSlice() inout 72 { 73 return this; // same as copy 74 } 75 76 @property bool empty() const @safe pure nothrow @nogc 77 { 78 import std.range.primitives : empty; // pick this if `_range` doesn't have it 79 return _range.empty; 80 } 81 82 @property auto ref front() inout @safe pure 83 { 84 assert(!empty); 85 import std.range.primitives : front; // pick this if `_range` doesn't have it 86 return _range.front; 87 } 88 89 typeof(this) save() // forward range 90 { 91 return this; 92 } 93 94 void popFront() @safe 95 { 96 import std.range.primitives : popFront; // pick this if `_range` doesn't have it 97 _range.popFront(); 98 } 99 100 Range _range; /// constant range 101 alias _range this; /// behave like range 102 103 private: 104 Owner* _owner = null; /// pointer to container owner 105 }