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.
233 lines
7.7 KiB
233 lines
7.7 KiB
/*
|
|
* VectorSet.h
|
|
*
|
|
* Created on: 23.10.2013
|
|
* Author: Christian Dehnert
|
|
*/
|
|
|
|
#ifndef STORM_STORAGE_VECTORSET_H
|
|
#define STORM_STORAGE_VECTORSET_H
|
|
|
|
#include <set>
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace storm {
|
|
namespace storage {
|
|
|
|
template<typename T>
|
|
class VectorSet {
|
|
public:
|
|
typedef T* difference_type;
|
|
typedef T value_type;
|
|
typedef T* pointer;
|
|
typedef T& reference;
|
|
typedef typename std::vector<T>::iterator iterator;
|
|
typedef typename std::vector<T>::const_iterator const_iterator;
|
|
|
|
VectorSet() : data(), dirty(false) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
VectorSet(uint_fast64_t size) : data(), dirty(false) {
|
|
data.reserve(size);
|
|
}
|
|
|
|
VectorSet(std::vector<T> const& data) : data(data), dirty(true) {
|
|
ensureSet();
|
|
}
|
|
|
|
VectorSet(std::set<T> const& data) : dirty(false) {
|
|
this->data.reserve(data.size());
|
|
for (auto const& element : data) {
|
|
this->data.push_back(element);
|
|
}
|
|
}
|
|
|
|
template<typename InputIterator>
|
|
VectorSet(InputIterator first, InputIterator last) : data(first, last), dirty(true) {
|
|
ensureSet();
|
|
}
|
|
|
|
VectorSet(VectorSet const& other) : dirty(false) {
|
|
other.ensureSet();
|
|
data = other.data;
|
|
}
|
|
|
|
VectorSet& operator=(VectorSet const& other) {
|
|
data = other.data;
|
|
dirty = other.dirty;
|
|
return *this;
|
|
}
|
|
|
|
VectorSet(VectorSet&& other) : data(std::move(other.data)), dirty(std::move(other.dirty)) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
VectorSet& operator=(VectorSet&& other) {
|
|
data = std::move(other.data);
|
|
dirty = std::move(other.dirty);
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(VectorSet const& other) const {
|
|
ensureSet();
|
|
if (this->size() != other.size()) return false;
|
|
return std::equal(data.begin(), data.end(), other.begin());
|
|
}
|
|
|
|
bool operator<(VectorSet const& other) const {
|
|
ensureSet();
|
|
if (this->size() < other.size()) return true;
|
|
if (this->size() > other.size()) return false;
|
|
for (auto it1 = this->begin(), it2 = other.begin(); it1 != this->end(); ++it1, ++it2) {
|
|
if (*it1 < *it2) return true;
|
|
if (*it1 > *it2) return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ensureSet() const {
|
|
if (dirty) {
|
|
std::sort(data.begin(), data.end());
|
|
data.erase(std::unique(data.begin(), data.end()), data.end());
|
|
dirty = false;
|
|
}
|
|
}
|
|
|
|
bool contains(T const& element) const {
|
|
ensureSet();
|
|
return std::binary_search(data.begin(), data.end(), element);
|
|
}
|
|
|
|
bool subsetOf(VectorSet const& other) const {
|
|
ensureSet();
|
|
other.ensureSet();
|
|
return std::includes(other.begin(), other.end(), data.begin(), data.end());
|
|
}
|
|
|
|
bool supersetOf(VectorSet const& other) const {
|
|
ensureSet();
|
|
return other.subsetOf(*this);
|
|
}
|
|
|
|
VectorSet intersect(VectorSet const& other) {
|
|
ensureSet();
|
|
other.ensureSet();
|
|
VectorSet result;
|
|
std::set_intersection(data.begin(), data.end(), other.begin(), other.end(), std::inserter(result.data, result.data.end()));
|
|
return result;
|
|
}
|
|
|
|
VectorSet join(VectorSet const& other) {
|
|
ensureSet();
|
|
other.ensureSet();
|
|
VectorSet result;
|
|
std::set_union(data.begin(), data.end(), other.begin(), other.end(), std::inserter(result.data, result.data.end()));
|
|
return result;
|
|
}
|
|
|
|
iterator begin() {
|
|
ensureSet();
|
|
return data.begin();
|
|
}
|
|
|
|
iterator end() {
|
|
ensureSet();
|
|
return data.end();
|
|
}
|
|
|
|
const_iterator begin() const {
|
|
ensureSet();
|
|
return data.begin();
|
|
}
|
|
|
|
const_iterator end() const {
|
|
ensureSet();
|
|
return data.end();
|
|
}
|
|
|
|
void insert(T const& element) {
|
|
data.push_back(element);
|
|
dirty = true;
|
|
}
|
|
|
|
template<typename InputIterator>
|
|
iterator insert(InputIterator first, InputIterator last) {
|
|
dirty = true;
|
|
return data.insert(data.end(), first, last);
|
|
}
|
|
|
|
template<typename InputIterator>
|
|
iterator insert(InputIterator pos, T element) {
|
|
dirty = true;
|
|
return data.insert(pos, element);
|
|
}
|
|
|
|
bool empty() const {
|
|
ensureSet();
|
|
return data.empty();
|
|
}
|
|
|
|
size_t size() const {
|
|
ensureSet();
|
|
return data.size();
|
|
}
|
|
|
|
void clear() {
|
|
data.clear();
|
|
dirty = false;
|
|
}
|
|
|
|
bool erase(T const& element) {
|
|
ensureSet();
|
|
uint_fast64_t lowerBound = 0;
|
|
uint_fast64_t upperBound = data.size();
|
|
while (lowerBound != upperBound) {
|
|
uint_fast64_t currentPosition = lowerBound + (upperBound - lowerBound) / 2;
|
|
bool searchInLowerHalf = element < data[currentPosition];
|
|
if (searchInLowerHalf) {
|
|
upperBound = currentPosition;
|
|
} else {
|
|
bool searchInRightHalf = element > data[currentPosition];
|
|
if (searchInRightHalf) {
|
|
lowerBound = currentPosition + 1;
|
|
} else {
|
|
// At this point we have found the element.
|
|
data.erase(data.begin() + currentPosition);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
friend std::ostream& operator<< (std::ostream& stream, VectorSet const& set) {
|
|
set.ensureSet();
|
|
stream << "VectorSet(" << set.size() << ") { ";
|
|
if (set.size() > 0) {
|
|
for (uint_fast64_t index = 0; index < set.size() - 1; ++index) {
|
|
stream << set.data[index] << ", ";
|
|
}
|
|
stream << set.data[set.size() - 1] << " }";
|
|
} else {
|
|
stream << "}";
|
|
}
|
|
return stream;
|
|
}
|
|
|
|
private:
|
|
mutable std::vector<T> data;
|
|
mutable bool dirty;
|
|
};
|
|
}
|
|
}
|
|
|
|
namespace std {
|
|
|
|
}
|
|
|
|
|
|
#endif /* STORM_STORAGE_VECTORSET_H */
|