Skip to content

Make dmsort work with non-default-constructible types (fixes #1) #2

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

Merged
merged 2 commits into from
Jan 17, 2017
Merged

Make dmsort work with non-default-constructible types (fixes #1) #2

merged 2 commits into from
Jan 17, 2017

Conversation

Morwenn
Copy link
Contributor

@Morwenn Morwenn commented Jan 12, 2017

See issue #1 for the detail.

@adrian17
Copy link
Owner

Nice find, and silly resize. Thanks.

I'll repeat the benchmarks with this change later (in ~12h) (although it's far from the critical part of the algorithm, so it shouldn't matter anyway) and most likely merge it then.

Copy link
Owner

@adrian17 adrian17 left a comment

Choose a reason for hiding this comment

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

Hm, the second overload (with-trivial-copies) may also need this, because a type may be trivially copyable and not be default constructible.

for (int i = 0; i < num_dropped_in_row; ++i) {
--read;
*read = std::move(*(dropped.end() - (i+1)));
}
dropped.resize(trunc_to_length);
for (int i = 0; i < num_dropped_in_row; ++i) {
Copy link
Owner

Choose a reason for hiding this comment

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

This can most likely be merged with the loop above:

                for (int i = 0; i < num_dropped_in_row; ++i) {
                    --read;
                    *read = std::move(*(dropped.end() - 1));
                    dropped.pop_back();
                }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, we could try that too, that might be more sensible.

@Morwenn
Copy link
Contributor Author

Morwenn commented Jan 13, 2017

Eh, it's true that I didn't think of trivially copyable types that are not default-constructible, but I guess that such types can indeed exist. Good catch.

@Morwenn
Copy link
Contributor Author

Morwenn commented Jan 13, 2017

By the way, it looks like the algorithm could easily be made to work with bidirectional iterators instead of random-access ones. The changes I see to make the magic happen:

  • Replace read -= num_dropped_in_row; by std::advance(read, -num_dropped_in_row), first chaging num_dropped_in_row to a signed type (std::iterator_traits<Iter>::difference_type looks like a good choice for that)
  • Replace a few it - 1 by std::prev(it) and it + 1 by std::next(it)

Apparently, the algorithm almost never performs big jumps in the collection, so making it work with bidirectional iterators could be worth (unlike e.g. heapsort). You may want to consider it since there aren't many good sorting algorithms for bidirectional iterators :)


My small tests on one million integer lists show that it's more than decent for bidirectional iterators too (ok, the more efficient would still probably be to move everything to a vector, sort it, and move everything back):

look at me

Morwenn added a commit to Morwenn/cpp-sort that referenced this pull request Jan 13, 2017
@adrian17 adrian17 merged commit e8cb18e into adrian17:master Jan 17, 2017
@adrian17
Copy link
Owner

Thank you.

I'll take a look at bidirectional iterator changes too, thanks for that advice too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants