From fba056a8df961138859561a6f4ea3d9447efbd6d Mon Sep 17 00:00:00 2001 From: somzzz Date: Fri, 2 Dec 2016 04:40:14 -0800 Subject: [PATCH 1/5] fix issue 13314 --- std/container/binaryheap.d | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/std/container/binaryheap.d b/std/container/binaryheap.d index a2a5195a217..12fe19e9a96 100644 --- a/std/container/binaryheap.d +++ b/std/container/binaryheap.d @@ -62,8 +62,14 @@ size of that range. If $(D Store) is a container that supports $(D insertBack), the $(D BinaryHeap) may grow by adding elements to the container. */ + +template hasDup(T) +{ + const hasDup = __traits(compiles, (T t) { return t.dup(); }); +} + struct BinaryHeap(Store, alias less = "a < b") -if (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) +if ((isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) && hasDup!(Store)) { import std.functional : binaryFun; import std.exception : enforce; From 192b47aadb580e652c8a7cadc4789865bbe25455 Mon Sep 17 00:00:00 2001 From: somzzz Date: Fri, 2 Dec 2016 12:37:42 -0800 Subject: [PATCH 2/5] allow BinaryHeap.dup only on Store.dup present --- std/container/binaryheap.d | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/std/container/binaryheap.d b/std/container/binaryheap.d index 12fe19e9a96..5515b7f4c97 100644 --- a/std/container/binaryheap.d +++ b/std/container/binaryheap.d @@ -62,14 +62,8 @@ size of that range. If $(D Store) is a container that supports $(D insertBack), the $(D BinaryHeap) may grow by adding elements to the container. */ - -template hasDup(T) -{ - const hasDup = __traits(compiles, (T t) { return t.dup(); }); -} - struct BinaryHeap(Store, alias less = "a < b") -if ((isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) && hasDup!(Store)) +if (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) { import std.functional : binaryFun; import std.exception : enforce; @@ -207,12 +201,14 @@ Returns $(D true) if the heap is _empty, $(D false) otherwise. Returns a duplicate of the heap. The underlying store must also support a $(D dup) method. */ - @property BinaryHeap dup() - { - BinaryHeap result; - if (!_payload.refCountedStore.isInitialized) return result; - result.assume(_store.dup, length); - return result; + static if (is(typeof(Store.init.dup) == Store)) { + @property BinaryHeap dup() + { + BinaryHeap result; + if (!_payload.refCountedStore.isInitialized) return result; + result.assume(_store.dup, length); + return result; + } } /** From c3714ea01eb4c612897e90b7e6d7ba4556e4c41f Mon Sep 17 00:00:00 2001 From: somzzz Date: Tue, 6 Dec 2016 02:04:57 -0800 Subject: [PATCH 3/5] unittest --- std/container/binaryheap.d | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/std/container/binaryheap.d b/std/container/binaryheap.d index 5515b7f4c97..b0eac7f84f2 100644 --- a/std/container/binaryheap.d +++ b/std/container/binaryheap.d @@ -475,3 +475,12 @@ unittest // 16072 assert(r.front == 99); } + +unittest +{ + import std.algorithm.comparison : equal; + int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7]; + auto heap = heapify(a); + auto dup = heap.dup(); + assert(dup.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1])); +} From 4c708c7566708dca03f3550ea85bbf21b99aea35 Mon Sep 17 00:00:00 2001 From: somzzz Date: Tue, 6 Dec 2016 10:17:46 -0800 Subject: [PATCH 4/5] comment --- std/container/binaryheap.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/container/binaryheap.d b/std/container/binaryheap.d index b0eac7f84f2..e8708f18bef 100644 --- a/std/container/binaryheap.d +++ b/std/container/binaryheap.d @@ -198,8 +198,8 @@ Returns $(D true) if the heap is _empty, $(D false) otherwise. } /** -Returns a duplicate of the heap. The underlying store must also -support a $(D dup) method. +Returns a duplicate of the heap. The $(D dup) method is available only if the +underlying store supports it. */ static if (is(typeof(Store.init.dup) == Store)) { @property BinaryHeap dup() From b339da57ed6f72074bc0e8c2ae7e46b2ff9cf6d9 Mon Sep 17 00:00:00 2001 From: somzzz Date: Tue, 6 Dec 2016 17:00:41 -0800 Subject: [PATCH 5/5] unittest for dup present and missing in Store --- std/container/binaryheap.d | 55 +++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/std/container/binaryheap.d b/std/container/binaryheap.d index e8708f18bef..91dbf6ba752 100644 --- a/std/container/binaryheap.d +++ b/std/container/binaryheap.d @@ -201,7 +201,8 @@ Returns $(D true) if the heap is _empty, $(D false) otherwise. Returns a duplicate of the heap. The $(D dup) method is available only if the underlying store supports it. */ - static if (is(typeof(Store.init.dup) == Store)) { + static if (is(typeof((Store s) { return s.dup; }(Store.init)) == Store)) + { @property BinaryHeap dup() { BinaryHeap result; @@ -484,3 +485,55 @@ unittest auto dup = heap.dup(); assert(dup.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1])); } + +unittest +{ + static struct StructWithoutDup + { + int[] a; + @disable StructWithoutDup dup() + { + StructWithoutDup d; + return d; + } + alias a this; + } + + // Assert Binary heap can be created when Store doesn't have dup + // if dup is not used. + assert(__traits(compiles, () + { + auto s = StructWithoutDup([1,2]); + auto h = heapify(s); + })); + + // Assert dup can't be used on BinaryHeaps when Store doesn't have dup + assert(!__traits(compiles, () + { + auto s = StructWithoutDup([1,2]); + auto h = heapify(s); + h.dup(); + })); +} + +unittest +{ + static struct StructWithDup + { + int[] a; + StructWithDup dup() + { + StructWithDup d; + return d; + } + alias a this; + } + + // Assert dup can be used on BinaryHeaps when Store has dup + assert(__traits(compiles, () + { + auto s = StructWithDup([1, 2]); + auto h = heapify(s); + h.dup(); + })); +}