Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std.algorithm: Remove the hasAssignableElements restriction from HeapSortImpl #1858

Merged
merged 3 commits into from Jan 16, 2014

Conversation

CyberShadow
Copy link
Member

This restriction seems unnecessary (as HeapSortImpl uses swap/swapAt, which does not require assignability), and was getting in the way of e.g. sorting a range of Refs.

This was the only thing preventing the sorting of a range of structs with disabled opAssign, but implementing proxySwap.

@CyberShadow
Copy link
Member Author

While trying to write a test for this, I discovered that the proxySwap version of swap does not work if proxySwap wants to take the other struct by reference. Is that on purpose, or just an unforeseen side effect of using T.init to test callability?

@monarchdodra
Copy link
Collaborator

a) I think it is an "unforeseen consequence". is(typeof(lhs.proxySwap(rhs))) would probably be better
b) I'm not even sure what the status on "proxySwap" is: It's undocumented, and completely unused. It looks like a way to open swap for user code, but I'm not sure we ever went through with it.

I wouldn't lose any sleep over this one.

This restriction seems unnecessary (as HeapSortImpl uses swap/swapAt, which does not require assignability), and was getting in the way of e.g. sorting a range of Refs.

Hum... you are right, swap requires hasSwapableElements and swapAt requires either hasSwapableElements or hasAssignableElements.

I didn't see any direct calls to swap so (I think) the correct change would be to have static assert(hasSwapableElements || hasAssignableElements)

This restriction seems unnecessary (as HeapSortImpl uses swap/swapAt,
which does not require assignability), and was getting in the way of
e.g. sorting a range of Refs. The range can satisfy either
hasAssignableElements, or hasSwappableElements
@CyberShadow
Copy link
Member Author

I didn't see any direct calls to swap so (I think) the correct change would be to have static assert(hasSwapableElements || hasAssignableElements)

Ah yes, good catch.

Updated with swap fix and unit test.

@@ -2039,7 +2039,7 @@ if (allMutableFields!T && !is(typeof(T.init.proxySwap(T.init))))
}

// Not yet documented
void swap(T)(T lhs, T rhs) if (is(typeof(T.init.proxySwap(T.init))))
void swap(T)(auto ref T lhs, auto ref T rhs) if (is(typeof(lhs.proxySwap(rhs))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely not. Swap takes by reference, always. You can't swap args that are passed by value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can if the type being swapped only contains a pointer towards the real data. This is the case in what I wanted to accomplish when I wrote this pull: http://stackoverflow.com/a/21104053/21501

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The differentiator is whether proxySwap takes rhs by value or reference. If it takes it by reference, this instantiation will fail if auto ref resolves to non-ref. If it takes it by value, then it doesn't need to mutate the other value, possibly only its indirections.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it takes it by reference, this instantiation will fail if auto ref resolves to non-ref.

Oh, gah, not it won't! It'll get a copy. I see what you mean now. swap here needs to accept either ref, or a qualifier that is not passable to a ref function. Would ref and in overloads work?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would ref and in overloads work?

in means const, so that wouldn't work (mutation of const). "ref scope" could work, but (AFAIK) that doesn't work for some reason. As for "scope", are the references ever escaped? They are swapped, that's for sure...

In nay case (AFAIK), scope don't work right now, so it might be best to simply leave it as ref.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, thanks.

@monarchdodra
Copy link
Collaborator

LGTM, though I still have dounts about how "official" proxySwap is. Perhaps @andralex has some knowledge on it?

andralex added a commit that referenced this pull request Jan 16, 2014
…nable

std.algorithm: Remove the hasAssignableElements restriction from HeapSortImpl
@andralex andralex merged commit 6732bbb into dlang:master Jan 16, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants