From 68d510418da453fd1094437e823a860c555cc7f9 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Mon, 29 Apr 2024 11:44:29 +0200 Subject: [PATCH 01/26] View - Initial work-in-progress for a new `View` type-buffer --- source/niknaks/containers.d | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 9c1a01c..a4158c9 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -597,4 +597,106 @@ unittest // Destroy the map (such that it ends the sweeper destroy(map); +} + +private struct Sector(T) +{ + private T[] data; + + this(T[] data) + { + this.data = data; + } + + public T opIndex(size_t idx) + { + return this.data[idx]; + } + + public size_t opDollar() + { + return this.data.length; + } + + public T[] opSlice(size_t start, size_t end) + { + return this.data[start..end]; + } + + public T[] opSlice() + { + return opSlice(0, opDollar); + } + +} + +// TODO: Make a bit better +private bool isSector(S)() +{ + return __traits(hasMember, S, "opIndex"); +} + +public struct View(T, SectorType = Sector!(T)) +if(isSector!(SectorType)()) +{ + private SectorType[] sectors; + // private + + private size_t computeTotalLen() + { + size_t l; + foreach(SectorType sector; this.sectors) + { + l += sector.opDollar(); + } + return l; + } + + public size_t opDollar() + { + return this.computeTotalLen(); + } + + public T opIndex(size_t idx) + { + size_t thunk; + foreach(SectorType sector; this.sectors) + { + if(idx-thunk < sector.opDollar()) + { + return sector[idx-thunk]; + } + else + { + thunk += sector.opDollar(); + } + } + + import core.exception : ArrayIndexError; + throw new ArrayIndexError(idx, opDollar()); + } + + // Takes the data, constructs a kind-of SectorType + // and adds it + public void add(T[] data) + { + this.sectors ~= SectorType(data); + } +} + +unittest +{ + View!(int) view; + assert(view.opDollar() == 0); + + view.add([1,3,45]); + assert(view.opDollar() == 3); + + view.add([2]); + assert(view.opDollar() == 4); + + assert(view[0] == 1); + assert(view[1] == 3); + assert(view[2] == 45); + assert(view[3] == 12); } \ No newline at end of file From 0fb11d7c4772d2078c876961b75a8725d3b6903b Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Mon, 29 Apr 2024 11:46:26 +0200 Subject: [PATCH 02/26] View (unittests) - Fixed incorrect assertion --- source/niknaks/containers.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index a4158c9..6637a3a 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -698,5 +698,5 @@ unittest assert(view[0] == 1); assert(view[1] == 3); assert(view[2] == 45); - assert(view[3] == 12); + assert(view[3] == 2); } \ No newline at end of file From dba6ea59fa2ac9b417a393b590889ef40eeaa51e Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Mon, 29 Apr 2024 11:51:51 +0200 Subject: [PATCH 03/26] View - Implemented `opSlice()` View (unittests) - Added test for `opSlice()` --- source/niknaks/containers.d | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 6637a3a..8f2747b 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -676,6 +676,17 @@ if(isSector!(SectorType)()) throw new ArrayIndexError(idx, opDollar()); } + public T[] opSlice() + { + T[] buff; + foreach(SectorType sector; this.sectors) + { + buff ~= sector[]; + } + + return buff; + } + // Takes the data, constructs a kind-of SectorType // and adds it public void add(T[] data) @@ -699,4 +710,7 @@ unittest assert(view[1] == 3); assert(view[2] == 45); assert(view[3] == 2); + + int[] all = view[]; + assert(all == [1,3,45,2]); } \ No newline at end of file From 451fb668bdf8a125a60161762063376f4890fb43 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Tue, 30 Apr 2024 08:11:21 +0200 Subject: [PATCH 04/26] View (unittests) - Added test for out-of-bounds indexing --- source/niknaks/containers.d | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 8f2747b..9ec06b0 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -636,6 +636,8 @@ private bool isSector(S)() return __traits(hasMember, S, "opIndex"); } +import core.exception : ArrayIndexError; + public struct View(T, SectorType = Sector!(T)) if(isSector!(SectorType)()) { @@ -672,7 +674,6 @@ if(isSector!(SectorType)()) } } - import core.exception : ArrayIndexError; throw new ArrayIndexError(idx, opDollar()); } @@ -700,6 +701,17 @@ unittest View!(int) view; assert(view.opDollar() == 0); + try + { + view[1]; + assert(false); + } + catch(ArrayIndexError e) + { + assert(e.index == 1); + assert(e.length == 0); + } + view.add([1,3,45]); assert(view.opDollar() == 3); From 71257f3926d61007fba6fdad437098b7cdeb6592 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Tue, 30 Apr 2024 21:35:19 +0200 Subject: [PATCH 05/26] View - Added support for the `~=` operator overload View (unittests) - Use the operator overload --- source/niknaks/containers.d | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 9ec06b0..6186e14 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -688,6 +688,32 @@ if(isSector!(SectorType)()) return buff; } + private static bool isArrayAppend(P)() + { + return __traits(isSame, P, T[]); + } + + private static bool isElementAppend(P)() + { + return __traits(isSame, P, T); + } + + // Append + public void opOpAssign(string op, E)(E value) + if(op == "~" && (isArrayAppend!(E) || isElementAppend!(E))) + { + static if(isArrayAppend!(E)) + { + add(value); + } + else + { + add([value]); + } + } + + // public opIn + // Takes the data, constructs a kind-of SectorType // and adds it public void add(T[] data) @@ -712,10 +738,10 @@ unittest assert(e.length == 0); } - view.add([1,3,45]); + view ~= [1,3,45]; assert(view.opDollar() == 3); - view.add([2]); + view ~= 2; assert(view.opDollar() == 4); assert(view[0] == 1); From 20c39695162bd6c55a960802796f054b5f8d05d0 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Tue, 30 Apr 2024 22:35:54 +0200 Subject: [PATCH 06/26] View - Allow updating indices --- source/niknaks/containers.d | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 6186e14..30bab09 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -613,6 +613,11 @@ private struct Sector(T) return this.data[idx]; } + public void opIndexAssign(T value, size_t index) + { + this.data[index] = value; + } + public size_t opDollar() { return this.data.length; @@ -677,6 +682,24 @@ if(isSector!(SectorType)()) throw new ArrayIndexError(idx, opDollar()); } + public void opIndexAssign(T value, size_t idx) + { + size_t thunk; + foreach(SectorType sector; this.sectors) + { + if(idx-thunk < sector.opDollar()) + { + sector[idx-thunk] = value; + } + else + { + thunk += sector.opDollar(); + } + } + + throw new ArrayIndexError(idx, opDollar()); + } + public T[] opSlice() { T[] buff; @@ -749,6 +772,8 @@ unittest assert(view[2] == 45); assert(view[3] == 2); + view[0] = 71; + int[] all = view[]; - assert(all == [1,3,45,2]); + assert(all == [71,3,45,2]); } \ No newline at end of file From b383cfad65ff3ff9d8b3d4de99e8f0388a567221 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Wed, 1 May 2024 20:27:14 +0200 Subject: [PATCH 07/26] View - More work being done on deciding various parts of this API - Fixed the `opIndexAssign(...)` --- source/niknaks/containers.d | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 30bab09..8400694 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -618,11 +618,19 @@ private struct Sector(T) this.data[index] = value; } + // Contract: Obtaining the length must be present public size_t opDollar() { return this.data.length; } + // Contract: Obtaining the length must be present + @property + public size_t length() + { + return opDollar(); + } + public T[] opSlice(size_t start, size_t end) { return this.data[start..end]; @@ -633,6 +641,12 @@ private struct Sector(T) return opSlice(0, opDollar); } + // Contract: Rezising must be implemented + // TODO: This would then be the very reason for + // using ref actually, as resizing may only + // change a local copy when extding on + // the tail-end "extent" (SectorType) + } // TODO: Make a bit better @@ -685,11 +699,17 @@ if(isSector!(SectorType)()) public void opIndexAssign(T value, size_t idx) { size_t thunk; + // TODO: Should be ref, else it is just a local struct copy + // could cheat if sector is never replaced, hence why it works foreach(SectorType sector; this.sectors) { + writeln(sector); + writeln("idx: ", idx); + writeln("thunk: ", thunk); if(idx-thunk < sector.opDollar()) { sector[idx-thunk] = value; + return; } else { @@ -743,6 +763,19 @@ if(isSector!(SectorType)()) { this.sectors ~= SectorType(data); } + + @property + public size_t length() + { + return computeTotalLen(); + } + + @property + public void length(size_t size) + { + // TODO: Add support for sizing down + // TODO: Add support for sizing up + } } unittest @@ -776,4 +809,9 @@ unittest int[] all = view[]; assert(all == [71,3,45,2]); + + // Truncate by 1 element + view.length = view.length-1; + all = view[]; + assert(all == [71,3,45]); } \ No newline at end of file From 328239cd5749681169a1968cec739616bdc93b5b Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 07:58:17 +0200 Subject: [PATCH 08/26] View - made `opIndex(size_t)` and `opIndexAssign(T, size_t)` respect the "fake" size View (unittests) - Added code to test the above updates to the `View` type --- source/niknaks/containers.d | 137 ++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 5 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 8400694..8687078 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -647,6 +647,8 @@ private struct Sector(T) // change a local copy when extding on // the tail-end "extent" (SectorType) + // Actually should resizing even be done here? + } // TODO: Make a bit better @@ -656,6 +658,7 @@ private bool isSector(S)() } import core.exception : ArrayIndexError; +import core.exception : RangeError; public struct View(T, SectorType = Sector!(T)) if(isSector!(SectorType)()) @@ -663,6 +666,11 @@ if(isSector!(SectorType)()) private SectorType[] sectors; // private + // Maybe current size should be here as we + // are a view, we should allow modofication + // but not make any NEW arrays + private size_t curSize; + private size_t computeTotalLen() { size_t l; @@ -675,11 +683,17 @@ if(isSector!(SectorType)()) public size_t opDollar() { - return this.computeTotalLen(); + return this.length; } public T opIndex(size_t idx) { + // Within range of "fake" size + if(!(idx < this.length)) + { + throw new ArrayIndexError(idx, this.length); + } + size_t thunk; foreach(SectorType sector; this.sectors) { @@ -693,11 +707,17 @@ if(isSector!(SectorType)()) } } - throw new ArrayIndexError(idx, opDollar()); + throw new ArrayIndexError(idx, this.length); } public void opIndexAssign(T value, size_t idx) { + // Within range of "fake" size + if(!(idx < this.length)) + { + throw new ArrayIndexError(idx, this.length); + } + size_t thunk; // TODO: Should be ref, else it is just a local struct copy // could cheat if sector is never replaced, hence why it works @@ -717,7 +737,7 @@ if(isSector!(SectorType)()) } } - throw new ArrayIndexError(idx, opDollar()); + throw new ArrayIndexError(idx, this.length); } public T[] opSlice() @@ -728,6 +748,9 @@ if(isSector!(SectorType)()) buff ~= sector[]; } + // Trim to "fake" size + buff.length = this.curSize; + return buff; } @@ -761,13 +784,20 @@ if(isSector!(SectorType)()) // and adds it public void add(T[] data) { + // Create a new sector + SectorType sec = SectorType(data); + + // Update the tracking size + this.curSize += sec.length; + + // Concatenate it to the view this.sectors ~= SectorType(data); } @property public size_t length() { - return computeTotalLen(); + return this.curSize; } @property @@ -775,6 +805,59 @@ if(isSector!(SectorType)()) { // TODO: Add support for sizing down // TODO: Add support for sizing up + + // TODO: Need we continuously compute this? + // ... we should have a tracking field for + // ... this + size_t actualSize = computeTotalLen(); + + // On successful exit, update the "fake" size + scope(success) + { + this.curSize = size; + } + + + // Don't allow sizing up (doesn't make sense for a view) + if(size > actualSize) + { + auto r = new RangeError(); + r.msg = "Cannot extend the size of a view past its total size (of all attached sectors)"; + throw r; + } + // If nothing changes + else if(size == actualSize) + { + // Nothing + } + // If shrinking to zero + else if(size == 0) + { + // Just drop everything + this.sectors.length = 0; + } + // If shrinking (arbitrary) + else + { + // Sectors from left-to-right to keep + size_t sectorCnt; + + // Accumulator + size_t accumulator; + + foreach(SectorType sector; this.sectors) + { + accumulator += sector.length; + sectorCnt++; + if(size <= accumulator) + { + break; + } + } + + this.sectors.length = sectorCnt; + } + } } @@ -796,22 +879,66 @@ unittest view ~= [1,3,45]; assert(view.opDollar() == 3); + assert(view.length == 3); view ~= 2; assert(view.opDollar() == 4); + assert(view.length == 4); assert(view[0] == 1); assert(view[1] == 3); assert(view[2] == 45); assert(view[3] == 2); + // Update elements view[0] = 71; + view[3] = 50; + // Set size to same size + view.length = view.length; + + // Check that update is present + // and size unchanged int[] all = view[]; - assert(all == [71,3,45,2]); + assert(all == [71,3,45,50]); // Truncate by 1 element view.length = view.length-1; all = view[]; assert(all == [71,3,45]); + + // This should fail + try + { + view[3] = 3; + assert(false); + } + catch(RangeError e) + { + } + + // This should fail + try + { + int j = view[3]; + assert(false); + } + catch(RangeError e) + { + } + + // Up-sizing past real size should not be allowed + try + { + view.length = view.length+1; + assert(false); + } + catch(RangeError e) + { + } + + // Size to zero + view.length = 0; + assert(view.length == 0); + assert(view[] == []); } \ No newline at end of file From df52dab72f56ee11e2cf9bb3ea2e7c3ab89abdc2 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 08:10:04 +0200 Subject: [PATCH 09/26] View - Made `add(T[])` private --- source/niknaks/containers.d | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 8687078..de7d396 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -778,11 +778,9 @@ if(isSector!(SectorType)()) } } - // public opIn - // Takes the data, constructs a kind-of SectorType // and adds it - public void add(T[] data) + private void add(T[] data) { // Create a new sector SectorType sec = SectorType(data); From 2ecb371d9a53283cf89dbecf1a9e83304a3e9872 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 08:34:28 +0200 Subject: [PATCH 10/26] View - Added range `opSlice()` --- source/niknaks/containers.d | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index de7d396..862706f 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -754,6 +754,13 @@ if(isSector!(SectorType)()) return buff; } + public T[] opSlice(size_t start, size_t end) + { + // FIXME: This is lazy, do a check for up to where + // and actually make THIS the real implementation + return this.opSlice()[start, end]; + } + private static bool isArrayAppend(P)() { return __traits(isSame, P, T[]); From bfa7c6020fdb87a389ea2949d2718a19467af785 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 08:35:45 +0200 Subject: [PATCH 11/26] View - Fixed range-based `opSlice(...)` View (unittests) - Added unittest --- source/niknaks/containers.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 862706f..75924fe 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -758,7 +758,7 @@ if(isSector!(SectorType)()) { // FIXME: This is lazy, do a check for up to where // and actually make THIS the real implementation - return this.opSlice()[start, end]; + return this.opSlice()[start..end]; } private static bool isArrayAppend(P)() @@ -894,6 +894,7 @@ unittest assert(view[1] == 3); assert(view[2] == 45); assert(view[3] == 2); + assert(view[0..2] == [1,3]); // Update elements view[0] = 71; From 64ba0baa8f3e2c5d738d9d08d5fbe6a1df0f11d7 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 09:18:01 +0200 Subject: [PATCH 12/26] View - New, more efficient `opSlice(size_t, size_t)` implemented View (unittests) - Updated slicing tests --- source/niknaks/containers.d | 60 ++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 75924fe..d807edf 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -756,9 +756,66 @@ if(isSector!(SectorType)()) public T[] opSlice(size_t start, size_t end) { + // Invariant of start < end + if(!(start <= end)) + { + // TODO: Check + throw new RangeError("Starting index must be smaller than or equal to ending index"); + } + // Within range of "fake" size + else if(!((start < this.length) && (end <= this.length))) + { + throw new RangeError("start index or end index not under range"); + // throw new ArrayIndexError(idx, this.length); + } + + // TODO: is this the best way to go about + // implementing this? + + T[] collected; + + size_t thunk; + foreach(SectorType sector; this.sectors) + { + // If the current sector contains + // both the starting AND ending + // indices + if(start-thunk < sector.opDollar() && end-thunk <= sector.opDollar()) + { + return sector[start-thunk..end-thunk]; + } + // If the current sector's starting + // index (only) is included + else if(start-thunk < sector.opDollar() && !(end-thunk <= sector.opDollar())) + { + collected ~= sector[start-thunk..$]; + } + // If the current sector's ending + // index (only) is included + else if(!(start-thunk < sector.opDollar()) && end-thunk <= sector.opDollar()) + { + collected ~= sector[0..end-thunk]; + } + // if the current secto's entirety + // is to be included + else + { + collected ~= sector[]; + } + + thunk += sector.opDollar(); + } + + + // FIXME: This is lazy, do a check for up to where // and actually make THIS the real implementation - return this.opSlice()[start..end]; + + writeln(collected); + + // TODO: Also if the range matches the bounds + // of a given range exactly then extract directly + return collected; } private static bool isArrayAppend(P)() @@ -895,6 +952,7 @@ unittest assert(view[2] == 45); assert(view[3] == 2); assert(view[0..2] == [1,3]); + assert(view[0..4] == [1,3,45,2]); // Update elements view[0] = 71; From 1b1cb8f31681669502d02f5a631f35f630c3721c Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 09:18:17 +0200 Subject: [PATCH 13/26] View - Typo fix --- source/niknaks/containers.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index d807edf..09d51f2 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -796,7 +796,7 @@ if(isSector!(SectorType)()) { collected ~= sector[0..end-thunk]; } - // if the current secto's entirety + // if the current sector's entirety // is to be included else { From 515d85eae029d98691c6cce9d14b140a915e9dbf Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 09:20:15 +0200 Subject: [PATCH 14/26] View (unittests) - Added another test to test the last )untested) branch of the `opSlice(size_t, size_t)` method --- source/niknaks/containers.d | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 09d51f2..d1c2725 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -769,9 +769,6 @@ if(isSector!(SectorType)()) // throw new ArrayIndexError(idx, this.length); } - // TODO: is this the best way to go about - // implementing this? - T[] collected; size_t thunk; @@ -796,7 +793,7 @@ if(isSector!(SectorType)()) { collected ~= sector[0..end-thunk]; } - // if the current sector's entirety + // If the current sector's entirety // is to be included else { @@ -1005,4 +1002,14 @@ unittest view.length = 0; assert(view.length == 0); assert(view[] == []); +} + +unittest +{ + View!(int) view; + view ~= 1; + view ~= [2,3,4]; + view ~= 5; + + assert(view[0..5] == [1,2,3,4,5]); } \ No newline at end of file From 6372f2d8c76d0350e01833cffca5572fba858494 Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 09:35:41 +0200 Subject: [PATCH 15/26] View (unittests) - Added more tests for `opSlice(size_t, size_t)` --- source/niknaks/containers.d | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index d1c2725..78faca6 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -1012,4 +1012,35 @@ unittest view ~= 5; assert(view[0..5] == [1,2,3,4,5]); + + // test: start <= end invariant broken + try + { + auto j = view[1..0]; + assert(false); + } + catch(RangeError e) + { + + } + + // test: end out of bounds + try + { + auto j = view[1..view.length+1]; + assert(false); + } + catch(RangeError e) + { + + } + + int[] d = [1,2,3]; + writeln("according to dlang: ", d[1..2]); + + writeln("test lekker: ", view[1..2]); + assert(view[1..2] == [2]); + + writeln("test lekker: ", view[1..1]); + assert(view[1..1] == []); } \ No newline at end of file From c886ba184bd3bd908dfca99eadb636541ee1abff Mon Sep 17 00:00:00 2001 From: Tristan Brice Velloza Kildaire Date: Thu, 2 May 2024 09:36:39 +0200 Subject: [PATCH 16/26] View - `opSlice()` now forwards to `opSlice(size_t, size_t)` --- source/niknaks/containers.d | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 78faca6..7a82d79 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -742,16 +742,7 @@ if(isSector!(SectorType)()) public T[] opSlice() { - T[] buff; - foreach(SectorType sector; this.sectors) - { - buff ~= sector[]; - } - - // Trim to "fake" size - buff.length = this.curSize; - - return buff; + return this[0..this.length]; } public T[] opSlice(size_t start, size_t end) From 19a7ce6f7e49784985a551c7bcba2fc837f06291 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 14:50:11 +0200 Subject: [PATCH 17/26] View - Only add debug in unittest mode --- source/niknaks/containers.d | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 7a82d79..106d05f 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -723,9 +723,13 @@ if(isSector!(SectorType)()) // could cheat if sector is never replaced, hence why it works foreach(SectorType sector; this.sectors) { - writeln(sector); - writeln("idx: ", idx); - writeln("thunk: ", thunk); + version(unittest) + { + writeln(sector); + writeln("idx: ", idx); + writeln("thunk: ", thunk); + } + if(idx-thunk < sector.opDollar()) { sector[idx-thunk] = value; From e9cb3a19601a05afd15a9e7e18383dfeed217c9f Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 14:50:46 +0200 Subject: [PATCH 18/26] View - Cleaned up --- source/niknaks/containers.d | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 106d05f..00c1cc9 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -751,17 +751,15 @@ if(isSector!(SectorType)()) public T[] opSlice(size_t start, size_t end) { - // Invariant of start < end + // Invariant of start <= end if(!(start <= end)) { - // TODO: Check throw new RangeError("Starting index must be smaller than or equal to ending index"); } // Within range of "fake" size else if(!((start < this.length) && (end <= this.length))) { throw new RangeError("start index or end index not under range"); - // throw new ArrayIndexError(idx, this.length); } T[] collected; From 85580d2a71c5fb9e390059fc9024e90486e63ebf Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 14:51:06 +0200 Subject: [PATCH 19/26] View - Cleaned up --- source/niknaks/containers.d | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 00c1cc9..4e93c24 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -796,15 +796,6 @@ if(isSector!(SectorType)()) thunk += sector.opDollar(); } - - - // FIXME: This is lazy, do a check for up to where - // and actually make THIS the real implementation - - writeln(collected); - - // TODO: Also if the range matches the bounds - // of a given range exactly then extract directly return collected; } From 9472cb96d4bca7dedf366e1843ed747c1987a938 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 14:59:36 +0200 Subject: [PATCH 20/26] View - When calling `opSlice(size_t, size_t)` with arguments that are equal then you should return `[]`. This fixe a bug when we do `view[]` and length was `0` as `opSlice()` calls `opSlice(size_t, size_t)` with `opSlice(0, 0) then --- source/niknaks/containers.d | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 4e93c24..adac908 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -756,6 +756,11 @@ if(isSector!(SectorType)()) { throw new RangeError("Starting index must be smaller than or equal to ending index"); } + // If the indices are equal, then it is empty + else if(start == end) + { + return []; + } // Within range of "fake" size else if(!((start < this.length) && (end <= this.length))) { From 365d15d81faaaed590817c4ff74c8f65876f476b Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:01:57 +0200 Subject: [PATCH 21/26] View - Removed unreachable code --- source/niknaks/containers.d | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index adac908..829e1bf 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -740,8 +740,6 @@ if(isSector!(SectorType)()) thunk += sector.opDollar(); } } - - throw new ArrayIndexError(idx, this.length); } public T[] opSlice() From a421b40bdb9f3f879ce4a3cfb934179fb81adafe Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:02:18 +0200 Subject: [PATCH 22/26] View - Removed unreachable code --- source/niknaks/containers.d | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 829e1bf..ea62008 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -706,8 +706,6 @@ if(isSector!(SectorType)()) thunk += sector.opDollar(); } } - - throw new ArrayIndexError(idx, this.length); } public void opIndexAssign(T value, size_t idx) From 98f2f10acad87fea8dfcf2a90d20b1850ede8b7f Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:03:06 +0200 Subject: [PATCH 23/26] View - Replaced unreachable code with a false assertion --- source/niknaks/containers.d | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index ea62008..2513929 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -706,6 +706,10 @@ if(isSector!(SectorType)()) thunk += sector.opDollar(); } } + + // NOTE: This should be unreachable but + // compiler moans and groans + assert(false); } public void opIndexAssign(T value, size_t idx) From 818a7cad324ab3422711554734295b2493dbe97b Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:03:29 +0200 Subject: [PATCH 24/26] View - Cleaned up --- source/niknaks/containers.d | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 2513929..b7c28fc 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -851,9 +851,6 @@ if(isSector!(SectorType)()) @property public void length(size_t size) { - // TODO: Add support for sizing down - // TODO: Add support for sizing up - // TODO: Need we continuously compute this? // ... we should have a tracking field for // ... this @@ -905,7 +902,6 @@ if(isSector!(SectorType)()) this.sectors.length = sectorCnt; } - } } From f71286e85c851d2f8ba9557ff157406c3cbdc55f Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:03:49 +0200 Subject: [PATCH 25/26] View - Cleaned up --- source/niknaks/containers.d | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index b7c28fc..83e0c88 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -11,6 +11,8 @@ import std.datetime.stopwatch : StopWatch, AutoStart; import core.thread : Thread; import core.sync.condition : Condition; import std.functional : toDelegate; +import core.exception : ArrayIndexError; +import core.exception : RangeError; version(unittest) { @@ -657,8 +659,7 @@ private bool isSector(S)() return __traits(hasMember, S, "opIndex"); } -import core.exception : ArrayIndexError; -import core.exception : RangeError; + public struct View(T, SectorType = Sector!(T)) if(isSector!(SectorType)()) From 20cb74d5e85c0117018fd8e1a2053add141f3260 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Thu, 2 May 2024 15:12:36 +0200 Subject: [PATCH 26/26] SectorType - Working on type definition --- source/niknaks/containers.d | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/niknaks/containers.d b/source/niknaks/containers.d index 83e0c88..a1a853d 100644 --- a/source/niknaks/containers.d +++ b/source/niknaks/containers.d @@ -654,13 +654,23 @@ private struct Sector(T) } // TODO: Make a bit better +import std.traits : hasMember, hasStaticMember, Parameters; +import std.meta : AliasSeq; private bool isSector(S)() { - return __traits(hasMember, S, "opIndex"); + bool s = true; + + s = hasMember!(S, "opSlice") && __traits(isSame, Parameters!(S.opSlice), AliasSeq!(size_t, size_t)); + + + + + return s; } + public struct View(T, SectorType = Sector!(T)) if(isSector!(SectorType)()) {