Reputation: 1908
Is there a container in the C++ world that has these properties ?
I'm currently collecting my data into a std::set<C,COMPARATOR>
and afterwards do a std::copy(_set.begin(),_set.end(),std::back_inserter(_vec))
to be able to have random access to the ordered collection. The size however might go into hundreds of millions.
Upvotes: 6
Views: 961
Reputation: 54777
If Boost is an option, have a look at flat_set
in the Containers library.
The interface for flat_set
is identical to that of std::set
but it provides random access iterators, like std::vector
:
#include <boost/container/flat_set.hpp>
[...]
boost::container::flat_set<int> c;
c.insert(1);
c.insert(2);
c.insert(3);
c.insert(4);
// unfortunately, no operator[] on the container itself,
// but the iterator is random access
int third_element = c.begin()[2];
If you are stuck with the standard library, you can use a sorted vector
for this purpose. The standard library actually offers a lot of algorithms in the <algorithm>
header that allow you to do pretty much anything that you can do with a set
with a sorted iterator range.
Upvotes: 8
Reputation: 304122
Not in the standard C++ library, no. You either have set
/priority_queue
for ordering or vector
/deque
for random access.
But there's nothing to stop you from writing your own wrapper around vector
which simply enforces ordering. It's not that much code at all. Some example functions:
template <typename T, typename COMP = std::less<T>>
class sorted_vec {
std::vector<T> vec_;
public:
// random access
using iterator = typename std::vector<T>::iterator;
T& operator[](size_t idx) { return vec_[idx]; }
iterator begin() { return vec_.begin(); }
iterator end() { return vec_.end(); }
// insertion
void push(const T& val) {
vec_.insert(std::lower_bound(vec_.begin(), vec_.end(), COMP{}),
val);
}
};
Upvotes: 1
Reputation: 973
None that I am aware of. However, with hundreds of millions of elements and some ordered access you might want your memory representation to be compact and consecutive, which are even more requirements for your container class.
I'd go with std::vector
and use the approach that you have described or any other sorting algorithm. You probably won't need your std::set
afterwards, so you can free the memory.
Upvotes: 1