/* * LabeledValues.h * * Created on: 26.09.2013 * Author: Christian Dehnert */ #ifndef STORM_STORAGE_LABELEDVALUES_H #define STORM_STORAGE_LABELEDVALUES_H #include <list> #include <boost/container/flat_set.hpp> namespace storm { namespace utility { template<class ValueType> static ValueType constantZero(); } namespace storage { // This class provides the functionality to store a list of values, each of which is labeled with possibly several // labels. template<class ValueType> class LabeledValues { public: /*! * Default-constructs an empty object. */ explicit LabeledValues() : valueLabelList() { // Intentionally left empty. } /*! * Constructs an object that stores the single probability value without any label. * * @param value The probability to sto */ explicit LabeledValues(ValueType value) : valueLabelList() { addValue(value); } /*! * Adds an (unlabeled) value to the list of labeled values. * * @param value The value to add. * @return A reference to the list of labels that is associated with the given value. */ boost::container::flat_set<uint_fast64_t>& addValue(ValueType value) { valueLabelList.emplace_back(value, boost::container::flat_set<uint_fast64_t>()); return valueLabelList.back().second; } /*! * Adds a labeled value to the list of labeled values. * * @param value The value to add. * @param labels The labels to associate with this value. * @return A reference to the list of labels that is associated with the given value. */ boost::container::flat_set<uint_fast64_t>& addValue(ValueType value, boost::container::flat_set<uint_fast64_t> const& labels) { valueLabelList.emplace_back(value, labels); return valueLabelList.back().second; } /*! * Returns an iterator pointing to the first labeled probability. * * @return An iterator pointing to the first labeled probability. */ typename std::list<std::pair<ValueType, boost::container::flat_set<uint_fast64_t>>>::iterator begin() { return valueLabelList.begin(); } /*! * Returns an iterator pointing past the last labeled probability. * * @return An iterator pointing past the last labeled probability. */ typename std::list<std::pair<ValueType, boost::container::flat_set<uint_fast64_t>>>::const_iterator end() { return valueLabelList.end(); } /*! * Returns a const iterator pointing to the first labeled probability. * * @return A const iterator pointing to the first labeled probability. */ typename std::list<std::pair<ValueType, boost::container::flat_set<uint_fast64_t>>>::const_iterator begin() const { return valueLabelList.begin(); } /*! * Returns a const iterator pointing past the last labeled probability. * * @return A const iterator pointing past the last labeled probability. */ typename std::list<std::pair<ValueType, boost::container::flat_set<uint_fast64_t>>>::const_iterator end() const { return valueLabelList.end(); } /*! * Inserts the contents of this object to the given output stream. * * @param out The stream in which to insert the contents. */ friend std::ostream& operator<<(std::ostream& out, LabeledValues const& labeledValues) { out << "["; for (auto const& element : labeledValues) { out << element.first << " ("; for (auto const& label : element.second) { out << label << ", "; } out << ") "; } out << "]"; return out; } /*! * Adds all labeled values of the given object to the current one. * * @param labeledValues The labeled values to add to the object. */ LabeledValues<ValueType>& operator+=(LabeledValues<ValueType> const& labeledValues) { for (auto const& valueLabelListPair : labeledValues) { this->valueLabelList.push_back(valueLabelListPair); } return *this; } /*! * Divides the values by the given value. * * @param value The value by which to divide. * @return A collection of labeled values that have the same labels as the current object, but whose values * are divided by the given one. */ LabeledValues<ValueType> operator/(ValueType value) const { LabeledValues<ValueType> result; for (auto const& valueLabelListPair : valueLabelList) { result.addValue(valueLabelListPair.first / value, valueLabelListPair.second); } return result; } /*! * Divides the values by the given unsigned integer value. * * @param value The unsigned integer value by which to divide. * @return A collection of labeled values that have the same labels as the current object, but whose values * are divided by the given one. */ LabeledValues<ValueType> operator/(uint_fast64_t value) const { LabeledValues<ValueType> result; for (auto const& valueLabelListPair : valueLabelList) { result.addValue(valueLabelListPair.first / value, valueLabelListPair.second); } return result; } /*! * Converts the object into the value type by returning the sum. * * @return The sum of the values. */ operator ValueType() const { return this->getSum(); } /*! * Retrieves the number of separate entries in this object. * * @return The number of separate entries in this object. */ size_t size() const { return this->valueLabelList.size(); } private: // The actual storage used to store the list of values and the associated labels. std::list<std::pair<ValueType, boost::container::flat_set<uint_fast64_t>>> valueLabelList; /*! * Returns the sum of the values. * * @return The sum of the values. */ ValueType getSum() const { ValueType sum = storm::utility::constantZero<ValueType>(); for (auto const& valueLabelListPair : *this) { sum += valueLabelListPair.first; } return sum; } }; /*! * Computes the hash value of a given labeled probabilities object. * * @param labeledProbabilities The labeled probabilities object for which to compute the hash value. * @return A hash value for the labeled probabilities object. */ template<typename ValueType> std::size_t hash_value(LabeledValues<ValueType> const& labeledValues) { return labeledValues.size(); } } } #endif /* STORM_STORAGE_LABELEDVALUES_H */