I have a \"column\" container type:
struct MyColumnType {
// Data: Each row represents a member of an object.
vector a; // All vectors a
If you're really concerned about performance and you want to sort your container with std::sort, use the overload that allows you to provide a custom comparison object:
template
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
.. and sort an array of indices into the container. Here's how:
You'll need the following members in your container:
struct MyColumnType {
...
int size() const;
// swaps columns
void swap(int l, int r);
// returns true if column l is less than column r
bool less(int l, int r) const;
...
};
Then define the following comparison object:
struct MyColumnTypeLess
{
const MyColumnType* container;
MyColumnTypeLess(const MyColumnType* container)
: container(container)
{
}
bool operator()(int l, int r) const
{
return container->less(l, r);
}
};
And use it to sort an array of indices:
void sortMyColumnType(MyColumnType& container)
{
std::vector indices;
indices.reserve(container.size());
// fill with [0, n)
for(int i = 0; i != container.size(); ++i)
{
indices.push_back(i);
}
// sort the indices
std::sort(indices.begin(), indices.end(), MyColumnTypeLess(&container));
}
The 'less' member of the container controls which order to sort in:
bool MyColumnType::less(int l, int r) const
{
// sort first by a, then b, then c
return a[l] != a[r] ? a[l] < a[r]
: b[l] != b[r] ? b[l] < b[r]
: c[l] < c[r];
}
The sorted array of indices can be used in further algorithms - you can avoid copying the actual data around until you need to.
All std algorithms that work with RandomAccessIterators have overloads that allow you to specify custom comparison objects, so they can also be used with this technique.