Make timsort work with move-only types.#9
Merged
Merged
Conversation
Contributor
|
Thanks to the pull request and the excellent report. Really cool. I think tests should be added but I don't think it seriously: just wrap |
gfx
added a commit
that referenced
this pull request
Oct 17, 2015
gfx
added a commit
that referenced
this pull request
Oct 17, 2015
Make timsort work with move-only types.
Member
Author
|
Thanks for writing the tests :) By the way, why do we need to enable the moves for C++11? Wouldn't it be simpler to have them enabled by default in C++11 and to conditionally disable them? I actually see no reason for not having them enabled by default. |
Contributor
|
The reason is simple: when I wrote this algorithm, C++ compilers including clang does not have |
Member
Author
|
Oh, ok. It indeed maked sense at the time. Good thing that it works by default now. |
Contributor
|
😄 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In C++11,
std::sortis supposed to be able to sort collections of mve-only types. This patch adds support for move-only types totimsort. Here is what it changes:GFX_TIMSORT_MOVEinstead of simple copy-assignments.GFX_TIMSORT_MOVE_RANGEto use the C++11 iterators version ofstd::moveif required and usstd::copyinstead.GFX_TIMSORT_MOVE_BACKWARDto use eitherstd::move_backwardorstd::copy_backward.assertmessage, but that's trivial :pHowever, here is the big deal: I am not 100% sure that the algorithm never reads from a moved-from value. I read the algorithm and checked everywhere that whenever a value was moved-from the algorithm made sure that the iterators point to other non-moved-from values before being dereferenced, but this method has its limits. I also used a derived version of the benchmarks from my sorting library with a move-only type that keeps track of whether it has been moved-from and asserts if we try to read from it if it has been moved-from. Here is the type I used:
The benchmark runs several times on arrays of one million element with several data patterns to cover common and not-so-common cases, including arrays filled with random values. After every call to a sort method, it also checks that the resulting array is indeed sorted.
So, while I couldn't be 100% sure that it never reads from moved-from value (it would require a formal analysis), check the algorithm by hand and running all those tests make me pretty confident that it is safe :)
I didn't write a proper test case though since all of your tests seem to work with C++03, and such a test would explicitly require C++11 support to run and I don't know whether it would integrate seamlessly in the testsuite.