Thread overview
How can I use heapify in @safe code?
Oct 01, 2016
Burt
Oct 01, 2016
klmp
Oct 01, 2016
Burt
October 01, 2016
Hi,
I'd like to use a binary heap from @safe code. I thought @safe is transitive but the following example does not compile:

import std.container.binaryheap;
@safe // This makes things fail.
unittest
{
	// Test range interface.
	import std.algorithm.comparison : equal;
	int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
	auto h = heapify(a);
	assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
}

Is there a way to @safely call heapify? How?

Thanks in advance!
October 01, 2016
On Saturday, 1 October 2016 at 16:59:18 UTC, Burt wrote:
> Hi,
> I'd like to use a binary heap from @safe code. I thought @safe is transitive

It tries too but "heapify" uses the struct "BinaryHeap" that is not safe at all.
(either not annotated or @safe not applicable because of what it uses in intern: @system stuff)

> but the following example does not compile:
>
> import std.container.binaryheap;
> @safe // This makes things fail.
> unittest
> {
> 	// Test range interface.
> 	import std.algorithm.comparison : equal;
> 	int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
> 	auto h = heapify(a);
> 	assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
> }
>
> Is there a way to @safely call heapify? How?

No easy "good" way:
1. BinaryHeap is an old container
2. It would require to patch the standard library. So virtually not available before weeks (but after a quick look it doesn't seem possible)

There's an easy "bad" way:

import std.container.binaryheap;
@safe // This makes things fail.
unittest
{
    void foo() @trusted
    {
	    import std.algorithm.comparison : equal;
	    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
	    auto h = heapify(a);
	    assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
    }
}

but "bad", don't forget ;)
It's a complete cheat to trust here.
October 01, 2016
On Saturday, 1 October 2016 at 18:36:54 UTC, klmp wrote:
> On Saturday, 1 October 2016 at 16:59:18 UTC, Burt wrote:
>> [...]
>
> It tries too but "heapify" uses the struct "BinaryHeap" that is not safe at all.
> (either not annotated or @safe not applicable because of what it uses in intern: @system stuff)
>
>> [...]
>
> No easy "good" way:
> 1. BinaryHeap is an old container
> 2. It would require to patch the standard library. So virtually not available before weeks (but after a quick look it doesn't seem possible)
>
> There's an easy "bad" way:
>
> import std.container.binaryheap;
> @safe // This makes things fail.
> unittest
> {
>     void foo() @trusted
>     {
> 	    import std.algorithm.comparison : equal;
> 	    int[] a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
> 	    auto h = heapify(a);
> 	    assert(h.equal([16, 14, 10, 9, 8, 7, 4, 3, 2, 1]));
>     }
> }
>
> but "bad", don't forget ;)
> It's a complete cheat to trust here.

Thanks for your quick answer! In this case I'll try to rewrite BinaryHeap. The bad way came to my mind too :). But I don't like it as does not really make things @safer.