#include "src/storage/VectorSet.h" #include "src/storage/BitVector.h" namespace storm { namespace storage { template<typename ValueType> VectorSet<ValueType>::VectorSet() : data(), dirty(false) { // Intentionally left empty. } template<typename ValueType> VectorSet<ValueType>::VectorSet(uint_fast64_t size) : data(), dirty(false) { data.reserve(size); } template<typename ValueType> VectorSet<ValueType>::VectorSet(std::vector<ValueType> const& data) : data(data), dirty(true) { ensureSet(); } template<typename ValueType> VectorSet<ValueType>::VectorSet(std::set<ValueType> const& data) : dirty(false) { this->data.reserve(data.size()); for (auto const& element : data) { this->data.push_back(element); } } template<typename ValueType> VectorSet<ValueType>::VectorSet(storm::storage::BitVector const& data) : dirty(false) { this->data.reserve(data.getNumberOfSetBits()); for (auto element : data) { this->data.push_back(element); } } template<typename ValueType> VectorSet<ValueType>::VectorSet(uint_fast64_t from, uint_fast64_t to) : dirty(false) { data.reserve(to - from); for (uint_fast64_t element = from; element < to; ++element) { data.push_back(element); } } template<typename ValueType> VectorSet<ValueType>::VectorSet(VectorSet const& other) : dirty(false) { other.ensureSet(); data = other.data; } template<typename ValueType> VectorSet<ValueType>& VectorSet<ValueType>::operator=(VectorSet<ValueType> const& other) { data = other.data; dirty = other.dirty; return *this; } template<typename ValueType> VectorSet<ValueType>::VectorSet(VectorSet<ValueType>&& other) : data(std::move(other.data)), dirty(std::move(other.dirty)) { // Intentionally left empty. } template<typename ValueType> VectorSet<ValueType>& VectorSet<ValueType>::operator=(VectorSet&& other) { data = std::move(other.data); dirty = std::move(other.dirty); return *this; } template<typename ValueType> bool VectorSet<ValueType>::operator==(VectorSet<ValueType> const& other) const { ensureSet(); if (this->size() != other.size()) return false; return std::equal(data.begin(), data.end(), other.begin()); } template<typename ValueType> bool VectorSet<ValueType>::operator<(VectorSet<ValueType> 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; } template<typename ValueType> bool VectorSet<ValueType>::operator>(VectorSet<ValueType> 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; } template<typename ValueType> void VectorSet<ValueType>::ensureSet() const { if (dirty) { std::sort(data.begin(), data.end()); data.erase(std::unique(data.begin(), data.end()), data.end()); dirty = false; } } template<typename ValueType> bool VectorSet<ValueType>::contains(ValueType const& element) const { ensureSet(); return std::binary_search(data.begin(), data.end(), element); } template<typename ValueType> bool VectorSet<ValueType>::subsetOf(VectorSet<ValueType> const& other) const { ensureSet(); other.ensureSet(); return std::includes(other.begin(), other.end(), data.begin(), data.end()); } template<typename ValueType> bool VectorSet<ValueType>::supersetOf(VectorSet<ValueType> const& other) const { ensureSet(); return other.subsetOf(*this); } template<typename ValueType> VectorSet<ValueType> VectorSet<ValueType>::intersect(VectorSet<ValueType> 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; } template<typename ValueType> VectorSet<ValueType> VectorSet<ValueType>::join(VectorSet<ValueType> 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; } template<typename ValueType> typename VectorSet<ValueType>::iterator VectorSet<ValueType>::begin() { ensureSet(); return data.begin(); } template<typename ValueType> typename VectorSet<ValueType>::iterator VectorSet<ValueType>::end() { ensureSet(); return data.end(); } template<typename ValueType> typename VectorSet<ValueType>::const_iterator VectorSet<ValueType>::begin() const { ensureSet(); return data.begin(); } template<typename ValueType> typename VectorSet<ValueType>::const_iterator VectorSet<ValueType>::end() const { ensureSet(); return data.end(); } template<typename ValueType> ValueType const& VectorSet<ValueType>::min() const { if (this->size() == 0) { throw storm::exceptions::InvalidStateException() << "Cannot retrieve minimum of empty set."; } ensureSet(); return data.front(); } template<typename ValueType> ValueType const& VectorSet<ValueType>::max() const { if (this->size() == 0) { throw storm::exceptions::InvalidStateException() << "Cannot retrieve minimum of empty set."; } ensureSet(); return data.back(); } template<typename ValueType> void VectorSet<ValueType>::insert(ValueType const& element) { data.push_back(element); dirty = true; } template<typename ValueType> typename VectorSet<ValueType>::iterator VectorSet<ValueType>::insert(typename VectorSet<ValueType>::const_iterator pos, ValueType const& element) { dirty = true; return data.insert(pos, element); } template<typename ValueType> void VectorSet<ValueType>::insert(VectorSet<ValueType> const& other) { data.insert(data.end(), other.data.begin(), other.data.end()); } template<typename ValueType> bool VectorSet<ValueType>::empty() const { ensureSet(); return data.empty(); } template<typename ValueType> size_t VectorSet<ValueType>::size() const { ensureSet(); return data.size(); } template<typename ValueType> void VectorSet<ValueType>::clear() { data.clear(); dirty = false; } template<typename ValueType> bool VectorSet<ValueType>::erase(ValueType 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; } template<typename ValueType> void VectorSet<ValueType>::erase(VectorSet<ValueType> const& eraseSet) { if (eraseSet.size() > 0 && this->size() > 0) { ensureSet(); eraseSet.ensureSet(); for (typename std::vector<ValueType>::reverse_iterator delIt = eraseSet.data.rbegin(), setIt = data.rbegin(); delIt != eraseSet.data.rend() && setIt != eraseSet.data.rend(); ++delIt) { while (setIt != eraseSet.data.rend() && *setIt > *delIt) { ++setIt; } if (setIt == data.rend()) break; if (*setIt == *delIt) { data.erase((setIt + 1).base()); ++setIt; } } } } template<typename ValueType> std::ostream& operator<<(std::ostream& stream, VectorSet<ValueType> 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; } template class VectorSet<uint_fast64_t>; template class VectorSet<VectorSet<uint_fast64_t>>; template std::ostream& operator<<(std::ostream& stream, VectorSet<uint_fast64_t> const& set); template std::ostream& operator<<(std::ostream& stream, VectorSet<VectorSet<uint_fast64_t>> const& set); } }