You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
2.9 KiB
132 lines
2.9 KiB
#include <vector>
|
|
#include <map>
|
|
#include <iterator>
|
|
|
|
template <class T>
|
|
class sparse_vector {
|
|
std::map<size_t, T> map;
|
|
size_t _size = 0;
|
|
|
|
public:
|
|
const T empty;
|
|
|
|
template <class U>
|
|
class iterator : public std::iterator<std::input_iterator_tag, U> {
|
|
sparse_vector<U> & vector;
|
|
size_t index;
|
|
|
|
public:
|
|
iterator(sparse_vector<U> & vector, size_t index) : vector(vector), index(index) {}
|
|
iterator(const iterator<U> & from) : vector(from.vector), index(from.index) {}
|
|
|
|
// Prefix increment operator
|
|
iterator<U> & operator++() {
|
|
++index;
|
|
return *this;
|
|
}
|
|
|
|
// Postfix increment operator
|
|
iterator<U> operator++(int) {
|
|
iterator<U> tmp(*this);
|
|
operator++();
|
|
return tmp;
|
|
}
|
|
|
|
bool operator==(const iterator<U> & rhs) const {
|
|
return index == rhs.index;
|
|
}
|
|
|
|
bool operator!=(const iterator<U> & rhs) const {
|
|
return index != rhs.index;
|
|
}
|
|
|
|
U & operator*() const {
|
|
return vector.at(index);
|
|
}
|
|
};
|
|
|
|
sparse_vector() {}
|
|
|
|
// Construct from element list given as arguments
|
|
sparse_vector(std::initializer_list<T> list) {
|
|
size_t index = 0;
|
|
for(auto element : list) {
|
|
map[index] = element;
|
|
}
|
|
}
|
|
|
|
// Copy constructor
|
|
sparse_vector(const sparse_vector<T> & svector) {
|
|
map = svector.map;
|
|
_size = svector._size;
|
|
}
|
|
|
|
// Move constructor
|
|
sparse_vector(sparse_vector<T> && svector) {
|
|
map = std::move(svector.map);
|
|
_size = svector._size;
|
|
svector._size = 0;
|
|
}
|
|
|
|
// Construct from regular vector
|
|
sparse_vector(const std::vector<T> vector) {
|
|
for(size_t index = 0; index < vector.size(); ++index) {
|
|
map[index] = vector.at(index);
|
|
}
|
|
_size = vector.size();
|
|
}
|
|
|
|
// Move assignment operator
|
|
sparse_vector<T> & operator=(sparse_vector<T> && svector) {
|
|
map = std::move(svector.map);
|
|
size = svector._size;
|
|
svector._size = 0;
|
|
return *this;
|
|
}
|
|
|
|
size_t size() const {
|
|
return _size;
|
|
}
|
|
|
|
const T & at(size_t index) const {
|
|
return map.at(index);
|
|
}
|
|
|
|
bool has(size_t index) const {
|
|
return map.count(index) == 1;
|
|
}
|
|
|
|
void push_back(const T & element) {
|
|
map[_size++] = element;
|
|
}
|
|
|
|
template <class Range>
|
|
void push_back(Range range) {
|
|
for(T & element : range) {
|
|
push_back(element);
|
|
}
|
|
}
|
|
|
|
T pop_back() {
|
|
--_size;
|
|
if(has(_size)) {
|
|
T element = map->at(_size);
|
|
map.erase(_size);
|
|
return element;
|
|
}
|
|
|
|
return empty;
|
|
}
|
|
|
|
iterator<T> begin() const {
|
|
return iterator<T>(*this, 0);
|
|
}
|
|
|
|
iterator<T> end() const {
|
|
return iterator<T>(*this, size());
|
|
}
|
|
|
|
T & operator[](size_t index) {
|
|
return map[index];
|
|
}
|
|
}; |