Just for fun, I have implemented the simplest sorting algorithm imaginable:
template<typename Iterator>
void treesort(Iterator begin, Iterator end)
{
typedef typename std::iterator_traits<Iterator>::value_type element_type;
// copy data into the tree
std::multiset<element_type> tree(begin, end);
// copy data out of the tree
std::copy(tree.begin(), tree.end(), begin);
}
It's only about 20 times slower than std::sort
for my test data :)
Next, I wanted to improve the performance with move semantics:
template<typename Iterator>
void treesort(Iterator begin, Iterator end)
{
typedef typename std::iterator_traits<Iterator>::value_type element_type;
// move data into the tree
std::multiset<element_type> tree(std::make_move_iterator(begin),
std::make_move_iterator(end));
// move data out of the tree
std::move(tree.begin(), tree.end(), begin);
}
But this did not affect the performance in a significant way, even though I am sorting std::string
s.
Then I remembered that associative containers are constant from the outside, that is, std::move
and std::copy
will do the same thing here :( Is there any other way to move the data out of the tree?
std::set
and std::multiset
only provide const
access to their elements. This means you cannot move something out of the set. If you could move items out (or modify them at all), you could break the set by changing the sort order of the items. So C++11 forbids it.
So your attempt to use the std::move
algorithm will just invoke the copy constructor.
I believe you could make a custom allocator for the multiset
to use (3rd template argument) which actually moves the elements in it's destroy
method back to the user's container. Then erase each element in the set and during its destruction it should move your string back to the original container. I think the custom allocator would need to have 2 phase construction (pass it the begin iterator passed to yourtreesort
function to hold as a member, but not during construction because it has to be default constructible).
Obviously this would be bizarre and is a silly workaround for not having a pop
method in set/multiset. But it should be possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With